NightCatSama/vue-slider-component

stops working after updating vue to 2.7

altert opened this issue · 14 comments

After updating vue 2.7 component produces this error:

vue.js:3701 TypeError: Cannot read properties of undefined (reading 'on')
    at setCurrentInstance (vue.js:570:23)
    at callHook$1 (vue.js:3071:21)
    at Object.insert (vue.js:4894:15)
    at invokeInsertHook (vue.js:6910:40)
    at Vue.patch [as __patch__] (vue.js:7119:11)
    at Vue._update (vue.js:2814:27)
    at Vue.updateComponent (vue.js:2920:18)
    at Watcher.get (vue.js:4146:35)
    at Watcher.run (vue.js:4222:32)
    at flushSchedulerQueue (vue.js:3166:19)

I found 2.6.14 as the latest working (which is latest of 2.6).
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

I ran into an issue where the minified code says "_.extend('vue-slider-mark')" is not a function, in the minified version of my app, after updating to Vue 2.7 on the latest Vite 3 + @vitejs/plugin-vue2 compiler.

This is due to vue-class-component and vue-property-decorator not being supported by the new compilers. Version 4 of vue-slider-component does NOT use vue-class-component or vue-property-decorator and does not have these issues however it is broken in other ways (dragging doesn't work and the props for VueSliderMark and VueSliderTooltip throw runtime errors because they're the wrong type).

I'm currently:

  1. Using the Vue Slider 4.x beta version with my Vue 2.7 project
  2. Importing the raw *.vue source files (not compiled dist)
  3. Applying fixes as necessary (types, some errors with props, vModel backwards compatibility)
  4. Patching locally in node_modules using patch-package or (pnpm patch depending on the codebase).

@NightCatSama Do you want help in v4 to make it backwards compatible with Vue 2.7? I need this fixed and am doing the work locally.

@JessicaSachs I tried vue@2.7.1 and vue-slider-component@3.2.23 and no error was reported.

And the 4.x beta version is for vue@3.

The Vue 2.7 Reproduction Stackblitz is here: https://stackblitz.com/edit/vitejs-vue-2-7-slider-issue?file=package.json,src%2FApp.vue.

  1. Open the console and step into the iframe.
  2. Make any change to the source code and hit save to trigger Vite reload.
  3. You'll see the HMR runtime throw errors on _.extend.
  4. This is only a minor issue BUT WHEN YOU vite build and serve the application, production breaks.

Screen Shot 2022-12-07 at 10 29 01 AM

Your 4.x version is very close to being backwards-compatible with 2.7 because it removes the decorator syntax. You also continue to emit('change') I (or you) can backport your object syntax changes and remove vue-class-component && vue-property-decorator.

Just checking in. Did you have a chance to look at the reproduction I provided?

The Vue 2.7 Reproduction Stackblitz is here: https://stackblitz.com/edit/vitejs-vue-2-7-slider-issue?file=package.json,src%2FApp.vue.

  1. Open the console and step into the iframe.
  2. Make any change to the source code and hit save to trigger Vite reload.
  3. You'll see the HMR runtime throw errors on _.extend.
  4. This is only a minor issue BUT WHEN YOU vite build and serve the application, production breaks.
Screen Shot 2022-12-07 at 10 29 01 AM

Your 4.x version is very close to being backwards-compatible with 2.7 because it removes the decorator syntax. You also continue to emit('change') I (or you) can backport your object syntax changes and remove vue-class-component && vue-property-decorator.

I appear to be in a similar situation. Using Vue 2.7 to transition to Vue 3. I discovered this component last week, it's beautiful and does everything we need, except build ;)

Can you elaborate or share your changes you've done? I myself tried to copy vue-slider-component lib folder into our own code base but was immediately met with nonsensical syntax errors at build time (though curiously my IDE does not see the same issue)

Yeah so the "extend" issue is because the 3.x (Vue 2) version using vue-property-decorator + vue-class-component under the hood. Their runtimes aren't compatible with Vue 2.7 right now. I merged a PR that was released in 4.1.0-beta.7 but I have no idea what the differences are between that version and the one I was testing locally.

In theory, the signature changes a little bit and v-model won't work transparently. You have to pass :modelValue and bind to change or update:modelValue (he emits both events still, but doesn't merge :value and :modelValue). Other than that, he hasn't made any breaking Vue 3-only changes and that specific version of the lib is backwards compatible.

Workaround

  1. you need to pin to the 4.0.0-beta.9 version
  2. you can apply the patch below (I had to do some of them for my version of TypeScript)
  3. you can either copy the 4.0.0-beta.9's code from lib into your src or you can deep-import from vue-slider-component/src/vue-slider.vue. If you deep-import, use patch-package or pnpm patch to work around it.
Diff of changes made onto `4.0.0-beta.9`
diff --git a/node_modules/vue-slider-component/lib/utils/control.ts b/node_modules/vue-slider-component/lib/utils/control.ts
index b4af30f..9dd8319 100644
--- a/node_modules/vue-slider-component/lib/utils/control.ts
+++ b/node_modules/vue-slider-component/lib/utils/control.ts
@@ -1,5 +1,5 @@
 import Decimal from './decimal'
-import {
+import type {
   Value,
   Mark,
   MarkOption,
diff --git a/node_modules/vue-slider-component/lib/utils/index.ts b/node_modules/vue-slider-component/lib/utils/index.ts
index 1ec9124..5aad2d1 100644
--- a/node_modules/vue-slider-component/lib/utils/index.ts
+++ b/node_modules/vue-slider-component/lib/utils/index.ts
@@ -1,4 +1,4 @@
-import { Direction } from '../typings'
+import type { Direction } from '../typings'
 
 interface IPosObject {
   x: number
diff --git a/node_modules/vue-slider-component/lib/vue-slider-dot.vue b/node_modules/vue-slider-component/lib/vue-slider-dot.vue
index 455e822..f8e0faa 100644
--- a/node_modules/vue-slider-component/lib/vue-slider-dot.vue
+++ b/node_modules/vue-slider-component/lib/vue-slider-dot.vue
@@ -20,14 +20,15 @@
 </template>
 
 <script lang="ts">
+// @ts-nocheck
 import { defineComponent, PropType } from 'vue'
-import { Value, Styles, Position, TooltipProp, TooltipFormatter } from './typings'
+import type { Value, Styles, Position, TooltipProp, TooltipFormatter } from './typings'
 
 import './styles/dot.scss';
 
 export default defineComponent({
   name: 'VueSliderDot',
-  emits: ['DragStart'],
+  emits: ['drag-start'],
   props: {
     value: { type: [String, Number] as PropType<Value>, default: 0 },
 
@@ -50,9 +51,9 @@ export default defineComponent({
 
     disabled: { type: Boolean, default: false },
 
-    dotStyle: { type: Object as PropType<Styles> },
+    dotStyle: { type: [Object, Array] as PropType<Styles> },
 
-    tooltipStyle: { type: Object as PropType<Styles> },
+    tooltipStyle: { type: [Object, Array] as PropType<Styles> },
   },
   computed: {
     dotClasses() {
@@ -122,7 +123,7 @@ export default defineComponent({
         return false
       }
 
-      this.$emit('DragStart')
+      this.$emit('drag-start')
     },
   }
 })
diff --git a/node_modules/vue-slider-component/lib/vue-slider-mark.vue b/node_modules/vue-slider-component/lib/vue-slider-mark.vue
index f77b1e3..c8e8efa 100644
--- a/node_modules/vue-slider-component/lib/vue-slider-mark.vue
+++ b/node_modules/vue-slider-component/lib/vue-slider-mark.vue
@@ -32,14 +32,15 @@
 </template>
 
 <script lang="ts">
+// @ts-nocheck
 import { defineComponent, PropType } from 'vue'
-import { Mark, Styles } from './typings'
+import type { Mark, Styles } from './typings'
 
 import './styles/mark.scss';
 
 export default defineComponent({
   name: 'VueSliderMark',
-  emits: ['PressLabel'],
+  emits: ['press-label'],
   props: {
     mark: {
       type: Object as PropType<Mark>,
@@ -48,13 +49,13 @@ export default defineComponent({
 
     hideLabel: { type: Boolean },
 
-    stepStyle: { type: Object as PropType<Styles> },
+    stepStyle: { type: [Object, Array] as PropType<Styles> },
 
-    stepActiveStyle: { type: Object as PropType<Styles> },
+    stepActiveStyle: { type: [Object, Array] as PropType<Styles> },
 
-    labelStyle: { type: Object as PropType<Styles> },
+    labelStyle: { type: [Object, Array] as PropType<Styles> },
 
-    labelActiveStyle: { type: Object as PropType<Styles> },
+    labelActiveStyle: { type: [Object, Array] as PropType<Styles> },
   },
   computed: {
     marksClasses() {
@@ -85,7 +86,7 @@ export default defineComponent({
   methods: {
     labelClickHandle(e: MouseEvent | TouchEvent) {
       e.stopPropagation()
-      this.$emit('PressLabel', this.mark.pos)
+      this.$emit('press-label', this.mark.pos)
     },
   }
 })
diff --git a/node_modules/vue-slider-component/lib/vue-slider.vue b/node_modules/vue-slider-component/lib/vue-slider.vue
index 38bd739..b27283b 100644
--- a/node_modules/vue-slider-component/lib/vue-slider.vue
+++ b/node_modules/vue-slider-component/lib/vue-slider.vue
@@ -42,7 +42,7 @@
             :stepActiveStyle="stepActiveStyle"
             :labelStyle="labelStyle"
             :labelActiveStyle="labelActiveStyle"
-            :onPressLabel="(pos: number) => clickable && setValueByPos(pos)"
+            @press-label="pos => clickable && setValueByPos(pos)"
           >
             <template v-slot:step><slot name="step" v-bind="mark"></slot></template>
             <template v-slot:label><slot name="label" v-bind="mark"></slot></template>
@@ -102,10 +102,11 @@
 </template>
 
 <script lang="ts">
+// @ts-nocheck
 import { defineComponent, PropType } from 'vue'
 import VueSliderDot from './vue-slider-dot.vue'
 import VueSliderMark from './vue-slider-mark.vue'
-import {
+import type {
   Value,
   DataObject,
   MarksProp,

Thank you very much @JessicaSachs

@NightCatSama I have a GitHub monorepo template called Petite which tries to help library authors deploy the same backwards compatible source-code for Vue 2.7 and Vue 3 users by cross-compiling it with different versions of the Vite compiler. I use it internally at work for our Design System.

The template is here: https://github.com/JessicaSachs/petite and it uses Vitepress for its documentation, Vitest for tests, and also supports linting to warn you if you're using features that are Vue 3-only.

I know you're busy. Do you want some help with this repo?

Hi everyone, so I installed vue-slider-component@next which gave me v4.1.0-beta.7. I used @JessicaSachs 's diff to guide me to fix various issues. I am unfamiliar with npm's patching ability so I simply copied the code into my project. For what I need, vue-slider-component appears to be working as expected.

Thank you all again. I look forward to the next stable version of vue-slider-component as it is the best of its kind that I've been able to find.

@JessicaSachs It seems that there is no good way to fix the problem on vue-slider-component@3.2.4 for now.

I have tried the solution to this issue and it works. But it may have an impact on other dependencies. #642

// vite.config.ts
build: {
  commonjsOptions: {
    requireReturnsDefault: 'preferred',
  },
},

resolveComponent is not a function
vue2.7 not support resolveComponent @4.1.0-beta.9

jpetko commented

resolveComponent is not a function vue2.7 not support resolveComponent @4.1.0-beta.9

I ran into the same issue and after re-reading through some of the comments you need to import vue-slider-component/lib/vue-slider.vue from the node-modules when using the slider like so:

import VueSlider from 'vue-slider-component/lib/vue-slider.vue';

I'm using patch-package to make the suggested updates. The other suggestion was to just copy over the components into your own source and apply the changes there.