全局混入

全局混入会影响所有 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')
  }
})

注意事项

谨慎使用全局混入

  1. 影响所有组件:包括第三方组件库
  2. 性能影响:每个组件都会执行混入逻辑
  3. 调试困难:难以追踪问题来源
  4. 命名冲突:可能与组件选项冲突

替代方案

使用插件

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

对于全局状态,使用 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()
      }
    }
  }
})

使用前缀 $_ 避免与组件选项冲突。

理解全局混入后,接下来学习自定义混入策略。