计算属性:
1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
<div id="app">
<p>姓:<input type="text" v-model="firstName"></p>
<p>名:<input type="text" v-model="lastName"></p>
<p>地址:<input type="text" v-model="address"></p>
<!-- 计算属性的优势是:有缓存,当页面数据发生变化时,所有的方法都要重新执行,
当计算属性用到的数据发生变化时,计算属性才会重新执行。 -->
<p>方法返回姓名:<input type="text" :value="fullName2()"></p>
<p>计算属性返回姓名:<input type="text" :value="fullName"></p>
<hr>
<ul>
<li v-for="(item,index) in goodses" :key="index">{{item.name}}--{{item.price}}元--
<button @click="delGoods(index)">删除</button>
</li>
<li>总价是--{{totalPrice}}元</li>
</ul>
</div>
new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '杰',
address: '成都',
goodses: [{
name: '洗衣机',
price: 2999,
}, {
name: '电视机',
price: 3999,
}, {
name: '油烟机',
price: 1999,
}]
},
methods: {
fullName2() {
console.log('我是方法');
return this.firstName + '.' + this.lastName
},
delGoods(index){
this.goodses.splice(index,1)
}
/* totalPrice(){
console.log('我在计算总价格');
let sum=0
this.goodses.forEach(r=>{
sum+=r.price
})
return sum
} */
},
//用于定义计算属性
computed: {
totalPrice() {
console.log('我在计算总价格');
let sum = 0
this.goodses.forEach(r => {
sum += r.price
})
return sum
},
// 在这里面定义的是方法,计算属性默认情况下只能读,不能改
fullName() {
console.log('我是计算属性');
return this.firstName + '.' + this.lastName
}
// 定义完整结构的计算属性
/* fullName:{
//get方法,用于返回计算属性的值
get(){
return this.firstName+'.'+this.lastName
},
//set方法,用于修改计算属性的值
set(val){
let arr = val.split('.')
this.firstName = arr[0]
this.lastName = arr[1]
}
} */
}
})
监视属性watch:
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
new Vue({
el:'#root',
data:{
isHot:true,
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
immediate:true, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时。
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
}
}
})
vm.$watch('isHot',{
immediate:true, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时。
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
})
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
<hr/>
<h3>a的值是:{{numbers.a}}</h3>
<button @click="numbers.a++">点我让a+1</button>
<h3>b的值是:{{numbers.b}}</h3>
<button @click="numbers.b++">点我让b+1</button>
<button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>
{{numbers.c.d.e}}
</div>
new Vue({
el:'#root',
data:{
isHot:true,
numbers:{
a:1,
b:1,
c:{
d:{
e:100
}
}
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot:{
// immediate:true, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时。
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
},
//监视多级结构中某个属性的变化
/* 'numbers.a':{
handler(){
console.log('a被改变了')
}
} */
//监视多级结构中所有属性的变化
numbers:{
deep:true,
handler(){
console.log('numbers改变了')
}
}
}
})
过滤器:
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1.注册过滤器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据, 是产生新的对应的数据
//局部过滤器
<div id="app">
<p>商品名称:{{goods.name}}</p>
<p>商品价格:{{toFixed2(goods.price)}}</p>
<p>商品价格:{{myGoods.price}}</p>
<!-- 通过管道符| 调用过滤器,其实就是调用那个方法,将值传进去,再返回新的值 -->
<p>商品价格(人民币):{{goods.price | toFixed2 | toRMB}}
<input type="text" :value="goods.price | toFixed2">
</p>
<!-- 过滤器可以链式调用,就是之前已经过滤完成的结果,继续传给下一个过滤器,注意顺序 -->
<p>商品价格(美元):{{goods.price | toFixed2 | toUS}}</p>
</div>
new Vue({
el:'#app',
data:{
goods:{
name:'小米手机',
price:1999.22222
}
},
// 定义方法,过滤商品的价格
methods: {
toFixed2(val){
return val.toFixed(2)
}
},
// 定义一个计算属性
computed:{
myGoods(){
let goods = {
name:this.goods.name,
price:this.goods.price.toFixed(2)
}
return goods
}
},
// 定义过滤器
filters:{
// 过滤在模板中通过管道符 | 的方式来调用
toFixed2(val){
return val.toFixed(2)
},
//返回人民币数据
toRMB(val){
return '¥'+ val
},
//返回美元数据
toUS(val){
return '$'+ (val/6.5).toFixed(2)
}
}
})
//全局过滤器
<div id="app2">
<p>商品名称:{{goods.name}}</p>
<p>商品价格:{{goods.price | toFixed2}}</p>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
// 定义全局过滤器
// 如果局部过滤器和全局过滤器冲突了,优先级更高的是局部过滤器
Vue.filter("toFixed2", function (val) {
return val.toFixed(2);
});
面试相关考点:
1.计算属性与 watch 区别
Computed watch 区别就是 computed 的缓存功能,当无关数据数
据改变时,不会重新计算,直接使用缓存中的值。计算属性是用来声明
式的描述一个值依赖了其他的值,当所依赖的值后者变量发生变化时,
计算属性也跟着改变,
Watch 监听的是在 data 中定义的变量,当该变量变化时,会触发 watch
中的方法
2.什么是计算属性
计算属性是用来声明式的描述一个值依赖了其他的值,当它依赖的这个
值发生改变时,就更新 DOM
当在模板中把数据绑定到一个计算属性上时,vue 会在它依赖的任何值导
致该计算属性改变时更新 DOM
每个计算属性都包括一个 getter 和 setter,读取时触发 getter,修改时
触发 setter