# 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 指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • 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 上一个虚拟节点,仅在 updatecomponentUpdated钩子中可用。
<!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>
上次更新: 10/29/2019, 6:04:16 PM