主要讲:
- 资源:directives
- 组合:mixins、extends、provide、inject
Direvtives 指令
官方文档
用途:主要用于DOM操作,并减少DOM重复操作。
指令包括:
v-if
v-for
v-show
v-html
- 等
不过这里主要讲自己创建一个指令,语法为:
Vue.directive('x',{
bind: function (el, info, vnode, oldVnode) {
//类似created
},
inserted: function (参数同上) {
//当元素被插入到页面时
},
update: function (参数同上) {
//类似updated
},
componentUpdated: function (参数同上) {
//用得不多
},
unbind: function (参数同上) {
//类似destroyed
}
})
一般是用 bind
和 inserted
。参数一般用 el
和 info
如造出一个 v-x
,点击即出现一个x
例子1:
Vue.directive('x',{
inserted: function (el) {//当元素被插入到页面时
el.addEventListener('click', ()=>{console.log('x')})
}
})
new vue({
......
})
这是一个全局指令,可以在任何地方使用 v-x
例子2:
new Vue({
...,
directives:{
"x":{
inserted(el){
el.addEventListener('click', ()=>{console.log('x')})
}
}
}
})
这是一个局部指令,只能在这个组件使用。
这个创建指令甚至可以模仿一个 v-on
:模仿v-on
而且还能简写:函数简写
Mixin 混入
情景:如果有两个组件,这两个组件的代码存在一定的重复,如下简单的事例:
src/Test.vue
<template>
<div>
<button v-on:click="clicked('字符串1')">
Button 1
</button>
</div>
</template>
<script>
export default {
name: "Test",
methods: {
clicked(value) {
console.log(value);
}
}
};
</script>
上面的组件展示了一个按钮,点它会输出一个字符串。下面的组件会做确切相同的功能:
src/Modal.val
<template>
<div>
<button v-on:click="clicked('字符串2')">
Button 2
</button>
</div>
</template>
<script>
export default {
name: "Modal",
methods: {
clicked(value) {
console.log(value);
}
}
};
</script>
然后在App.vue文件引入和声明两个组件:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<Test />
<modal />
</div>
</template>;
<script>
import Test from "./Test.vue";
import Modal from "./Modal.vue";
export default {
name: "app",
components: {
Test,
Modal
}
};
</script>
看了这两个组件,代码存在一定的重复,不仅浪费内存,而且也不符合DRY原则。这时可以考虑Mixins。
Mixin
所谓的Mixin(混入),其实就是复制。
通过mixins可以封装一部份重复的代码,然后可以在需要时将其引入各种组件。
语法
//定义一个mixin对象
let myMixin = {
created: function{
this.hello()
}
methods: {
hello: function() {
console.log("来自mixin的消息")
}
}
}
//定义一个组件来使用这个 mixin
let Component = Vue.extend({
mixins: [myMixin]
});
let component = new Component();
重构上面的例子
创建Mixin.vue文件:
<script>
export default {
methods: {
clicked(value) {
console.log(value);
},
},
};
</script>
Test.vue引入Mixin.vue文件:
<template>
<div>
<button v-on:click="clicked('字符串1')">
Button 1
</button>
</div>
</template>
<script>
import MixinWJ from "./Mixin.vue"
export default {
name: "Test",
mixins: [MixinWJ]
};
</script>
Modal.vue同理:
<template>
<div>
<button v-on:click="clicked('字符串2')">
Button 2
</button>
</div>
</template>
<script>
import MixinWJ from "./Mixin.vue"
export default {
name: "Modal",
mixins: [MixinWJ]
};
</script>
App.vue
<template>
<div id="app">
<Test/>
<modal />
</div>
</template>;
<script>
import Test from "./Test.vue";
import Modal from "./Modal.vue";
export default {
name: "app",
components: {
Test,
Modal
}
};
</script>
这就是mixin的用法!
Mixins有两种类型
- 局部 Mixins:仅限在引用的文件使用。
- 全局 Mixins: 顾名思义,就是在整个项目都可以用,语法如下:
但不推荐使用全局Mixin。<script>
Vue.mixin({
mountd(){
console.log("来自全局mixin的消息")
}
})
</script>
总结
:::success Mixin就是把代码相似的组件收拢到一起成为一个组件,然后继承这个组件。 :::
extends 继承
与Mixin没什么区别,就是另一种写法。
只需要把mixin的例子里的 mixin:[mixin]
改成 extends:mixin
,注意extends只接受一个,而mixin可以接受一个数组。如:
const extend = {
data () {
return name : 'extend 消息'
}
}
const mixin1 = {
data(){
return name :'mixin1 消息'
}
}
const mixin2 = {
data(){
return name :'mixin2 消息'
}
}
export default {
mixins : [mixin1, mixin2],
extends: extend,
name: 'app',
data(){
return name: 'name'
}
}
不过还是推荐使用mixins!
provide 提供 与 inject 注入
provide允许一个祖先组件向所有子孙后代注入一个依赖。如下例子:
父组件Ba.vue
<script>
export default {
provide: return {name :'Aresn'}
}
</script>
子组件Er.vue
<script>
export default {
inject: ['name'],
mounted(){
console.log(this.name) //Aresn
}
}
</script>
实例:
实现一个按钮切换颜色。
父组件App.vue
<template>
<div :class="`theme-${themeName}`">
<Button1 />
</div>
</template>
<script>
import Button1 from "./Button1.vue";
export default {
name: "App",
provide(){
return {
themeName: this.themeName,
changeTheme: this.changeTheme
}
},
data(){
return {
themeName: "blue",
}
},
methods: {
changeTheme(){
if(this.themeName === 'blue'){
this.themeName = "red"
} else {
this.themeName = "blue"
}
}
},
components: {
Button1,
}
}
</script>
<style>
.theme-blue button{
background: blue;
}
.theme-red button{
background: red
}
</style>
子组件
<template>
<div>
<button @click="changeTheme">按钮</button>
</div>
</template>
<script>
export default {
inject:['changeTheme','themeName']
}
</script>