vue计算属性computed
computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是说多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择
计算属性允许我们对指定的视图,复杂的值计算。这些值将绑定到依赖项值,只在需要时更新。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 第一步 引入vue.js -->
<script src="../vue_js/Vue.js"></script>
</head>
<body>
<!-- 第二步 创建容器 -->
<div id="app">
<!-- 使用胡须表达式获取所有商品的总价值 -->
<h1>胡须表达式所有商品总价值:{{goodsNum * goodsPrice}}</h1>
<!-- 使用方法获取所有商品的总价值 -->
<h1>方法所有商品总价值:{{methodTotal()}}</h1>
<!-- 使用计算属性获取所有商品的总价值 -->
<h1>计算属性所有商品总价值:{{computedTotal}}</h1>
<!-- 胡须表达式 和 方法对比,一般复杂的计算逻辑,都要交给js去处理,不要在表达式里面处理
方法 和 计算属性 ,计算属性的数据有依赖缓存,只有数据发生变化时,才会从新计算,不然直接取缓存数据
我们每次进入这个页面时,methodTotal()都会被加载从新执行一次,而计算属性computedTotal,只会在第一次进入时
执行一次,然后把结果放入缓存,只要数据不发生变化,就不会再次被执行。
为什么计算属性里面我们写的computedTotal也是一个方法,但是在胡须表达式内使用不加(),而在methods里面的方法
必须添加小(),因为计算属性他会把在他内部写的方法名看作一个属性,每次返回的时候会给这个属性赋值,我们直接取就可以了
-->
</div>
<script>
// 第三步 vue实例对象
var vm = new Vue({
//挂载dom
el: "#app",
//准备数据
data: {
//商品数量
goodsNum: 10,
//商品价格
goodsPrice: 100
},
//方法
methods: {
methodTotal() {
return this.goodsNum * this.goodsPrice;
}
},
//计算属性
computed: {
computedTotal() {
return this.goodsNum * this.goodsPrice;
}
}
})
</script>
</body>
</html>
vue过滤器filters
过滤器就是经过过滤后数据发生变化,也就是说i在数据输出之前对数据进行过滤,vue.js 允许你自定义过滤器,过滤器可以用在两个地方:胡须表达式和 v-bind 指令绑定的表达式
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 第一步 引入vue.js -->
<script src="../vue_js/Vue.js"></script>
</head>
<body>
<!-- 第二步 创建容器 -->
<div id="app">
<!-- 胡须表达式 -->
<h1>胡须表达式msg:{{msg}}</h1>
<!-- 使用过滤器-->
<h1>在胡须表达式使用过滤器msg:{{msg | myFilters}}</h1>
<!-- 在v-bind绑定的表达式内使用过滤器 -->
<h1 v-bind:model="msg|myFilters">
</h1>
<input type="text" v-bind:value="msg|myFilters" />
</div>
<script>
// 第三步 vue实例对象
var vm = new Vue({
//挂载dom
el: "#app ",
//准备数据
data: {
msg: "单车 "
},
//方法
methods: {
},
//计算属性
computed: {
},
filters: {
myFilters(msg) {
//搏一搏,单车变摩托
msg = "摩托 ";
return msg;
}
}
})
</script>
</body>
</html>
显示效果
vue 侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
侦听器 String Number Boole类型的数据
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 第一步 引入vue.js -->
<script src="../vue_js/Vue.js"></script>
</head>
<body>
<!-- 第二步 创建容器 -->
<div id="app">
姓名:
<input type="text" v-model="name" /> <br/> 年龄:
<input type="number" v-model="age" /> <br/> 性别:
<input type="radio" v-model="sex" value=true />男 <input value=false type="radio" v-model="sex" />女<br/>年级:
<select v-model=" grade ">
<option value="">请选择</option>
<option value="一年级">一年级</option>
<option value="二年级">二年级</option>
<option value="三年级">三年级</option>
<option value="四年级">四年级</option>
<option value="五年级">五年级</option>
</select>
</div>
<script>
// 第三步 vue实例对象
var vm = new Vue({
//挂载dom
el: "#app ",
//准备数据
data: {
name: "尼古拉斯凯奇",
age: 18,
sex: true,
grade: "一年级"
},
//方法
methods: {
},
//计算属性
computed: {
},
//过滤器
filters: {
},
//侦听器
watch: {
//监听姓名发生变化
name(newValue, oldValue) {
console.log("newValue==============" + newValue)
console.log("oldValue==============" + oldValue)
},
//监听年龄发生变化
age(newValue, oldValue) {
console.log("newValue==============" + newValue)
console.log("oldValue==============" + oldValue)
},
//监听性别发生变化
sex(newValue, oldValue) {
console.log("newValue==============" + newValue)
console.log("oldValue==============" + oldValue)
},
//监听年级发生变化
grade(newValue, oldValue) {
console.log("newValue==============" + newValue)
console.log("oldValue==============" + oldValue)
}
}
})
</script>
</body>
</html>
数据改变前的页面
数据改变后的页面及数据打印变化
侦听器 普通数组 Array
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 第一步 引入vue.js -->
<script src="../vue_js/Vue.js"></script>
</head>
<body>
<!-- 第二步 创建容器 -->
<div id="app">
爱好:<br>
<label v-for="item in hobbyArray">
<input name="hobby" type="checkbox"
:value="item" v-model="myHobbyArray"/>{{item}}</label>
</div>
<script>
// 第三步 vue实例对象
var vm = new Vue({
//挂载dom
el: "#app ",
//准备数据
data: {
hobbyArray: ["吃饭", "睡觉", "打豆豆", "篮球", "足球", "乒乓球"],
myHobbyArray: []
},
//方法
methods: {
},
//计算属性
computed: {
},
//过滤器
filters: {
},
//侦听器
watch: {
//监听数组的变化
myHobbyArray(newValue, oldValue) {
console.log("newValue==============" + newValue)
console.log("oldValue==============" + oldValue)
},
}
})
</script>
</body>
</html>
为变化时的效果图
发生改变的效果图和变化打印的数据
侦听器 对象
对于对象属性的侦听,是不能侦听到对象属性值的变化的,就要用到侦听器里面的对象deep:其值是true或false;确认是否深入监听,默认是false,当我们把他写成true时,就可以监听到对象里面的属性的变化了。当使用deep时,我们还要用到另外一个属性handler:其值是一个回调函数。即监听到变化时应该执行的函数
代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 第一步 引入vue.js -->
<script src="../vue_js/Vue.js"></script>
</head>
<body>
<!-- 第二步 创建容器 -->
<div id="app">
编码:
<input type="text" v-model="user.id" /> <br/> 姓名:
<input type="text" v-model="user.name" /> <br/> 年龄:
<input type="number" v-model="user.age" /> <br/> 性别:
<input type="radio" v-model="user.sex" value="男" />男 <input value="女" type="radio" v-model="user.sex" />女<br/> 爱好:
<br>
<label v-for="item in hobbyArray">
<input name="hobby" type="checkbox"
:value="item" v-model="user.myHobbyArray"/>{{item}}</label>
</div>
<script>
// 第三步 vue实例对象
var vm = new Vue({
//挂载dom
el: "#app ",
//准备数据
data: {
user: {
id: "100001",
name: "小王吧",
age: 16,
sex: "男",
myHobbyArray: ["吃饭", "睡觉", "打豆豆"]
},
hobbyArray: ["吃饭", "睡觉", "打豆豆", "篮球", "足球", "乒乓球"]
},
//方法
methods: {
},
//计算属性
computed: {
},
//过滤器
filters: {
},
//侦听器
watch: {
//监听对象的变化
user: {
// 其值是一个回调函数。 即监听到变化时应该执行的函数
handler(newValue, oldValue) {
console.log("newValue==============" + JSON.stringify(newValue));
console.log("oldValue==============" + JSON.stringify(oldValue));
},
//其值是true或false;确认是否深入监听。
deep: true
}
}
})
</script>
</body>
</html>
改变前的页面
改变后的数据变化和数据打印效果
这种情况下你会发现,打印出来的改变前的值和改变后的值是一样的,并且都显示的是改变后的值,这就是deep的作用,进行了深拷贝。
那么这种情况下我们想要知道哪个属性发生了变化怎么处理呢?
第一种方式 要侦听器和计算属性结合使用了。
computed的代码:
userName() {
return this.user.name
}
watch的代码
//监听用户的名字的变化
userName: {
// 其值是一个回调函数。 即监听到变化时应该执行的函数
handler(newValue, oldValue) {
console.log("newValue==============" + JSON.stringify(newValue));
console.log("oldValue==============" + JSON.stringify(oldValue));
},
//其值是true或false;确认是否深入监听。
deep: true
}
第二种 直接转换成字符串
'user.name': {
// 其值是一个回调函数。 即监听到变化时应该执行的函数
handler(newValue, oldValue) {
console.log("对象属性转字符串形似获取名字newValue==============" + JSON.stringify(newValue));
console.log("对象属性转字符串形似获取名字oldValue==============" + JSON.stringify(oldValue));
},
//其值是true或false;确认是否深入监听。
deep: true
}
数据获取效果
watch监听数据时,有三个选项,handler,deep,immediate
第一个:handler 其值是一个回调函数。即监听到变化时应该执行的函数
第二个:deep 其值是true或false;确认是否深入监听,默认是false,当我们把他写成true时,就可以监听到对象里面的属性的变化了
第三个:immediate
该值默认是false,在进入页面时,第一次绑定值,不会立刻执行监听,只有数据发生改变才会执行handler中的操作,我们来输出看一下
immediate为false:
总结
数组(一维、多维)的变化不需要通过深度监听,对象数组中对象的属性变化则需要deep深度监听。