Vue--》计算属性与监视(侦听)属性的使用
Posted 亦世凡华、
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue--》计算属性与监视(侦听)属性的使用相关的知识,希望对你有一定的参考价值。
目录
计算属性(computed)
计算属性指的是通过一系列运算之后,最终得到一个值。这个动态计算出来的属性值可以被模板结构或methods方法使用,案例如下:
<div id="root">
R:<input type="text" v-model.number="r"><br>
G:<input type="text" v-model.number="g"><br>
B:<input type="text" v-model.number="b">
<div class="box" :style="backgroundColor:rgb">
rgb
</div>
<button @click="show">按钮</button>
</div>
<script src="/vue/vue.js"></script>
<script>
const vm = new Vue(
el:'#root',
data:
r:0 , g:0, b:0,
,
methods:
show()
console.log(this.rgb);
,
//所有计算属性都要定义到computed节点之下
computed:
// 计算属性在定义的时候,要定义成“方法格式”,在这个方法中会生成好的rgb(x,x,x)的字符串
//实现了代码的复用,只要计算属性中依赖的数据变化了,则计算属性会自动重新赋值
rgb()
return `rgb($this.r,$this.g,$this.b)`
)
</script>
使用名字动态改变实现计算属性案例:
<div id="root">
<input type="text" v-model="firstname"><br>
<input type="text" v-model="lastname"><br>
全名:<span>fullname</span>
</div>
<script src="/vue/vue.js"></script>
<script>
const vm = new Vue(
el:"#root",
data:
firstname:'张',
lastname:'三'
,
computed:
fullname:
//当初次读取fullname或所依赖的数据发生变化时,get被调用
get()
console.log('get被调用了');
return this.firstname+'-'+this.lastname
,
//当主动修改fullname时,set被调用
set(value)
console.log('set', value);
const arr = value.split('-');
this.firstname = arr[0]
this.lastname = arr[1]
)
</script>
计算属性:
1.定义:要用的属性不存在,要通过已有的属性得来
2.原理:底层借助了Object.defineproperty方法提供的getter和setter
3.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便
4.备注:计算属性最终会出现在vm上,直接读取使用即可;如果计算属性要被修改,那必须写set函数去响应改变,且set中要引起计算时依赖的数据发生改变。
监视属性(watch)
watch监视(侦听)器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。
监视的两种方法
通过new Vue时传入watch配置:
<div id="root">
<input type="text" v-model="name">
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue(
el:'#root',
data:
name:''
,
//所有的侦听器,都应该被定义到watch节点下
watch:
// 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
//newVal是“变化后的新值”,oldVal是“变化之前旧值”
name(newVal,oldVal) //监听name值的变化
console.log("监听到了新值"+newVal, "监听到了旧值"+oldVal);
)
</script>
通过vm.$watch监视:
<div id="root">
<h2>今天天气很info</h2>
<button @click="changeWeather">切换天气</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue(
el:'#root',
data:
isHot:true
,
computed:
info()
return this.isHot ? '炎热' : '凉爽'
,
methods:
changeWeather()
this.isHot = !this.isHot
,
)
vm.$watch('info',
handler(newVal,oldVal)
console.log('天气被修改了', newVal, oldVal);
)
</script>
immediate选项
默认情况下,组件在初次加载完毕后不会调用watch侦听器,如果想让watch侦听器立即被调用,则需要使用immediate选项,immediate的作用是控制侦听器是否自动触发一次,选项的默认值为:false
<div id="root">
<input type="text" v-model="name">
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue(
el:'#root',
data:
name:'admin'
,
watch:
//定义对象格式的侦听器
name:
handler(newVal,oldVal)
console.log(newVal, oldVal);
,
immediate:true
)
</script>
深度监视
如果watch侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用deep选项,开启深度监听,只要对象中任何一个属性变化了,都会触发“对象的侦听器”。
<div id="root">
<input type="text" v-model="info.name">
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue(
el:'#root',
data:
info:
name:'admin'
,
watch:
info:
handler(newVal)
console.log(newVal);
,
//开启深度监听
deep:true
)
</script>
如果想要侦听的对象是子属性的变化,则必须包裹一层单引号。
watch:
"info.name"(newVal)
console.log(newVal);
总结:
1)Vue中的watch默认不监测对象内部值的改变(一层)
2)配置deep:true可以监测对象内部值改变(多层)
3)Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
4)使用watch时根据数据的具体结构,决定是否采用深度监视
watch能开启异步任务,案例如下:
<div id="root">
<input type="text" v-model="firstname"><br>
<input type="text" v-model="lastname"><br>
全名:<span>fullname</span>
</div>
<script src="/vue/vue.js"></script>
<script>
const vm = new Vue(
el:"#root",
data:
firstname:'张',
lastname:'三',
fullname:'张-三'
,
//watch能开启异步任务
watch:
firstname(val)
setTimeout(()=>
this.fullname = val + '-' + this.lastname
,1000)
,
lastname(val)
this.fullname = this.firstname+'-'+val
)
</script>
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
隐性原则:
1.被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象
2.不被Vue所管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
VUE前进之路使用数据代理,计算属性与监视属性的妙用
1.数据代理
1.1什么是数据代理
通过一个对象代理对另一个对象中属性的操作(读/写)
1.Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:更加方便的操作data中的数据
3.基本原理:通过0bject . defineProperty( )把data对象中所有属性添加到vm上。为每一一个 添加到vm上的属性,都指定个getter/setter。在getter/setter内部去操作(读/写) data中对应的属性。简单来说就是把data的属性全部都复制给了_data了一份,可以让vm进行使用
1.2了解使用数据代理
Object.defineProperty方法(给对象添加属性方法的一个方法)这个方法会传入三个参数分别是 对象名,属性名,配置项
在这里我们可以看到,这个颜色稍微的优点变化(这里就是使用Object.defineProperty方法进行添加的,这里的age是不可以进行枚举的,即不参与遍历)
<script>
let person =
name:'大熊'
sex:'男',
Object.defineProperty(person,'address',
value:18
)
console.log(person);
</script>
这里可以使用Object.keys()进行验证一下(并没有age这个属性)(可以看到依然没有age)
当然也可以使用for… in进行遍历一下这个对象
如和才能让他可以被枚举呢?(这里就使用 enumerable 只要将它的值改为true即可)enumerable: true (是否可以被枚举)writable:true(是否可以修改属性)configurable: true(是否可以删除改属性)这四个基本配置项的内容(包括value)他们的默认值为false
<script>
let person =
name:'大熊',
sex:'女',
Object.defineProperty(person,'address',
value:18
)
for(k in person)
console.log(k);
console.log(Object.keys(person));
console.log(person);
</script>
那问题来了,如何进行对数据的读取和修改呢?这里用到了两个方法,get和set
当有人读取person的age属性时,get函 数(getter)就会被调用,且返回值就是age值
当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具值
<script>
let number = 19;
let person =
name: '大熊',
sex: '女',
Object.defineProperty(person, 'address',
get()
console.log('age属性已被读取');
return number;
,
set(value)
console.log('age属性已被修改');
number = value
)
</script>
2. 事件处理
1.使用v-on:xxx或@xxx绑定事件,其中xxx是事件名
2.事件的回调需要配置在methods对象中,最终会在vm上
3.methods中配置的函数,不可以使用箭头函数,否则this就不是vm了而是window
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象5.@click="demo"和@click="demo"效果一致,但后者可以传参
注:不要把事件回调方法data里,虽然可以实现相同的功能,但是这样会给增加一个数据代理,给一个方法添加数据代理是没有意义的
<div id="user">
<h1>name吃饭了吗?</h1>
<button v-on:click="showPage($event,18)">点击提示</button>
<!-- 第一个参数是event,所以下面的参数顺序要和这里一致 -->
</div>
<script>
let vm = new Vue(
el: '#user',
data:
name: '山鱼',
,
methods:
// 在这里配置各种事件回调
showPage(event, number)
alert('山鱼吃饭了!')
console.log(number);
)
</script>
2.1事件修饰符
1.prevent:阻止默认事件(常用)
2.stop: 阻止事件冒泡(常用)
3.once:事件只触发一次(常用)
4.capture: 使用事件的捕获模式
5.self: 只有event.target是当前操作的元素是才触发事件;
6.passive: 事件的默认行为立即执行,无需等待事件回调执行完毕;
<div id="user">
<h1>欢迎来到name的小屋</h1>
<!-- 1,阻止默认事件 -->
<a href="http://baidu.com" @click.prevent = "showInfo">点我不跳转</a>
<!-- 2,阻止事件冒泡 -->
<div class="one" @click = 'showInfo'>
<button @click.stop = 'showInfo'>点我</button>
</div>
<!-- 3,事件只触发一次 -->
<button @click.once = 'showInfo'>只能点一次</button>
</div>
<script>
const vm = new Vue(
el:'#user',
data:
name:'大熊',
,
methods:
showInfo(e)
alert('同学,慢走!')
)
</script>
2.2键盘事件
常用的按键别名
回车=> enter,删除=>delete(捕获“删除”和“退格”键),退出=> esc,空格=> space,上=>up,下=> down,左=> left,右=> right
特殊的按键别名
1.换行=> tab (特殊,必须配合keydown使用)
2.系统修饰键 ctrl,alt,shift,meta(meta就是win键也就是windows徽标)
注:
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
<div class="user">
<h1>欢迎加入uname</h1>
<!--.enter 就是按下回车触发事件,也成为按键别名-->
<input type="text" placeholder="按下回车提示输入" @keyup.enter = 'showInfo'>
<!--删除 del -->
<input type="text" placeholder="按下del提示输入" @keyup.delete = 'showInfo'>
<!-- 退出esc -->
<input type="text" placeholder="按下ESC提示输入" @keyup.esc = 'showInfo'>
<!-- 特殊按键别名 -->
<input type="text" placeholder="一同按下ctrl+‘其他按键’并释放提示输入" @keyup.ctrl = 'showInfo'>
<!-- 自定义别名 -->
<input type="text" placeholder="按下回车提示输入" @keyup.huiche = 'showInfo'>
</div>
<script>
// 也可以自定义按键别名
Vue.config.keyCodes.huiche = 13;
const vm = new Vue(
el:'.user',
data:
uname:'山鱼社区'
,
methods:
showInfo(e)
console.log(e.target.value);
)
</script>
3.计算属性
1.定义: 要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了objcet . defineproperty方法提供的getter和Isetter.
3. get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与jmethods 实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.注:
1.计算属性最终会出现在:vm上,直接读取使用即可。
2.如果i计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发发生变化
3.计算属性内不能够开启异步任务(如:定时器)
<body>
<!-- 容器 -->
<div class="user">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
姓名:<span>fullName</span>
</div>
<script>
const vm = new Vue(
el: '.user',
data:
firstName: '李',
lastName: '四'
,
// 计算属性
computed:
fullName:
// 当ful1Name被读取时,get就会被调用,且返回值就作为fullName的值,而且get有个缓存效果
// 这里的get在初次读取fullName时会被调用,在所依赖的数据进行改变时也会调用
// 这里所依赖的数据有俩分别是firstName和lastName
get()
return this.firstName +"-" +this.lastName
,
// 当fullName被修改时调用
set(value)
console.log('set被hi行');
const arr = value. split('-');
this.firstName = arr[0];
this.lastName = arr[1];
)
</script>
</body>
简写计算属性(前提是只用到get的时候可以简写)
4.侦听属性
监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作
2.监视的属性必须存在,I才能进行监视! !
3.监视的两种写法:
(1) . new Vue时传入watch配置
(2) .通过vm. $watch监视
<body>
<div class="user">
<h1>今天我很info</h1>
<button @click='changeMood'>点击切换心情</button>
</div>
<script>
new Vue(
el: '.user',
data:
mood: true
,
computed:
info()
return this.mood ? '开心' : '不开心'
,
,
methods:
changeMood()
this.mood = !this.mood
,
watch:
// 被监视的是谁
mood:
immediate: true,// 初始化时 让handler调用一次
// handler有俩参数分别是修改前的值和修改后的值
handler(newValue, oldValue)
console.log('mood被修改了', newValue, oldValue);
,
// 这个监视属性也可以监视计算属性
info:
immediate: true,// 初识化时 让handler调用一次
// handler有俩参数分别是修改前的值和修改后的值
handler(newValue, oldValue)
console.log('info被修改了', newValue, oldValue);
,
)
// 也可以用vm.$watch进行监视 =》vm.$watch(监视对象,如何监视)
vm.$watch('mood',
immediate: true,// 初识化时 让handler调用一次
// handler有俩参数分别是修改前的值和修改后的值
handler(newValue, oldValue)
console.log('info被修改了', newValue, oldValue);
)
</script>
</body>
4.1深度监视
深度监视
①Vue中的watch默认不监测对象内部值的改变
②配置deep:true可以监测对象内部值改变
备注:
①Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
②使用watch时根据数据的具体结构,决定是否采用深度监视
4.2监视属性简写
简写(但是不能配置immediate:true,deep:true)
watch:
// 完整写法
// mood:
// deep:true
// handler(newValue, oldValue)
// console.log("mood被修改", newValue, oldValue);
//
//
// 简写
mood(newValue, oldValue)
console.log('mood被修改', newValue, oldValue);
)
// 正常写法
vm.$watch('mood',
immediate:true,
deep:true,
handler(newValue, oldValue)
console.log('mood被修改', newValue, oldValue);
)
// 简写
vm.$watch('mood',function(newValue, oldValue)
console.log('mood被修改', newValue, oldValue);
)
4.3computed & watch之间的区别
1.computed能完成的功能,watch 都可以完成。
2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步操作。
3.两个重要的小原则:
①所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
②所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
5.写在最后
大家好我是大熊🐻
一个学前端的旅行者也是一个前进的创作者,奋进再这篇土地,希望能和您相遇
✍善于利用零星时间的人,才会做出更大的成绩来。——华罗庚
以上是关于Vue--》计算属性与监视(侦听)属性的使用的主要内容,如果未能解决你的问题,请参考以下文章