一、Mixin(混入数据)
1.1、局部Mixin认识与基本使用
Mixin你可以当做是一个vue实例对象,其中也可包含属性、方法、生命周期函数,在外部直接定义就是局部Mixin,你可以将局部Mixmin引入到vue实例中来进行使用其中的属性内容!
局部Mixin引入规则:
data对象属性值优先级小于原本data对象属性值。(原本的没有同名时才会生效)
methods方法优先级小于原本methods属性值。(原本的没有同名时才生效)
生命周期与原本的生命周期都会执行,Mixin的会优先执行,原本的会后执行!
示例:
<body> <div id="app"></div> <script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script> <script> // 重点1:局部mixin声明 const mymixin = { data() { return { // 1、data数据 num: 2 } }, methods: { // 2、方法 bindclick() { console.log("mixin click") } }, // 3、生命周期函数 created() { console.log("mixin created!") }, } Vue.createApp({ created() { console.log("created!") }, data() { return { num: 1 } }, // 重点2:引入局部mixin mixins: [mymixin], methods: { bindclick() { console.log("click") } }, template: ` <div>{{num}}</div> <button @click="bindclick">点我一下</button> ` }).mount("#app"); </script> </body>
num属性值、methods方法执行以及生命周期函数执行示例如上图。
1.2、全局Mixin定义(app.mixin({}))
全局Mixmin就是使用vue实例调用mixin来进行定义:不需要像上面的使用mixins属性来引入
const app = Vue.createApp({xxx}); // 全局Mixin定义 app.mixin({ data() { return { // 1、data数据 num: 2 } }, methods: { // 2、方法 bindclick() { console.log("mixin click") } }, // 3、生命周期函数 created() { console.log("mixin created!") }, });
对应的引入规则与局部的相同!
1.3、Mixmin自定义属性优先级(this.$options获取自定义属性)
核心要点:对于自定义属性,组件中的属性优先级高于mixin属性的优先级。
对于获取自定义属性,你需要使用this.$options.自定义属性名来获取。 <body> <div id="app"></div> <script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script> <script> // 声明局部mixin const mymixin = { num: 2 } const app = Vue.createApp({ num: 1, // 引入局部mixin mixins: [mymixin], // 访问mixmin(原本组件中的优先级要高于mixin属性) template: ` <div>{{this.$options.num}}</div> ` }); const vm = app.mount("#app"); </script> </body>
1.4、修改Mixin中属性的优先级(使用配置方法来修改策略)
原本是组件中的自定义属性优先级高于mixin中自定义属性的,我们可以通过app.config.optionMergeStrategies.xxx来指定返回优先级更高的属性:
<body> <div id="app"></div> <script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script> <script> const mymixin = { num: 2 } const app = Vue.createApp({ num: 1, mixins: [mymixin], template: ` <div>{{this.$options.num}}</div> ` }); // 针对于自定义属性(修改策略,返回的是Mixmin中的属性在左边表示其优先级更高) app.config.optionMergeStrategies.num = (mixinVal, appValue) => { return mixinVal || appValue;//mixin中的属性在前优先级更高 } const vm = app.mount("#app"); </script> </body>
该函数声明过后,我们浏览器来查看一下:仅有我们刚才自只能自定义的函数,可以设想一下内部可能会在执行前来进行调用得到值。
二、自定义指令(directive)
引言
若是我们想在加载组件后就光标选中该元素,我们能够相当的就是直接写一个生命周期函数,之后来调用dom元素执行focus方法:
<div id="app"></div> <script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script> <script> const app = Vue.createApp({ // 利用生命周期函数:在加载过程中自动选中 mounted() { this.$refs.input.focus(); }, template: ` <input ref="input" type="text"></input> ` }); const vm = app.mount("#app"); </script>
弊端:若是我们有多个dom元素都要在加载之后执行相应的操作,那么按照原本的思路就都需要写在mounted()函数中!!!可能会造成代码冗余的问题。
2.1、局部与全局自定义指令
自定义指令有什么用?
核心就是自定义指令能够绑定到指定的元素并且能够在自定义指令中编写对应的生命周期函数,此时就可以独立起来。
全局自定义指令
<div id="app"></div> <script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script> <script> //2、使用自定义指令v-focus const app = Vue.createApp({ template: ` <input v-focus type="text"/> ` }); // 1、定义全局组件,名称为focus,使用时v-focus app.directive('focus', { //编写生命周期函数,el参数为使用的指定元素 mounted(el) { el.focus();//令其光标选中 } }) const vm = app.mount("#app"); </script>
全局自定义指令
<script> // 1、自定义局部指令 const mydirective = { // 指令名称为focus focus: { mounted(el) { console.log(el) el.focus(); } } } //2、使用自定义指令v-focus const app = Vue.createApp({ directives: mydirective, template: ` <input v-focus type="text"/> ` }); const vm = app.mount("#app"); </script>
上面两个例子都是引言案例的自定义指令实现方法!
2.2、自定义指令中生命周期函数的两个参数(el、binding)
使用方式:在自定义指令中的生命周期函数中写两个参数即可获取。
el:使用自定义指令的dom元素。
binding:一个对象,可以拿到如v-自定义指令:top="xxx",binding.arg拿到top,binding.value拿到xxx,并且该xxx可以使用data对象中的属性值进行动态绑定。
示例如下:
<body> <div id="app"></div> <script src="https://unpkg.com/vue@3.1.5/dist/vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { num: 50 } }, //2、使用自定义指令v-focus template: ` <input v-focus:top="num" type="text"/> ` }); // 1、定义局部指令 app.directive('focus', { // 挂载之后生效 mounted(el, bindling) { console.log(el, bindling); // v-focus:top="num" => bindling.arg拿到top bindling.value拿到data对象中的50 el.style[bindling.arg] = bindling.value + "px"; }, // 更新前:若是想要更改num值来让dom元素生效,需要在模板渲染后来执行 beforeUpdate(el, bindling) { el.style[bindling.arg] = (bindling.value) + "px"; }, }) const vm = app.mount("#app"); </script> </body>
注意:若是你想要借助自定义指令来动态修改dom元素的样式等,你需要将该操作写于beforeUpdate()中,否则无效。
2.3、简化自定义指令方式
简化方式如下:第二个参数写箭头函数,默认指的就是beforeUpdate生命周期函数
app.directive('focus', (el, bindling) => { el.style[bindling.arg] = bindling.value + "px"; })