1. 监听(watch)
: 监听一个属性的变化
-
监事属性
watch
:- 当监视的属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进入监视
- 监视的两种写法:
new Vue
时传入watch
配置- 通过
vm.$watch()
监视
immediate
初始化时让handler
调用一下
-
深度监视:
Vue
中的watch
默认不监视对象内部值的变化(只监视一层)- 配置
deep:true
可以监视对象内部值变化(多层)
-
备注:
Vue
自身可以监视对象内部值得变化,但Vue提供的watch默认不可以- 使用
watch
时,根据数据的具体结构,决定是否采用深度监听 - 简写:当确定不使用
immediate
和deep
属性时可以简写
一、监听1. const vm = new Vue({el: "#app",watch:{immediate: true, // 初始化时让handler调用一下deep: true, // 深度监听handler(newValue, oldValue){console.log(newValue, oldValue)}}})2. vm.$watch('isSHow',{immediate: true, // 初始化时让handler调用一下deep: true, // 深度监听handler(newValue, oldValue){console.log(newValue, oldValue)}})
二、简写1. const vm = new Vue({el: "#app",watch:{isShow(newValue, oldValue){console.log(newValue, oldValue)}}})2. vm.$watch('isSHow', function(newValue, oldValue){console.log(newValue, oldValue)})
-
计算属性
(computed)
、方法methods
、监听(watch)
的区别?
computed、watch、methods
专人干专事- 计算属性
computed
:- 目的是得到一个计算结果,必须要有return,一个状态值受多个状态值影响。
- 有缓存,当依赖状态值变化是,才会重新计算。
- 不能异步
- 本身不支持传参,可以使用闭包
- 事件
methods
:- 绑定的事件处理,非必须
return
- 没有缓存
- 绑定的事件处理,非必须
- 监听
watch
:- 一个状态的改变 影响多条数据,没有
return
- 没有缓存
- 可以异步
- 不传参
- 一个状态的改变 影响多条数据,没有
- 计算属性
2. class和style
绑定
class
样式 写法::class = "xxx"
,xxx
可以是字符串、对象、数组- 字符串写法适用于:类名不确定,要动态获取
- 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
- 数组写法适用于:要绑定多个样式,个数确定,名字也确定
style
样式
:style = "{fontSize: xxx}" 其中xx是动态的
:style = "[a, b]" 其中a, b是样式对象
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
<style>/* #region */.red{color: red;}.blue{color: blue;}.green{color: green}.yellow{color: yellow}/* #endregion */.bold{font-weight: bold;}.size{font-size: larger;}
</style>
</head>
<body>
<div id="app"><!-- 1. 绑定字符串 --><!-- 1.1.1 固定切换class名称 --><p :class="name">这是一个动态class</p><button @click="changClass">点击单次切换class名</button><br><!-- 1.1.2 随机切换class名称 --><!-- class 和:class 可以绑定多个class名称 --><p class="bold" :class="name">这是一个动态class</p><button @click="changClass2">点击数组切换class名</button><br><!-- 1.1.3 三元表达式表达式切换class名称 --><p :class="isName ? 'red' : 'blue'">这是一个动态class</p><button @click="isName = !isName">表达式切换class名</button><hr><!-- 2. 绑定对象 --><!-- <p :class="{bold: true, size: false}">这是一个对象绑定的class类名</p> --><p :class="objClass">这是一个对象绑定的class类名</p><button @click="objClassChange">表达式切换class名</button><hr><!-- 3. 绑定数组 --><!-- <p :class="['blue', 'bold', 'size']">这是一个对象绑定的class类名</p> --><p :class="arrClass">这是一个对象绑定的class类名</p><button @click="arrClassChange">表达式切换class名</button></div>
<script>const vm = new Vue({el: '#app',data: {name: 'red',isName: true,arr:['red', 'blue', 'green'],// 对象class名称objClass:{red: true,bold: true},// 数组class名称arrClass:[ 'blue', 'bold', 'size']},methods: {// #region 字符串绑定changClass(){this.name = 'blue'},changClass2(){const a = Math.floor(Math.random() * 3)console.log(this.arr[a]);this.name = this.arr[a]},// #endregionobjClassChange(){// this.objClass.size = true// 解决方法 $set方法// this.$set(this.objClass, 'size', true)Vue.set(this.objClass, 'size', true)},arrClassChange(){// this.arrClass.splice(0, 1, 'yellow')// 存在问题?为何vm中的arrClass值改变了,页面却没有渲染 => Vue内部监视原理// this.arrClass[0] = 'yellow'// 解决方法// this.$set(this.arrClass, 0, 'yellow')this.$set(this.arrClass, 0, 'yellow')}},})
</script></body>
</html>
3. set
方法
Vue
会监视data
中所有层次的数据。- 如何监视对象的数据? 通过
setter
实现监视,且要在new Vue
时就传入要监测的内容- 对象中后追加的属性,
Vue
默认不做响应式处理 - 如需要给后添加的属性做响应式,使用如下
API
:
- 对象中后追加的属性,
Vue.set(target, propertyName/index, value)
vm.$set(target, propertyName/index, value)
- 如何监视数组中的数据? 通过包裹数组更新元素的方法实现,本质就是做两件事
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进而更新页面
- 在Vue修改数组中的某个元素一定要用如下方案:
- 使用这些API:
push(), pop(), shift(), unshift(), sort(), reverse(), splice()
- 使用这些API:
Vue.set()
或者vm.$set()
- 特别注意:Vue.set()和vm.$set()不能给vm或者vm的根数据对象添加属性!!
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">{{ obj }}<button @click="changeObj">点击改变obj值</button><hr>{{ arr }}<button @click="changeArr">点击改变arr值</button><hr>{{ arr2 }}<span v-once>{{ arr2 }}</span><button @click="changeArr2">点击改变arr顺序sort方法</button><hr>{{ arr3 }}<button @click="changeArr3">点击翻转arr</button>
</div>
<script>
const vm = new Vue({el: '#app',data:{obj:{name: '小明'},arr:['小亮', 10],arr2:[ 10, 40, 5, 30],arr3:[ 1, 2, 3, 4]},methods: {changeObj(){// this.obj.banji = 'xx班级'// 解决方法// this.$set(this.obj, 'banji', 'xx班级')Vue.set(this.obj, 'banji', 'xx班级')},changeArr(){// this.arr[0] = '小白'// 解决方法一: set// this.$set(this.arr, 2, 'xx班级')// Vue.set(this.arr, 2, 'xx班级')// this.arr[2] = '小白'// 解决方法二:内置函数// 1. 数组后添加值// this.arr.push('小白')// 2. 数组后删除值// this.arr.pop()// 3. 从头往后删除数组// this.arr.shift()// 4. 数组前面加值// this.arr.unshift('小小')},// 数组排序changeArr2(){// 5. sort()// 正序this.arr2.sort((a,b) =>{console.log('--');console.log(a, b);return a-b})// this.arr2.sort((a,b) =>{// return b - a// })},// 翻转数组changeArr3(){// this.arr3.reverse()// this.arr3.splice(1, 2, 'a', 'b', 'v')// 注意: 禁止给vm或者vm的跟数据对象添加属性// console.log(vm._data)// this.$set(vm._data, 'name', 'ssss')// this.$set(vm, 'name', 'ssss')}},
})
</script>
</body>
</html>