vue学习简记(一)
监视属性
在vue中配置watch实现监视,当被监视的属性变化时, 回调函数自动调用, 进行相关操作
- 监视属性的基本写法
watch: {
//正常写法
isHot: {
// immediate:true, //初始化时让handler调用一下
// deep:true,//深度监视
handler(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue)
}
},
其中使用deep:true实现深度监视,Vue中的watch默认不监测对象内部值的改变(一层),深度监视也就是可以监测对象内部值改变(多层)
data: {
numbers: {
a: 1,
b: 1,
c: {
d: {
e: 100
}
}
},
多层也就是当numbers中的第二层,a,b,c,或者更深的d,e等改变时是监视不到的
注意: Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
- 监视属性的简写方式(当不需要配置属性时可以采用)
watch: {
//简写
isHot(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
}
}
- 当需要在外部配置监视属性时候,可以写成
vm.$watch('isHot',function(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue,this)
})
注意此处函数不能写成箭头函数,因为箭头函数的this指向会变为window
监视属性和计算属性的区别
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定 能完成,例如:watch可以进行异步操作(比如说有延迟执行的需求等)。
绑定样式的写法
- class样式
写法:class=“xxx” xxx可以是字符串、对象、数组。
- 字符串写法适用于:类名不确定,要动态获取。
- 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
- 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
- style样式
- :style="{fontSize: xxx}"其中xxx是动态值。
- :style="[a,b]"其中a、b是样式对象。
条件渲染
- v-if(将元素从dom树中直接删除)
写法:
(1).v-if=“表达式”
(2).v-else-if=“表达式”
(3).v-else=“表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
用法例如以下所示:
<div v-if="n === 1">火锅</div>
<div v-else-if="n === 2">烧烤</div>
<div v-else-if="n === 3">烤肉</div>
<div v-else>看见啥吃啥</div>
<template> ... </template>
template 只能和v-if配合使用。可以起到包裹的作用,在页面渲染时会将此标签脱掉。
2. v-show(相当于display:none)
写法:v-show=“表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
Vue中的数据监视
- vue会监视data中所有层次的数据
- 如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据
- 对象中后追加的属性,Vue默认不做响应式处理
- 如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value) 或
vm.$set(target,propertyName/index,value)
- 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。 - 在Vue修改数组中的某个元素一定要用如下方法:
-
使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()]
-
Vue.set() 或 vm.$set()
为什么数组要调用这些方法呢?
因为数组中的元素是没有绑定get和set方法的,可以理解为vue对这些方法进行了劫持并重定义,只有调用这些方法对数据进行增删改查等操作,vue才能监测到。如果不调用这些方法操作数组,则vue监测不到数组的变化,也就无法反馈到页面上了。
如下可见hobby数组并没有绑定get和set方法:
同理friends数组也没有绑定,get和set方法在对象中被绑定
注意Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!
<div id="root">
<h1>自身信息</h1>
<button @click="person.age++">年龄+1岁</button> <br/>
<button @click="addSex">添加性别属性,默认值:女</button> <br/>
<button @click="person.sex = '未知' ">修改性别</button> <br/>
<button @click="addFriend">在列表首位添加一个朋友</button> <br/>
<button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br/>
<button @click="addHobby">添加一个爱好</button> <br/>
<button @click="updateHobby">修改第一个爱好为:看书</button> <br/>
<button @click="removeSleep">过滤掉爱好中的睡觉</button> <br/>
<h3>姓名:{{person.name}}</h3>
<h3 v-if="person.sex">性别:{{person.sex}}</h3>
<h3>年龄:{{person.age}}</h3>
<h3>爱好:</h3>
<ul>
<li v-for="(h,index) in person.hobby">
{{h}}
</li>
</ul>
<h3>朋友:</h3>
<ul>
<li v-for="(f,index) in person.friends">
{{f.name}}--{{f.age}}
</li>
</ul>
</div>
var vm = new Vue({
el: '#root',
data: {
person: {
name: '小琪',
age: 18,
hobby: ['吃饭', '睡觉', '运动', '学习'],
friends: [{
name: '王五',
age: 20
}, {
name: '陆六',
age: 24
}]
}
},
methods: {
addSex() {
Vue.set(this.person, 'sex', '女')
// this.$set(this.person, 'sex', '女')
},
addFriend() {
this.person.friends.unshift({
name: '王二',
age: 30
})
},
updateFirstFriendName() {
this.person.friends[0].name = '张三'
},
addHobby() {
this.person.hobby.push('开车')
},
updateHobby() {
this.person.hobby.splice(0, 1, '看书')
},
//filter(),concat(),slice()不会改变数组,而返回一个新数组。使用这些非变更方法时,可以使用新数组替换旧数组
removeSleep() {
this.person.hobby = this.person.hobby.filter((h) => {
return h != '睡觉'
})
}
},
})