watch
watch其实就是 (this可以访问到的)某个值的 change事件;
语法
-
简单版语法
-
watch{ //写出需要侦听 实例话对象(this能够找到的) 属性名,若是存在点需要变为字符串 属性名(newVal,oldVal){ // 进行处理 } }
-
-
若是需要深度监听(当监听器监听的数据为引用类型时,有时候嵌套数据(属性之类的)被修改可能监听不到)
-
watch:{ 属性名:{ handler(newVal,oldVal){ // 进行处理 }, deep:true } }
- 加一个
deep
属性,这样不论你监听的数据嵌套多深都会被监听到
-
-
若是需要在最初渲染的时候执行1次
-
watch:{ 属性名:{ handler(newVal,oldVal){ // 进行处理 }, immdiate:true } }
-
示例
<template>
<ul style="margin-top:20px">
<li v-for="(value,key) in obj" :key="key">{{value}}</li>
<li><el-button @click="obj.age++">点击</el-button></li>
</ul>
</template>
<script>
export default {
data(){
return{
obj:{
name:'chaochao',
sex:'女',
age:18
}
}
},
watch:{
obj(newVal){
console.log('值改变了', newVal)
}
}
}
</script>
-
-
如上所示监听了一个对象(引用类型),当我点击按钮时 age属性值会发生变化;
-
实际操作过程:点击按钮->视图数据不断变化,但是确没有在控制台输出任何结果;
-
原因:只能监听一层,若是想监听多层,需要使用深度监听;
-
watch:{ obj:{ handler(newVal){ console.log('值改变了', newVal) }, deep:true } } }
-
-
也可以单独监听age属性
-
watch:{ 'obj.age'(newVal){ console.log('值改变了',newVal) } }
-
使用场景
watch的依赖是单个的(相当于是某个值的change事件);当某个值改变影响多个变量的值的时候就可以使用watch;
computed
模板的使用非常便利,但是最初设计是用于简单数据,若是模板内部放入 复杂的逻辑关系会使得模板臃肿且难以维护,因此若是复杂的数据运算可以使用方法 或 计算属性;
语法
computed:{
计算属性名(){
return 值
}
}
- 计算属性虽然是个方法,但是不可以传值,在html中可以直接作为属性使用;
- 返回值为依赖 一个或多个data中数据计算的结果;
- 计算属性存在缓存,只有依赖的值发生变化时,才会重新渲染;
- 计算属性不可直接修改,当依赖改变时会自动修改;
当然我们页可以使用方法去处理这段逻辑关系,返回处理后的值,以下面这个例子进行说明
// 计算属性
computed:{
sum(){
return this.a+this.b
}
}
// 方法
getSum(){
return this.a+this.b
}
虽然看起来是一样的,但是呢若是我们在页面中使用多次,就能看出区别
<!-- 虽然在页面中使用多次,但是计算属性不会重复调用-->
<div>{{sum}}</div>
<div>{{sum}}</div>
<div>{{sum}}</div>
<div>{{sum}}</div>
<!-- 方法只要使用一次就会调用一次-->
<div>{{getSum()}}</div>
<div>{{getSum()}}</div>
<div>{{getSum()}}</div>
<div>{{getSum()}}</div>
计算属性传值
因为计算属性是不能传值的,但是若是想传值,可以return 一个方法出去
computed:{
方法名(){
# return 函数
# 函数内部return 想要使用的值
return (fn, id) => {
return this.userInfo[fn] && this.userInfo[fn].includes(+id)
? '#e40137'
: '#b4b4bd'
}
}
}
get与set方法
在计算属性中存在get和set方法
computed:{
attr:{
get(){
// 当在页面上使用attr时就会走get方法
return XXX
},
set(){
// 当改变计算属性时,需要提供set方法 ->一般在set里面把改变后的值设置给它的依赖
// 注意:如果需要set方法时,一定要完整写法
}
}
}
举例说明-全选非全选
<script>
const vue = new Vue({
el: '#app',
data: {
selectArr: [
{ name: '吃饭', value: false },
{ name: '睡觉', value: false },
{ name: '打豆豆', value: false }
]
},
computed: {
all: {
get () {
// [1]一进入页面使用初始化数据计算一次;[2]每次all变为true/false(依赖值的计算结果改变)就会再走一次;[3]其余时刻使用缓存数据
console.log('页面使用到了all')
return this.selectArr.every(item => item.value)
},
set (val) {
// all是绑定在全选框里的,当我们手动修改all的值时会走这个方法
console.log('修改了是否全选')
this.selectArr = this.selectArr.map(item => {
return {
name: item.name,
value: val
}
})
}
}
}
})
</script>
举例说明
<div id="app">
{{msg}} {{resMsg}}
</div>
<!-- 3.实例话对象VM -->
<script>
const vm = new Vue({
el: '#app',
data: {
msg: 'Hello'
},
computed: {
resMsg () {
return this.msg
.split('')
.reverse()
.join('')
}
}
})
</script>
使用场景
依赖一个或多个值
(是通过this可以访问到的值)产生一个新的值
的地方使用计算属性;
filter
过滤器是对接收的数据做一个统一的处理;
注意点
- 过滤器只能使用于插值语法{{}}和v-bind语法,不能用于其他场景;
- 在过滤器中
不能
使用this
语法
局部过滤器
// 1.给实例话对象添加一个filters属性;
// 2.在这个属性中添加一个方法;
// 3.对方法的形参做一定的处理并返回;
// 4.在插值表达式或者是v-bind中·{{实参|方法名}}
filters:{
方法名(形参){
return 值;
}
}
//使用
{{参数 | 方法名}}
全局过滤器
Vue.filter('过滤器的名字',function(形参){
return 值;
}
使用场景
一般来说我们用过滤器来格式化一些数据或者渲染的文本对于格式展现的要求