## 一、自定义指令 除了核心功能默认内置的指令(例如v-model和v-show等),Vue也允许创建自己的指令。自己做的指令中也可以封装某个功能,这样就能达到复用代码的目的。 #### 1、全局指令 创建自定义指令需要用到`.directive`方法,第一个参数为指令名称,后续调用需要用到`v-指令名`,第二个参数是一个对象,里面一般是生命周期函数,一般从`mounted()`之后才会生效,生命周期函数第一个参数都会传入一个`element`简写`el`的参数,其值为当前属性的对象。 ```html Title ``` **注意**:全局指令是创建到全局组件上的;直接通过对象属性赋值即可。 #### 2、局部指令 局部指令需要创建到跟组件上,可以通过其`directives`属性定义,以属性的方式来定义,用法与全局指令相同。 ```html Title ``` #### 3、指令参数 在使用自定义指令时可以通过`v-指令名="参数值"`来传参,多个参数可以传入一个对象,在自定义指令中,第二个参数`binding`是用来获取绑定的参数值的,可以用`binding.value`来调用参数值。 ```html Title {{num}} ``` ## 二、Mixin混入 Mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个Mixin对象可以包含任意组件选项。当组件使用Mixin对象是,所有Mixin对象的选项将被”混合“进入该组件本身的选项。 #### 1、基本用法 声明一个变量/常量来存储mixin的数据,其对象属性与组件或实例属性完全一致,当有多个mixin时可以同时混入多个。 ```html Title 姓名:;日期: {{num}} ``` #### 2、混入优先级 当组件当中有属性与Mixin中重复,那么组件中的属性优先级更高,但是生命周期方法除外,因为在混入前要先声明Mixin对象。 ```html Title 姓名:;日期: {{num}} ``` #### 3、全局Mixin Mixin可以全局注册,也就是将Mixin挂载到Vue实例上,这样组件中就不用再写`mixins:[]`选项了。一般使用`全局组件.mixin({})`来注册,可以注册多次,实现的效果与上面一样,只不过不可以在子组件中复用。 ```html Title 姓名:;日期: {{num}} ``` ## 三、插件 plugin插件是把通用功能封装起来,通常向Vue添加全局级功能,比如给Vue添加自定义指令、Mixin等。 #### 1、基本用法 插件的声明分为两种方式,第一种为对象形式,里面必须有固定的`install()`函数,第二种函数形式,将`install()`函数匿名。 ```html Title ``` #### 2、给Vue扩展功能 ```html Title 姓名:;日期: {{num}} ``` **注意**:扩展功能时使用的是`directive`、`mixin`不是`directives`、`mixins` Loading... ## 一、自定义指令 除了核心功能默认内置的指令(例如v-model和v-show等),Vue也允许创建自己的指令。自己做的指令中也可以封装某个功能,这样就能达到复用代码的目的。 #### 1、全局指令 创建自定义指令需要用到`.directive`方法,第一个参数为指令名称,后续调用需要用到`v-指令名`,第二个参数是一个对象,里面一般是生命周期函数,一般从`mounted()`之后才会生效,生命周期函数第一个参数都会传入一个`element`简写`el`的参数,其值为当前属性的对象。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> <div v-date></div> <p v-date></p> </div> <script> // 创建Vue实例 const app = Vue.createApp({ data() { return {} } }); app.directive('date',{ mounted(el){ el.innerHTML = new Date(); } }) const vm = app.mount('#app'); </script> </body> </html> ``` **注意**:全局指令是创建到全局组件上的;直接通过对象属性赋值即可。 #### 2、局部指令 局部指令需要创建到跟组件上,可以通过其`directives`属性定义,以属性的方式来定义,用法与全局指令相同。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> <div v-date></div> <p v-date></p> </div> <script> // 创建Vue实例 const app = Vue.createApp({ data() { return {} }, directives: { date: { mounted(el) { el.innerHTML = new Date(); } } } }).mount('#app'); </script> </body> </html> ``` #### 3、指令参数 在使用自定义指令时可以通过`v-指令名="参数值"`来传参,多个参数可以传入一个对象,在自定义指令中,第二个参数`binding`是用来获取绑定的参数值的,可以用`binding.value`来调用参数值。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> <input max="1000" min="0" step="1" type="range" v-model="num"/>{{num}}<br> <img alt="" src="assets/img/spingfw.jpg" v-circleimg="num"> </div> <script> // 创建Vue实例 const app = Vue.createApp({ data() { return { num: 100 } }, directives: { circleimg: { mounted(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; }, updated(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; } } } }).mount('#app'); </script> </body> </html> ``` ## 二、Mixin混入 Mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个Mixin对象可以包含任意组件选项。当组件使用Mixin对象是,所有Mixin对象的选项将被”混合“进入该组件本身的选项。 #### 1、基本用法 声明一个变量/常量来存储mixin的数据,其对象属性与组件或实例属性完全一致,当有多个mixin时可以同时混入多个。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> 姓名:<span v-text="name"></span>;日期:<span v-text="time"></span><br> <input max="1000" min="0" step="1" type="range" v-model="num"/>{{num}}<br> <img alt="" src="assets/img/spingfw.jpg" v-circleimg="num"> </div> <script> const mixin1 = { data() { return { name: '张三' }; }, directives: { circleimg: { mounted(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; }, updated(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; } } } }; const mixin2 = { data() { return { time: '' } }, mounted() { setInterval(() => { let time = new Date(); this.time = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds(); }, 1000) } } // 创建Vue实例 const app = Vue.createApp({ data() { return { num: 100 } }, mixins: [mixin1, mixin2] }).mount('#app'); </script> </body> </html> ``` #### 2、混入优先级 当组件当中有属性与Mixin中重复,那么组件中的属性优先级更高,但是生命周期方法除外,因为在混入前要先声明Mixin对象。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> 姓名:<span v-text="name"></span>;日期:<span v-text="time"></span><br> <input max="1000" min="0" step="1" type="range" v-model="num"/>{{num}}<br> <img alt="" src="assets/img/spingfw.jpg" v-circleimg="num"> </div> <script> const mixin1 = { data() { return { name: '张三', num: 20 }; }, directives: { circleimg: { mounted(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; }, updated(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; } } } }; const mixin2 = { data() { return { time: '' } }, mounted() { console.log("mixin2-mounted"); setInterval(() => { let time = new Date(); this.time = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds(); }, 1000) } } // 创建Vue实例 const app = Vue.createApp({ data() { return { num: 100 } }, mounted() { console.log("app-mounted"); }, mixins: [mixin1, mixin2] }).mount('#app'); </script> </body> </html> ``` #### 3、全局Mixin Mixin可以全局注册,也就是将Mixin挂载到Vue实例上,这样组件中就不用再写`mixins:[]`选项了。一般使用`全局组件.mixin({})`来注册,可以注册多次,实现的效果与上面一样,只不过不可以在子组件中复用。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> 姓名:<span v-text="name"></span>;日期:<span v-text="time"></span><br> <input max="1000" min="0" step="1" type="range" v-model="num"/>{{num}}<br> <img alt="" src="assets/img/spingfw.jpg" v-circleimg="num"> </div> <script> // 创建Vue实例 const app = Vue.createApp({ data() { return { num: 100 } }, mounted() { console.log("app-mounted"); } }); app.mixin({ data() { return { name: '张三', num: 20 }; }, directives: { circleimg: { mounted(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; }, updated(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; } } } }); app.mixin({ data() { return { time: '' } }, mounted() { console.log("mixin2-mounted"); setInterval(() => { let time = new Date(); this.time = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds(); }, 1000) } }); const vm = app.mount('#app'); </script> </body> </html> ``` ## 三、插件 plugin插件是把通用功能封装起来,通常向Vue添加全局级功能,比如给Vue添加自定义指令、Mixin等。 #### 1、基本用法 插件的声明分为两种方式,第一种为对象形式,里面必须有固定的`install()`函数,第二种函数形式,将`install()`函数匿名。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> </div> <script> // 插件声明方式有两种 // 1、对象形式 const Plugin1 = { // app为Vue实例,options为参数 install(app, options) { console.log("hello world."); console.log(app); console.log(options); } }; // 2、函数形式,本质上声明的就是install函数 const Plugin2 = (app, options) => { console.log("hello world."); console.log(app); console.log(options); }; // 创建Vue实例 const app = Vue.createApp({}); // 应用插件 app.use(Plugin2, { name: '张三' }) const vm = app.mount('#app'); </script> </body> </html> ``` #### 2、给Vue扩展功能 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="assets/js/vue.global.js"></script> </head> <body> <div id="app"> 姓名:<span v-text="name"></span>;日期:<span v-text="time"></span><br> <input max="1000" min="0" step="1" type="range" v-model="num"/>{{num}}<br> <img alt="" src="assets/img/spingfw.jpg" v-circleimg="num"> </div> <script> // 插件声明方式有两种 // 2、函数形式,本质上声明的就是install函数 const Plugin2 = (app, options) => { app.directive('circleimg',{ mounted(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; }, updated(el, binding) { el.style.width = binding.value + "px"; el.style.height = binding.value + "px"; el.style.borderRadius = binding.value / 2 + "px"; } }); app.mixin({ data() { return { name: '张三', num: 20, time: '' }; }, mounted() { console.log("mixin2-mounted"); setInterval(() => { let time = new Date(); this.time = time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds(); }, 1000) } }); }; // 创建Vue实例 const app = Vue.createApp({}); // 应用插件 app.use(Plugin2) const vm = app.mount('#app'); </script> </body> </html> ``` **注意**:扩展功能时使用的是`directive`、`mixin`不是`directives`、`mixins` 最后修改:2025 年 10 月 28 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。