TypeError this.$slots.default is not a function
andrewjackroyd opened this issue · comments
Hi, we use splitpanes in a vue 2 app which we are currently upgrading to vue3. We have upgraded to the Vue Migration Build (vue compat) with Splitpanes 3 and we're seeing the error this.$slots.default is not a function in the console, and the splitpanes are not rendering.
console error
vue.runtime.esm-bundler.js:1789 Uncaught TypeError: this.$slots.default is not a function
at Proxy.render (splitpanes.es.js:280:26)
at Proxy.compatRender (vue.runtime.esm-bundler.js:4931:21)
at renderComponentRoot (vue.runtime.esm-bundler.js:2858:16)
at ReactiveEffect.componentUpdateFn [as fn] (vue.runtime.esm-bundler.js:8923:46)
at ReactiveEffect.run (vue.runtime.esm-bundler.js:593:19)
at instance.update (vue.runtime.esm-bundler.js:9057:51)
at setupRenderEffect (vue.runtime.esm-bundler.js:9065:5)
at mountComponent (vue.runtime.esm-bundler.js:8831:5)
at processComponent (vue.runtime.esm-bundler.js:8783:9)
at patch (vue.runtime.esm-bundler.js:8271:11)
I have abstracted this out to a very basic vue app using the Vue3 migration build in mode2 (backwards compatibility with Vue2). See source below.
I have tried changing the compatibility mode to 3 and its the same error.
Do you have any suggestions?
Thanks
App.vue
<template>
<div id="app">
<Heading msg="Compat App" />
<ul>
<li v-for="item in items" v-bind:key="item">{{ item }}</li>
</ul>
<button v-on:click="pop">Pop</button>
</div>
</template>
<script>
import Heading from './components/Heading.vue'
export default {
name: 'App',
components: {
Heading
},
data() {
return {
items: [1,2,3,4,5]
}
},
watch: {
items: {
handler(val, oldVal) {
console.log(oldVal + ' --> ' + val)
}
}
},
methods: {
pop() {
this.items.pop()
}
}
}
</script>
<style scoped>
#app {
font-family: Arial, Helvetica, sans-serif;
padding: 1em;
max-width: 240px;
margin: 0 auto;
background-color:#eee;
text-align: center;
}
ul {
padding-left: 0;
list-style: none;
}
button {
background-color: red;
padding: 5px 15px;
border: none;
color:white;
font-size: 16pt;
}
</style>
Heading.vue
<template>
<div>
<h1>{{ msg }}</h1>
<splitpanes style="height: 400px">
<pane min-size="20">1</pane>
<pane>2</pane>
<pane>5</pane>
</splitpanes>
</div>
</template>
<script>
export default {
name: "Heading",
props: {
msg: String,
},
};
</script>
main.js
import Vue from 'vue'
import App from './App.vue'
import { createApp } from "vue";
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
const app = createApp(App)
app.component('splitpanes', Splitpanes)
app.component('pane', Pane)
app.mount("#app");
vue.config
module.exports = {
chainWebpack: config => {
config.resolve.alias.set('vue', '@vue/compat')
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
return {
...options,
compilerOptions: {
compatConfig: {
MODE: 2
}
}
}
})
}
}
package.json
{
"name": "compat-app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vue/compat": "^3.1.0-0",
"core-js": "^3.6.5",
"splitpanes": "^3.1.5",
"vue": "^3.1.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.1.0-0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}