自定义指令
- 指令用于简化DOM操作,相当于对基础DOM操作的一种封装
- 使用一些内置指令不具备的DOM功能时,可以进行自定义指令设置
自定义全局指令
- 指的是可以被任意Vue实例或者组件使用的指令
书写什么指令名称,使用时就是v-名称 - 拓展:
<div id="app">
<input type="text" v-focus.a.b='100+1'>
</div>
<script>
// 自定义全局指令
Vue.directive('focus',{
inserted(el,binding){
// console.log(el);
console.log(binding)
el.focus();
}
});
new Vue({
el: '#app',
data: {
}
});
})
</script>
inserted内部的第二个参数binding指的是当前指令设置的相关信息
自定义局部指令
-
指的是可以在当前 Vue 实例或组件内使用的指令
<script>
// 自定义局部指令
new Vue({
el: '#app',
data: {},
directives: {
focus: {
inserted (el) {
el.focus();
}
}
}
});
new Vue({
el: '#app2'
});
</script>
过滤器
- 过滤器用于进行文本内容格式化处理
- 过滤器可以在插值表达式和 v-bind 中使用
全局过滤器
- 全局过滤器可以在任意Vue实例中使用
Vue.filter('过滤器名称',function(value){
//逻辑代码
return '处理结果';
})
- 由于过滤器能在插值表达式和v-bind中使用,通过管道符 | 连接数据
<div id="app">
<!-- 在v-bind中 -->
<div v-bind:id="id | filterId"></div>
<!--在插值表达式中 -->
<div>{{content | filterContent }}</div>
</div>
事例:清除横线
<body>
<div id="app">
<p v-bind:title="value | filterA">这是标签</p>
<p>{{ value2 | filterA }}</p>
</div>
<div id="app2">
<p>{{ value | filterA }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
// 设置全局过滤器
Vue.filter('filterA', function (value) {
return value.split('-').join('');
});
new Vue({
el: '#app',
data: {
value: 'a-b-c',
value2: 'x-y-z'
}
});
new Vue({
el: '#app2',
data: {
value: 'q-w-e'
}
})
</script>
</body>
全局过滤器的特殊用法
-
可以将一个数据传到多个过滤器进行处理
<body>
<div id="app">
<p>{{ value | filterA | filterB }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.filter('filterA', function (value) {
console.log(value, 'filterA');
return value.split('-').join('');
});
Vue.filter('filterB', function (value) {
console.log(value, 'filterB');
return value[0].toUpperCase() + value.slice(1);
})
new Vue({
el: '#app',
data: {
value: 'a-b-c'
}
});
</script>
</body>
-
一个过滤器可以传入多个参数
<body>
<div id="app">
<p>{{ value | filterC('lagou-', 200) }}</p>
<p>{{ value | filterC('qqq-', 200) }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.filter('filterC', function (par1, par2, par3) {
return par2 + par1.split('-').join('') + par3;
});
new Vue({
el: '#app',
data: {
value: 'a-b-c'
}
});
</script>
</body>
局部过滤器
-
只能在当前的Vue实例中使用
<body>
<div id="app">
<!-- <p>{{ content | filterA }}</p>
<p>{{ content2 | filterA }}</p> -->
<p>{{ content | filterA | filterB }}</p>
<p>{{ content | filterA | filterC('lagou-') }}</p>
</div>
<div id="app2">
<p>{{ content | filterA }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
content: 'a-b-c',
content2: 'x-y-z'
},
filters: {
filterA: function (value) {
return value.split('-').join('');
},
filterB: function (value) {
return value.split('').reverse().join('');
},
filterC (value, prefix) {
return prefix + value;
}
}
});
/* new Vue({
el: '#app2',
data: {
content: 'q-w-e'
}
}) */
</script>
</body>
如果全局过滤器和局部过滤器重名冲突了的话,只有局部过滤器生效
计算属性
-
Vue.js 的视图不建议书写复杂逻辑,这样不利于维护
- 封装函数是个很好的方式,写在methods中,但是有时重复的计算会消耗不必要的性能
-
计算属性使用时为属性形式,访问时会自动执行对应的函数
<body>
<div id="app">
<p>{{ getResult }}</p>
<p>{{ getResult }}</p>
<p>{{ getResult }}</p>
<p>{{ getResult }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4, 5]
},
computed: {
getResult () {
console.log('执行了计算属性');
var arr = this.arr;
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
}
})
</script>
</body>
由计算属性引出methods与computed的区别
- computed具有缓存性,methods没有
- computed通过属性名访问,methods需要调用
- computed只适用于计算操作
计算属性的练习
- 准备一个数组,根据数组数据创建列表
- 要求:当数据大于10时创建li,否则不创建
- 三种思路:
- v-if和v-for的组合
执行效率很低,v-if和v-for不适合一起使用,解决办法是v-if放在父元素上,但是这个方法不适合这个情况
- v-if和v-for的组合
<body>
<div id="app">
<ul>
<!-- 不推荐 v-if 与 v-for 同时应用与同一个元素 -->
<li v-if="item > 10" v-for="item in arr">{{ item }}</li>
</ul>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 11, 2, 22, 3, 33, 4, 44, 5, 55]
}
});
</script>
</body>
- v-for和methods结合
正如计算属性的功能所述,用methods如果重复调用就没有computed的效率高
<body>
<div id="app">
<ul>
<li v-for="item in fn()">{{ item }}</li>
</ul>
<ul>
<li v-for="item in fn()">{{ item }}</li>
</ul>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 11, 2, 22, 3, 33, 4, 44, 5, 55]
},
methods: {
fn () {
console.log('函数代码执行了');
// 遍历 arr ,找到大于 10 的数据
var resultArr = [];
for (var i = 0; i < this.arr.length; i++) {
if (this.arr[i] > 10) {
resultArr.push(this.arr[i])
}
}
return resultArr;
}
}
});
</script>
</body>
- v-for与计算属性结合
<body>
<div id="app">
<ul>
<li v-for="item in result">{{ item }}</li>
</ul>
<ul>
<li v-for="item in result">{{ item }}</li>
</ul>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: [1, 11, 2, 22, 3, 33, 4, 44, 5, 55]
},
computed: {
result () {
console.log('执行了代码');
return this.arr.filter(item => item > 10);
}
}
});
</script>
</body>
计算属性的setter
-
计算属性默认只有 getter(计算属性被访问的时候执行的操作),Vue.js 也允许给计算属性设置 setter(修改计算属性,赋值)
<body>
<div id="app">
<p>{{ fullName }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '三'
},
computed: {
// 默认书写方式:
/* fullName () {
return this.firstName + this.lastName;
} */
// 分开书写 getter 与 setter
fullName: {
get () {
return this.firstName + this.lastName;
},
set (newValue) {
var nameArr = newValue.split(' ');
this.firstName = nameArr[0];
this.lastName = nameArr[1];
}
}
}
});
</script>
</body>
侦听器
-
用于监听数据变化并且执行指定的操作
<body>
<div id="app">
<input type="text" v-model="value">
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
value: ''
},
watch: {
value () {
console.log('侦听器执行了');
}
}
})
</script>
</body>
侦听器处理数组和对象时
- 为了监听对象内部值的变化,需要将watch书写为对象,设置选项deep:true,通过handler设置处理函数
-
数组不需要写deep,就一般的侦听器就可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<script src="lib/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
title: '这是内容',
obj: {
content1: '内容1',
content2: '内容2'
},
arr: [1, 2, 3, 4, 5]
},
watch: {
title (val, oldVal) {
console.log('title 被修改了', val, oldVal);
},
obj: {
deep: true,
handler (val, oldVal) {
console.log('obj 被修改了', val, oldVal);
console.log(val === oldVal);
}
},
arr (val, oldVal) {
console.log('arr 修改了', val, oldVal)
},
}
});
</script>
</body>
</html>
注意点:
-
注意:当更改(非替换)数组或对象时,回调函数中的新值与旧值相同,因为它们的引用都指向同一个数组 、对象
- 注意:数组操作不要使用索引与length,无法触发侦听器函数(修改数组的,或者Vue.set等等都可以监听到)
Vue DevTools
- 是Vue.js官方提供的用来调试Vue应用的工具
- 在chrome网上应用商店搜索来源于vuejs.org的插件
- 注意事项:
- 网页必须用了Vue.js功能才能看到DevTools
- 网页必须使用vue.js而不是Vue.min.js
-
网页需要在http协议下打开,而不是file协议本地打开
避免了这些注意事项之后打开网页拓展程序会显示高亮,并且开发者工具可以调出vue调试界面
Vue.js生命周期
- Vue.js 生命周期指的是 Vue 实例的生命周期
- Vue 实例的生命周期,指的是实例从创建到运行,再到销毁的过程
官方的图示
https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
通过设置生命周期函数,可以在生命周期的特定阶段执行功能
生命周期函数也叫作生命周期钩子
Vue.js生命周期函数
- 创建阶段:
- beforeCreate:实例初始化之前调用
- created:实例创建后调用(重要:进行一些数据的请求)
- beforeMount:实例挂载之前调用
- mounted:实例挂载完毕(重要:DOM的一些操作)
特点:每个实例只能执行一次
- 运行阶段
- beforeUpdate:数据更新,视图更新前调用
- updated:视图更新后调用
特点:按需调用
- 销毁阶段
- beforeDestory:实例销毁之前调用
- destroyed:实例销毁后调用