Migration to Vue 3, Part 6. – Removed APIs

Using numbers, i.e. keyCodes, as v-on modifiers (and defining custom aliases via config.keyCodes) is no longer supported.

Vue 2

Vue.config.keyCodes = {
    f1: 112
}

<!-- keyCode -->
<input v-on:keyup.13="submit" />

<!-- alias -->
<input v-on:keyup.enter="submit" />

<!-- keyCode -->
<input v-on:keyup.112="showHelpText" />

<!-- custom alias -->
<input v-on:keyup.f1="showHelpText" />

Vue 3

<input v-on:keyup.enter="submit" />

<input v-on:keyup.f1="showHelpText" />

$on, $off and $once instance methods are removed. Component instances no longer implement the event emitter interface.

Vue 2

// eventBus.js

const eventBus = new Vue()

export default eventBus

// ChildComponent.vue

import eventBus from './eventBus'

export default {
    mounted() {
        eventBus.$on('custom-event', () => {
            console.log('Custom event triggered!')
        })
    },
    beforeDestroy() {
        eventBus.$off('custom-event')
    }
}

// ParentComponent.vue

import eventBus from './eventBus'

export default {
    methods: {
        callGlobalCustomEvenet() {
            eventBus.$emit('custom-event')
        }
    }
}

Vue 3

// There is no direct migration path.
// Depending on the circumstances, there are various options:
// - Props and events should be first choice for parent-child communication.
//   Siblings can communicate via their parent.
// - Provide / inject allow a component to communicate with its slot contents.
//   This is useful for tightly-coupled components that are always used together.
//   It can also be used for long-distance communication between components.
//   where props need to be passed down through many levels of components that
//   don't need those props themselves.
// - Prop drilling can also be avoided by refactoring to use slots. If an interim
//   component doesn't need the props then it might indicate a problem with
//   separation of concerns. Introducing a slot in that component allows the
//   parent to create the content directly, so that props can be passed without
//   the interim component needing to get involved.
// - Global state management, such as Pinia.

filters are removed and no longer supported.

Vue 2

<!-- template -->

<div>{{ accountBalance | currentUSD }}</div>

// script

export default {
    props: {
        accountBalance: {
            type: Number,
            required: true
        }
    },
    filters: {
        currencyUSD(value) {
            return '$' + value
        }
    }
}

Vue 3

<!-- template -->

<div>{{ accountInUSD }}</div>

// script

export default {
    props: {
        accountBalance: {
            type: Number,
            required: true
        }
    },
    computed: {
        accountInUSD() {
            return '$' + this.accountBalance
        }
    }
}

Support for the inline-template feature has been removed.

Vue 2

<ChildComponent inline-template :msg="parentMsg">
    {{ msg }} {{ childState }}
</ChildComponent>

Vue 3

<!-- ParentComponent.vue -->

<ChildComponent v-slot="{ childState }">
    {{ parentMsg }} {{ childState }}
</ChildComponent>

<!-- ChildComponent.vue -->

<template>
    <slot :childState="childState" />
</template>

The $children instance property has been removed and is no longer supported.

Vue 2

<!-- template -->

<div>
    <my-button>Change logo</my-button>
</div>

// script

import MyButton from './MyButton'

export default {
    components: {
        MyButton
    },
    mounted() {
        console.log(this.$children)
    }
}

Vue 3

<!-- template -->

<div>
    <my-button ref="buttonRef">Change logo</my-button>
</div>

// script

import { ref, onMounted } from 'vue'
import MyButton from './MyButton'

export default {
    components: {
        MyButton
    },
    setup() {
        const buttonRef = ref(null)

        onMounted(() => {
            console.log(buttonRef.value)
        })

        return {
            buttonRef
        }
    }
}

The propsData option, used to pass props to the Vue instance during its creation, is removed.

Vue 2

const Comp = Vue.extend({
    props: ['username'],
    template: '<div>{{ username }}</div>'
})

new Comp({
    propsData: {
        username: 'Evan
    }
})

Vue 3

const app = createApp(
    {
        props: ['username'],
        template: '<div>{{ username }}</div>
    },
    { username: 'Evan' }
)