深入理解 Vue.mixin() 方法

目录

一、什么是 Vue.mixin()

1.基本语法

2.主要特点

二、案例解析

1. 定义全局混入

2. 方法合并

3. 生命周期钩子

三、项目实战

1.vuex的模块文件dict.js

 2.字典的对象文件DictData.js

 3.字典的数据文件Dict.js

 4.字典的关键文件DictMixin.js

 5.字典的关键文件index.js

 6.最后在main.js文件中引入

 7.vue页面中的使用

四、注意事项

五、总结


一、什么是 Vue.mixin()

    Vue.mixin() 方法是 Vue.js 的一个重要 API,用于定义全局混入(mixins)。它允许开发者将一个对象中的功能、数据、生命周期钩子等与所有 Vue 实例共享,从而实现代码的复用。

1.基本语法
Vue.mixin(mixin);

mixin: 一个对象,包含要共享的选项,如 datamethodscomputed 等。

2.主要特点
  1. 全局生效: 使用 Vue.mixin() 创建的混入会对所有 Vue 实例生效,包括根实例和子实例。
  2. 选项合并: 当多个混入对象中存在相同的选项时,Vue 会进行合并。通常后面的混入会覆盖前面的混入。
  3. 生命周期钩子: 当混入对象中定义了生命周期钩子(如 createdmounted 等)时,这些钩子会被合并,如果多个混入定义了相同的钩子,则会按顺序执行。

二、案例解析

1. 定义全局混入
// 定义一个混入
Vue.mixin({
    data() {
        return {
            globalData: 'This is a global data'
        };
    },
    created() {
        console.log('This is a global created hook!');
    }
});

// 在 Vue 实例中使用
new Vue({
    el: '#app',
    data() {
        return {
            instanceData: 'This is instance data'
        };
    },
    created() {
        console.log('Instance created hook!');
    },
    template: `<div>{{ globalData }} - {{ instanceData }}</div>`
});

输出:

This is a global created hook!
Instance created hook!
2. 方法合并
// 定义一个混入,其中包含一个方法
Vue.mixin({
    methods: {
        greet() {
            console.log('Hello from mixin!');
        }
    }
});

// 在 Vue 实例中调用混入的方法
new Vue({
    el: '#app',
    mounted() {
        this.greet(); // 输出: Hello from mixin!
    }
});
3. 生命周期钩子
Vue.mixin({
    created() {
        console.log('Global mixin created hook');
    }
});

new Vue({
    el: '#app',
    created() {
        console.log('Instance created hook');
    }
});

输出:

Global mixin created hook
Instance created hook

三、项目实战

 在实际的项目中,通常都会有字典类型,而前端每次获取字典都需要去请求一个接口,然而,每次请求的接口都是同一个,页面却有很多个,这样每次都要CV的方式显得很麻烦,有没有更简单的方式去获取字典呢?当然,这里就会用到mixin全局混入的方式。

1.vuex的模块文件dict.js
const state = {
  dict: new Array()
}

const mutations = {
  SET_DICT: (state, { key, value }) => {
    if (key !== null && key !== "") {
      state.dict.push({
        key: key,
        value: value
      })
    }
  },
  REMOVE_DICT: (state, key) => {
    try {
      for (let i = 0; i < state.dict.length; i++) {
        if (state.dict[i].key == key) {
          state.dict.splice(i, 1)
          return true
        }
      }
    } catch (e) {
    }
  },
  CLEAN_DICT: (state) => {
    state.dict = new Array()
  }
}

const actions = {
  // 设置字典
  setDict({ commit }, data) {
    commit('SET_DICT', data)
  },
  // 删除字典
  removeDict({ commit }, key) {
    commit('REMOVE_DICT', key)
  },
  // 清空字典
  cleanDict({ commit }) {
    commit('CLEAN_DICT')
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
 2.字典的对象文件DictData.js
/**
 * @classdesc 字典数据
 * @property {String} label 标签
 * @property {*} value 标签
 * @property {Object} raw 原始数据
 */
export default class DictData {
    constructor(label, value, raw) {
        this.label = label
        this.value = value
        this.raw = raw
    }
}
 3.字典的数据文件Dict.js
import Vue from 'vue'
import DictData from './DictData'

export default class Dict {
    constructor() {
        this.owner = null
        this.label = {}
        this.type = {}
    }

    init(dicts, metas) {
        dicts.forEach(key => {
            Vue.set(this.label, key, {})
            Vue.set(this.type, key, [])
            metas.request(key).then(resp => {
                let dicts = resp.map(t => 
                    new DictData(t[metas.labelField],t[metas.valueField],t))
                this.type[key].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
                dicts.forEach(d => {
                    Vue.set(this.label[key], d.value, d.label)
                })
            })
        })
    }
}
 4.字典的关键文件DictMixin.js
import Dict from './Dict'

export default function (Vue, options) {
    Vue.mixin({
        data() {
            if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
                return {}
            }
            const dict = new Dict()
            dict.owner = this
            return {
                dict
            }
        },
        created() {
            if (!(this.dict instanceof Dict)) {
                return
            }
            this.dict.init(this.$options.dicts, options.metas)
        }
    })
}
 5.字典的关键文件index.js
import Vue from 'vue'
import store from '@/store'
import DataMixin from '@/utils/dict/DictMixin'
import { getDicts } from '@/api/system/dict/data'

function searchDictByKey(dict, key) {
    if (key == null && key == "") {
        return null
    }
    try {
        for (let i = 0; i < dict.length; i++) {
            if (dict[i].key == key) {
                return dict[i].value
            }
        }
    } catch (e) {
        return null
    }
}

function install() {
    Vue.use(DataMixin, {
        metas: {
            labelField: 'dictLabel',
            valueField: 'dictValue',
            request(dictKey) {
                const storeDict = searchDictByKey(store.getters.dict, dictKey)
                if (storeDict) {
                    return new Promise(resolve => { resolve(storeDict) })
                } else {
                    return new Promise((resolve, reject) => {
                        getDicts(dictKey).then(res => {
                            store.dispatch('dict/setDict', { key: dictKey, value: res.data })
                            resolve(res.data)
                        }).catch(error => {
                            reject(error)
                        })
                    })
                }
            }
        }
    })
}

export default {
    install
}
 6.最后在main.js文件中引入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 字典数据
import DictData from './utils/dict'
DictData.install()

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})
 7.vue页面中的使用

在export中添加dicts属性即可,数组类型可以有多个值,value值就是你需要的字典type

如此之后,要使用其字典数据,直接这样即可:

效果如图

 

这种方式去使用字典,是不是就显得很方便且快捷,再也不用一碰到字典就要去CV之前写过的代码了。以上就是全部内容了,当然了,这只是一个简化版的,实际上的要复杂一点,但本质是没什么太大区别的,那就怎么简单怎么来咯,至少代码的阅读性要好很多。

四、注意事项

  1. 性能考虑: 由于全局混入会影响所有 Vue 实例,因此应谨慎使用,避免引入不必要的复杂性和性能开销。
  2. 命名冲突: 在多个混入中存在相同的方法、计算属性或数据时,需要考虑合并逻辑,以避免意想不到的结果。
  3. 调试困难: 由于混入机制可能导致代码的可读性和可维护性降低,调试时可能会变得更加困难。

五、总结

    Vue.mixin() 是一种非常强大的工具,可以有效地复用代码和功能。它适用于需要在多个组件中共享相同功能的场景,但需谨慎使用,以保持代码的清晰和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值