Subscribe on changes!

$options shared between instances if used in mixins

avatar
Feb 25th 2023

Vue version

3.2.47

Link to minimal reproduction

Vue playground

Steps to reproduce

Open the reproduction playground above, then open your DevTool and observe the console.

What is expected?

$options are shared! Value is: foo should not be logged to the console

What is actually happening?

$options are shared! Value is: foo is logged to the console

System Info

No response

Any additional comments?

In Vue 2 I used to attach instances of 3rd party plugins onto this using the created() hook. With Vue 3, that doesn't play well anymore with Typescript, so I followed this comment and used the $options object instead.

However, when using that approach in a mixin for a component that is used several times, the property value attached to $options becomes shared across instances.

avatar
Feb 27th 2023

@LinusBorg Thank you for this. Works like a charm!

For iternity, the suggested way to store something on the vue instance (non-reactive) is to use a WeakMap() as cache like that:

import type { ComponentPublicInstance } from 'vue'
import * as Highcharts from 'highcharts'

const cache = new WeakMap<ComponentPublicInstance, Highcharts.Chart>()

export default {
    mounted() {
      const chart = Highcharts.chart('chart-id', { /* chartOptions */ })
      this.setChart(chart)
    },
    methods: {
      setChart(chart: Highcharts.Chart) { cache.set(this, chart) },
      getChart() { return cache.get(this) }
    },
    beforeUnmount() {
      this.getChart().destroy()
    }
}

Feel free to close this issue if you don't consider it as a bug after all.