# Vue 的可复用性与组合
# 混入
混入 (mixins
) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="05-vue/lib/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
var objs = {
el: "#app",
data() {
return {
info: 111,
};
},
created() {
console.log("我是混入的对象!");
},
};
//var vm = new Vue(objs);
var vm = new Vue({
mixins: [objs],
});
</script>
</body>
</html>
# 自定义指令
常见的指令如 v-text v-model 都是 vue 封装好的语法糖
我们也可以封装自己的指令(用于对 dom 执行某些操作)
封装自己的指令是通过directives
来执行的
# 常用指令钩子函数
- bind 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
- inserted 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
- componentUpdated 指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind 只调用一次,指令与元素解绑时调用。
# 钩子函数参数
el
指令所绑定的元素,可以用来直接操作 DOM 。binding
:一个对象,包含以下属性:name
指令名,不包括 v- 前缀。value
指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为 2。oldValue
指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为 "1 + 1"。arg
传给指令的参数,可选。例如v-my-directive:foo
中,参数为 "foo"。modifiers
一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode
Vue 编译生成的虚拟节点oldVnode
上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="05-vue/lib/vue.js"></script>
</head>
<body>
<div id="app">
<div v-aa="'blue'">
111
</div>
</div>
<script>
var objs = {
el: "#app",
data() {
return {
info: 111,
};
},
created() {
console.log("我是混入的对象!");
},
directives: {
aa: {
bind(el, binding, vnode, oldVnode) {
// 指令绑定到元素上的
console.log(el, binding, vnode, oldVnode);
el.style.color = binding.value;
},
inserted(el, binding, vnode, oldVnode) {
// 指令插入到元素上执行
console.log(el, binding, vnode, oldVnode);
},
},
},
};
//var vm = new Vue(objs);
var vm = new Vue({
mixins: [objs],
});
</script>
</body>
</html>
# 指令简写
在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。
<script>
Vue.directive("color-swatch", function(el, binding) {
el.style.backgroundColor = binding.value;
});
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="05-vue/lib/vue.js"></script>
</head>
<body>
<div id="app">
<!-- <div v-aa="'blue'">
111
</div> -->
<!-- <div v-aaa>
111
</div> -->
<input type="text" v-aaa v-if="isShow" />
<button @click="isShow = !isShow">
取反
</button>
</div>
<script>
var that;
var vm = new Vue({
el: "#app",
data() {
return {
info: 111,
isShow: false,
};
},
created() {
console.log("我是混入的对象!");
that = this;
},
directives: {
aaa(el) {
console.log(el, this, that);
that.$nextTick(function() {
el.focus();
});
// setTimeout(()=>{
// el.focus()
// })
},
},
});
</script>
</body>
</html>
# nextTick(function(){})
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。相当于 setTimeout
# filter 过滤器
对需要的数据进行过滤操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="05-vue/lib/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in list " :key="item.name">
{{ item.name }} {{ item.age }} {{ item.money | fil1 | fil }}
</li>
</ul>
</div>
<script>
var that;
var vm = new Vue({
el: "#app",
data() {
return {
list: [
{
name: "张三",
age: 40,
money: 100,
},
{
name: "王五",
age: 20,
money: 200,
},
{
name: "李四",
age: 30,
money: 300,
},
],
};
},
filters: {
fil1(val) {
return val * 2;
},
fil(val) {
console.log(val);
return val + "元";
},
},
created() {
console.log("我是混入的对象!");
that = this;
},
});
</script>
</body>
</html>