笔记来源:拉勾教育 - 大前端就业集训营
文章内容:学习过程中的笔记、感悟、和经验
Vue进阶语法
自定义指令
官方文档:cn.vuejs.org/v2/guide/cu…
指令用于简化Dom操作,相当于对基础Dom操作的一种封装
当我们希望使用一些内置指令不具备的Dom操作功能时,可以进行自定义指令的设置
自定义全局指令
可以被任意Vue实例或者组建使用的指令,也就是说哪怕我们new了多个Vue实例,这些实例都可以使用全局自定义指令
Vue提供了directive方法可以进行自定义指令的创建
<body>
<div id="app">
<!-- 在元素上使用自定义全局指令cwn,控制台输出 ‘我插入dom中了’ -->
<!-- 注意,使用自定义前面加v- -->
<p v-cwn>123</p>
<!-- 设置标签diaplay为none,,控制台输出 ‘我插入dom中了’ -->
<p v-cwn style="display: none;">123</p>
<!-- 设置标签v-if使标签不会被插入到页面中,控制台没哟输出任何内容,表示如果标签不能真正的插入到Dom中的话,上面的自定义指令并不会执行 -->
<p v-cwn style="display: none;" v-if="value === 0">123</p>
</div>
<script>
// 使用Vue的directive方法创建自定义指令
// 参数1:表示自定义指令名
// 参数2:配置项
Vue.directive('cwn', {
//inserted表示标签插入Dom中后执行的函数
//element是当前设置了自定义指令的元素本身,所以我们可以在函数中对元素做一些操作
//banding表示element上面的一些信息
inserted: function (element,banding) {
console.log('我插入dom中了')
// 打印元素看一下
console.log(element)
}
})
const vm = new Vue({
el: '#app',
data: {
value: ''
}
})
</script>
</body>
注意:inserted只是一个钩子函数,directive的第二个参数内部可以写多个钩子函数
自定义局部指令
只能在当前Vue实例或者组建内部使用的指令
自定义局部指令和全局指令使用方法很相似
<body>
<div id="app">
<!-- 在元素上使用自定义局部指令cwn,控制台输出 ‘我插入dom中了’ -->
<!-- 注意,使用自定义前面加v- -->
<p v-cwn>123</p>
<!-- 设置标签diaplay为none,,控制台输出 ‘我插入dom中了’ -->
<p v-cwn style="display: none;">123</p>
<!-- 设置标签v-if使标签不会被插入到页面中,控制台没哟输出任何内容,表示如果标签不能真正的插入到Dom中的话,上面的自定义指令并不会执行 -->
<p v-cwn style="display: none;" v-if="value === 0">123</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
value: ''
},
// directives内部可以设置自定义局部指令
directives: {
// cwn是指令名,指令名的值是一个对象
cwn: {
// 对象内部全部都是钩子函数,可以有多个
// inserted表示当标签插入Dom中执行
inserted(element) {
console.log('我插入dom中了')
console.log(element)
}
}
}
})
</script>
</body>
注意:局部指令不能再vue实例之外的位置使用
过滤器
用于进行文本内容格式化处理的工具
可以在差值表达式和v-bind中使用
全局过滤器
可以在任何Vue实例中使用
// 书写方法
Vue.filter( 过滤器名称 , function(value){
// 逻辑代码
return 处理结果
})
使用方法:在差值表达式和v-bind中使用管道符号“|”连接数据
<body>
<div id="app">
<!-- 使用过滤器filterId和filterContent,使用管道符|连接 -->
<p :id="id | filterId">123</p>
<p>{{ content | filterContent }}</p>
</div>
<script>
// 设置全局过滤器,
// 参数1:过滤器名称
// 参数2:过滤器执行函数,解构一个参数value为要处理的数据
Vue.filter('filterId', function (value) {
// 我们在这里拼接字符
return '我是id' + value
})
Vue.filter('filterContent', function (value) {
return '我是Content' + value
})
const vm = new Vue({
el: '#app',
data: {
id: '123',
content: '文本内容'
}
})
</script>
</body>
注意:过滤器最后只能使用return出来的结果,如果不写return则输出为空
全局过滤器特殊用法
-
Vue中允许数据传入到多个过滤器中进行处理,后一个过滤器使用的value是前一个过滤器返回值
- 例如:
<p :id="id | filterId | filterContent">123</p>
- 例如:
-
一个过滤器传入多个参数,参数也可以在过滤器中使用,注意value始终都是是第一个值,后面新传入的参数向后顺延
-
<!-- 过滤器filterId再传入两个参数 --> <p :id="id | filterId(10, 'hello')">123</p> // 过滤器使用参数 Vue.filter('filterId', function (value, x, y) { // 我们在这里拼接字符 return value + x + y })
-
局部过滤器
只能在当前Vue实例中使用的过滤器
// 书写方法:书写在Vue实例中
filters: {
// 过滤器名称:函数
filterContent: function (value) {
// 逻辑代码
return 处理结果
}
}
<body>
<div id="app">
<!-- 调用局部过滤器 -->
<p>{{ content | filterA }}</p>
<p>{{ content | filterB }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
id: '123',
content: '文本内容'
},
// filters里面书写局部过滤器,只能在当前vue实例中使用
filters: {
// 过滤器可以按照过滤器名:函数的方式书写
filterA: function (value) {
return '我是过滤器A' + value
},
// 也可以直接简写为一个函数
filterB(value) {
return '我是过滤器B' + value
},
}
})
</script>
</body>
和全局过滤器一样,局部也可以使用多个过滤器处理一个数据,同样也可以传入多个参数
过滤器注意事项
如果同时存在全局过滤器和局部过滤器并且同名的时候,Vue优先使用局部过滤器
计算属性
- Vue视图(HTML)中不建议书写复杂的逻辑,不利于维护
- 封装函数是很好的方式,但是有时可能会重复计算消耗不必要的资源
- 计算数属性使用时为属性的形式,第一次访问时会自动触发内部函数,并把结果保存下来以供下次使用,后续再次调用都会检查依赖的数据是否发生变化,如果发生变化会再次执行,否则会直接使用当前存储的结果
<body>
<div id="app">
<!-- 使用计算属性 -->
<p>{{ sum }}</p>
<!-- 后面再次使用计算属性会先判断arr是否发生变化,如果没有变化直接使用上次的结果 -->
<!-- 下面两次调用在控制台可以看到没有打印‘我执行了’,证明下面两次调用没有再次执行计算属性 -->
<p>{{ sum }}</p>
<p>{{ sum }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
arr: [1, 2, 3, 4]
},
// computed内部书写计算属性
computed: {
// 可以按照函数的方法书写,sum为计算属性名,
sum() {
// 在每次执行计算属性之前都输出一下‘我执行了’
console.log('我执行了')
let he = 0
let arr = this.arr
for (const i of arr) {
he += i
}
return he
}
}
})
</script>
</body>
计算属性-computed和函数-methods的区别
- 计算属性具有缓存性,函数没有
- 计算属性通过属性名访问,函数需要调用
- 计算属性仅仅适用于计算操作
案例
需求:数组元素大于10时创建li,否则不创建
解决方法:
- v-if和v-for结合
- v-for和methods结合
- v-for和计算属性结合(最优解)
<body>
<div id="app">
<!-- 利用计算属性动态创建结构 -->
<ul>
<!-- v-for使用计算属性fn结果 -->
<li v-for="item in fn" :key="item">{{ item }}</li>
<!-- 后续再次使用的时候也调用fn,就可直接使用newArr -->
<li v-for="item in fn" :key="item">{{ item }}</li>
<li v-for="item in fn" :key="item">{{ item }}</li>
<li v-for="item in fn" :key="item">{{ item }}</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
arr: [1, 11, 2, 22, 3, 33, 4, 44, 5, 55]
},
computed: {
// 计算属性
fn() {
// 使用数组筛选方法,筛选全部大于10的数据
return this.arr.filter(item => item > 10)
}
}
})
</script>
</body>
计算属性的setter
计算属性默认只有getter。vue允许给计算属性设置setter进行一些数据的更新(一般情况下,使用getter的方式比较多)
<body>
<div id="app">
<!-- 使用计算属性 -->
<p>{{sun}}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
// 设置三个字符串存储名字
x: '张',
y: '三',
z: ''
},
computed: {
// 计算属性完整写法
sun: {
// get - 默认用法,使用会直接执行get
get() {
return this.x + this.y + this.z
},
// set - 修改数据,当我们在程序中修改sun的值的时候(vm.sun='韩梅梅')会触发这个方法,然后会再次调用get渲染
set(value) {
const newArr = value.split('')
this.x = newArr[0]
this.y = newArr[1]
this.z = newArr[2]
}
}
}
})
</script>
</body>
侦听器
用于监听数据变化,并执行指定操作
<body>
<div id="app">
<!-- 侦听器 -->
<input type="text" v-model="value">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
value: ''
},
// watch内部书写侦听器
watch: {
// 侦听value变化,接收两个值,新值和旧值,一旦发生数据变化执行结构体
value(newvalue, oldvalue) {
console.log('侦听器执行了', newvalue, oldvalue)
}
}
})
</script>
</body>
监听对象数据
如果我们直接修改对象赋值,那么上面的方法是可以生效的,但是如果我们更改对象内部内部成员,就需要使用下面的方法
监听对象内部值变化,需要将侦听器书写为一个对象,内部书写deep:true,在通过gandler设置处理函数
<body>
<div id="app">
<!-- 侦听器 -->
<input type="text" v-model="value">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
value: '',
obj: {
name: 'zs',
age: 16
}
},
// watch内部书写侦听器
watch: {
// 侦听value变化,接收两个值,新值和旧值,一旦发生数据变化执行结构体
value(newvalue, oldvalue) {
console.log('侦听器执行了', newvalue, oldvalue)
},
obj: {
// 监听对象内部成员变化
deep: true,
handler(val, oldval) {
//val, oldval 是相同的,他们指向同一个物内存位置
console.log('侦听器执行了', val, oldval)
}
}
}
})
</script>
</body>
注意事项
- 当我们更改(非替换)数组或者对象时,回调函数中的新值和旧值是相同的,因为此时他们指向同一个位置
- 数组不需要使用deep: true设置,所以使用第一种方法就可以了(注意vue中数组处理不可以使用索引和legth操作)
Vue DevTools
vue官方提供的用来调试Vue应用的工具 - 一款谷歌浏览器插件,直接在谷歌扩展商店搜索即可
地址(需要科学上网):chrome.google.com/webstore/de…
注意事项
- 网页必须应用的Vue才能看到Vue DevTools
- 使用的vue必须是Vue.js而不是vue.min.js
- 需要使用HTTP协议打开,不可以使用file(右键运行)的方式打开
使用方法
打开开发者工具F12,找到Vue即可使用,会看到一个操作面板,其中的root点击可以查看到当前实例的数据
Vue生命周期
Vue实例的生命周期,从vue实力创建到运行再到销毁的过程
官方文档:cn.vuejs.org/v2/guide/in…
生命周期函数/钩子:可以在特定生命周期阶段执行特定的功能
创建阶段
- 初始化阶段
- beforeCreate:实例在初始化之前调用,一般不用,此时data、函数都没有创建完毕
- created:实例创建之后调用,比较常用,此时data、函数都已经创建并可使用了
- 挂载阶段
- beforeMount:实例挂载前调用
- mounted:实例挂载之后调用,已经可以进行Dom操作了(比较常用)
注意:创建阶段函数只能执行一次
运行阶段
- beforeUpdata:数据更新后,实体更新前调用,此时视图还没有更新,访问只能获取更新前的视图数据
- updated:视图更新后调用
注意:此阶段按需调用,每个阶段的函数都可以执行多次
销毁阶段
- beforeDestroy:实例销毁之前调用,此时实例还没有销毁,内部的数据等还能访问
- destroyed:实例销毁之后调用,此时已经不存在实例的,也无法访问了