目录
一、什么是 Vue.mixin()
Vue.mixin()
方法是 Vue.js 的一个重要 API,用于定义全局混入(mixins)。它允许开发者将一个对象中的功能、数据、生命周期钩子等与所有 Vue 实例共享,从而实现代码的复用。
1.基本语法
Vue.mixin(mixin);
mixin
: 一个对象,包含要共享的选项,如 data
、methods
、computed
等。
2.主要特点
- 全局生效: 使用
Vue.mixin()
创建的混入会对所有 Vue 实例生效,包括根实例和子实例。 - 选项合并: 当多个混入对象中存在相同的选项时,Vue 会进行合并。通常后面的混入会覆盖前面的混入。
- 生命周期钩子: 当混入对象中定义了生命周期钩子(如
created
、mounted
等)时,这些钩子会被合并,如果多个混入定义了相同的钩子,则会按顺序执行。
二、案例解析
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之前写过的代码了。以上就是全部内容了,当然了,这只是一个简化版的,实际上的要复杂一点,但本质是没什么太大区别的,那就怎么简单怎么来咯,至少代码的阅读性要好很多。
四、注意事项
- 性能考虑: 由于全局混入会影响所有 Vue 实例,因此应谨慎使用,避免引入不必要的复杂性和性能开销。
- 命名冲突: 在多个混入中存在相同的方法、计算属性或数据时,需要考虑合并逻辑,以避免意想不到的结果。
- 调试困难: 由于混入机制可能导致代码的可读性和可维护性降低,调试时可能会变得更加困难。
五、总结
Vue.mixin()
是一种非常强大的工具,可以有效地复用代码和功能。它适用于需要在多个组件中共享相同功能的场景,但需谨慎使用,以保持代码的清晰和可维护性。