antoniandre / splitpanes

A Vue 2 & 3 reliable, simple and touch-ready panes splitter / resizer.

Home Page:https://antoniandre.github.io/splitpanes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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"
  ]
}