全局混入会影响所有 Vue 实例,包括第三方组件。使用时需要格外小心,通常用于插件或全局功能。
Vue.mixin({
created() {
console.log('全局混入的 created 钩子')
}
})
new Vue({
created() {
console.log('组件的 created 钩子')
}
})
输出:
全局混入的 created 钩子
组件的 created 钩子
Vue.mixin({
created() {
console.log(`[${this.$options.name}] created`)
},
mounted() {
console.log(`[${this.$options.name}] mounted`)
},
methods: {
log(message) {
console.log(`[${this.$options.name}] ${message}`)
}
}
})
Vue.mixin({
methods: {
async safeExecute(fn) {
try {
return await fn()
} catch (error) {
console.error('Error:', error)
this.$emit('error', error)
}
}
}
})
Vue.mixin({
beforeRouteEnter(to, from, next) {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login')
} else {
next()
}
}
})
Vue.mixin({
data() {
return {
globalLoading: false
}
},
computed: {
isAuthenticated() {
return this.$store.state.auth.isAuthenticated
}
}
})
Vue.mixin({
methods: {
trackEvent(eventName, data = {}) {
if (this.$analytics) {
this.$analytics.track(eventName, {
component: this.$options.name,
...data
})
}
}
},
mounted() {
this.trackEvent('component_mounted')
}
})
谨慎使用全局混入
const MyPlugin = {
install(Vue) {
Vue.prototype.$log = function(message) {
console.log(`[${this.$options.name}] ${message}`)
}
}
}
Vue.use(MyPlugin)
Vue.prototype.$formatDate = function(date) {
return new Date(date).toLocaleDateString()
}
Vue.component('LoadingSpinner', {
template: '<div class="spinner">Loading...</div>'
})
对于全局状态,使用 Vuex 更合适:
const store = new Vuex.Store({
state: {
loading: false
},
mutations: {
setLoading(state, value) {
state.loading = value
}
}
})
何时使用全局混入:
何时避免使用全局混入:
Vue.mixin({
data() {
return {
$_loading: false
}
},
methods: {
$_startLoading() {
this.$_loading = true
},
$_stopLoading() {
this.$_loading = false
},
async $_withLoading(fn) {
this.$_startLoading()
try {
return await fn()
} finally {
this.$_stopLoading()
}
}
}
})
使用前缀 $_ 避免与组件选项冲突。
理解全局混入后,接下来学习自定义混入策略。