1.vue2的mixins
mixins是vue2用于开发可复用性的功能组件,它可以将一些公共的代码提取出来,然后在需要的地方进行引入,从而实现代码的复用。
2.mixin的使用方式-定义mixins
我们可以定义一个公共mixins.js文件,然后在需要的地方进行引入。可以混入的选项有:data、methods、computed、watch、子组件、生命周期钩子函数等。示例代码如下:
import ChildrenComponent from "./ChildrenComponent.vue";
export default {
// 混入子组件,可以复用
components: {
ChildrenComponent,
},
// 混入响应式数据
data() {
return {
msg: "hello mixins",
inputValue: "",
};
},
// 混入生命周期钩子
created() {
console.log("mixins created");
},
mounted() {
console.log("mixins mounted");
},
// 混入方法
methods: {
handleClick() {
console.log("hello mixins");
},
},
// 混入计算属性
computed: {
reverseMsg() {
return this.msg.split("").reverse().join("");
},
},
watch: {
inputValue(newVal, oldVal) {
console.log('监听数据变化: ', newVal, oldVal);
},
}
};
3.mixin的使用方式-引用mixins
在需要使用mixins的地方,我们只需要在组件中引入mixins,通过mixins中进行注入即可。示例代码如下:
<template>
<div class="use-mixins">
<div>通过mixins混入的数据: {{ msg }}</div>
<div>通过mixins混入的计算属性: {{ reverseMsg }}</div>
<div>组件自己的数据: {{ selfMsg }}</div>
<input type="text" v-model="inputValue">
<ChildrenComponent />
<button @click="handleClick">调用mixins混入的方法</button>
</div>
</template>
<script>
import mixin from "./mixins";
// vue2的mixins的使用方式
export default {
name: "use-mixins",
mixins: [mixin], // 包含了响应式数据data(msg), methods(handleClick), computed(reverseMsg), 生命周期钩子函数(created, mounted), 子组件components(ChildrenComponent)
data() {
return {
// msg: "与mixins命名冲突的data数据", // 组件data数据覆盖mixins的策略
selfMsg: "自有数据",
};
},
created() {
console.log("组件自己的生命周期钩子函数created"); // 先执行mixins的created, 再执行组件自己的created
},
mounted() {
console.log("组件自己的生命周期钩子函数mounted"); // 先执行mixins的mounted, 再执行组件自己的mounted
},
computed: {
// reverseMsg() {
// return this.msg + '命名冲突的计算属性'; // 组件计算属性覆盖mixins的策略
// },
},
methods: {
// handleClick() {
// console.log("组件自己的方法handleClick"); // methods方法覆盖mixins的策略
// },
},
watch: {
inputValue(newVal, oldVal) {
console.log('组件监听数据变化: ', newVal, oldVal); // 先执行mixins的watch, 再执行组件自己的watch
},
}
};
</script>
<style scoped>
.use-mixins {
width: 100%;
height: 100%;
background-color: #fff;
color: black;
padding: 21px;
}
.use-mixins input {
border: 1px solid #ccc;
}
</style>
代码中的注释已经描述了一些比较关键的点,总结一下:
合并策略:
1. data: 如果有相同的属性,会进行合并,以组件的属性为准。
2. methods: 如果有相同的函数,会进行合并,以组件的函数为准。
3. computed: 如果有相同的计算属性,会进行合并,以组件的计算属性为准。
4. watch: 如果有相同的监听器,会先执行mixins的watch,再执行组件的。
5. 生命周期钩子函数: 如果有相同的生命周期钩子函数,会先执行mixins中的生命周期钩子函数,再执行组件的。
vue2的mixins的优缺点:
优点:
1. 代码复用性,可以将通用逻辑代码提取,减少代码重复。
2. 灵活性,可以在多个组件中灵活引入mixins。
缺点:
1. 命名冲突,如果多个mixins中有相同的属性或方法,可能会导致命名冲突。
2. 依赖关系不明确,如果多个mixins中依赖了相同的属性或方法,可能会导致依赖关系不明确。
3. 难以追踪, 多个逻辑分散在多个地方,不知道哪个逻辑是哪个mixins的。
4.vue3的模块化
vue3 Composition API提供了一个更加灵活的方案来实现公共逻辑代码提取,从而实现代码的复用。
5. 定义公共逻辑代码useLaugh.js
包含响应式数据,计算属性,方法,生命周期钩子函数,watch,子组件。示例代码如下:
import { ref, watch, onMounted, computed } from "vue";
import Vue3ChildrenComponent from "./Vue3ChildrenComponent.vue";
function useLaugh() {
const laugh = ref("哈哈哈哈哈");
const laughLength = computed(() => laugh.value.length);
const laughToTears = () => {
laugh.value = "哈哈哈哈哈,出了眼泪";
};
const ticklingAndLaugh = () => {
laugh.value = "挠痒痒,哈哈哈哈哈";
};
onMounted(() => {
console.log("遇到了开心的事");
});
watch(laugh, (newVal, oldVal) => {
console.log(`公共逻辑的监听器: newVal: ${newVal},oldVal: ${oldVal}`);
});
return {
laugh,
laughLength,
laughToTears,
ticklingAndLaugh,
Vue3ChildrenComponent
};
}
export default useLaugh;
6. 引用公共逻辑代码useLaugh.js
在需要使用公共逻辑代码的地方,我们只需要在组件中引入useLaugh,通过useLaugh进行加载所需要的公共逻辑(支持按需加载)即可。示例代码如下:
<template>
<div class="wrap">
<div>vue3模块化: </div>
<div>{{ laugh }}</div>
<div>{{ laughLength }}</div>
<Vue3ChildrenComponent />
<button type="button" @click="laughToTears">笑成泪</button>
<button type="button" @click="ticklingAndLaugh">逗我笑</button>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from "vue";
import useLaugh from "./useLaugh";
const {
laugh,
laughLength,
laughToTears,
Vue3ChildrenComponent
// ticklingAndLaugh // 如果我们不需要使用这个方法,可以不引入, 自身组件可以定义同名方法,更加灵活地使用公共代码.
} = useLaugh(); // 按需加载方式引入模块(避免了命名冲突,来源清晰,清楚地知道我们引入了什么)
onMounted(() => {
console.log("组件生命周期钩子函数");
})
const ticklingAndLaugh = () => {
laugh.value = "组件自身函数, hahahahaha逗我笑";
console.log("组件自身函数, 逗我笑");
}
watch(laugh, (newVal, oldVal) => {
console.log("组件自身监听器: laugh变化了", newVal, oldVal);
})
// const laugh = ref("哈哈"); // 直接提示了命名冲突(避免了vue2中mixins的命名冲突)
</script>
<style scoped>
.wrap {
width: 100%;
height: 100%;
background-color: #fff;
color: black;
}
.wrap button {
margin: 0 10px;
border-radius: 1px;
padding: 5px 10px;
border: 1px solid #ccc;
cursor: pointer;
}
</style>
7.vue3模块化总结
策略差异:
watch: 如果同事对一个属性进行了监听,会先执行组件的watch,再执行useLaugh的watch。
优点:
1. 避免了命名冲突
2. 依赖关系明确,可以明确知道哪些逻辑是哪些模块的,更好代码追踪。
3. 更加灵活,可以按需加载。