1.更新时遇到的一个问题
<div id="root">
<button @click="updateMei">更新第一列</button>
<h1>人员列表</h1>
<ul>
<!-- (p,index) in persons -- :key="index" -->
<li v-for="p of persons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
keyword: '',
persons: [
{ id: '001', name: '马冬梅', age: '18', sex: '女' },
{ id: '002', name: '周冬雨', age: '19', sex: '女' },
{ id: '003', name: '周杰伦', age: '20', sex: '男' },
{ id: '004', name: '温兆伦', age: '22', sex: '男' }
]
},
methods: {
updateMei() {
/*this.persons[0].name = '马老师'//奏效
this.persons[0].age = '50'//奏效
this.persons[0].sex = '男'//奏效*/
this.persons[0] = { id: '001', name: '马老师', age: '50', sex: '男' }
}
},
})
</script>
用this.persons[0].name = '马老师'//奏效
this.persons[0].age = '50'//奏效
this.persons[0].sex = '男'//奏效
可以实现更新
用这个 this.persons[0] = { id: '001', name: '马老师', age: '50', sex: '男' 则不能更新
2.Vue检测数据改变的原理
<!-- 准备一个容器 -->
<div id="root">
<h1>名字:{{name}}</h1>
<h1>地址:{{address}}</h1>
</div>
<script>
Vue.config.productionTip = false //设置为 false 以阻止 vue 在启动时生成生产提示。
//创建Vue实例
const vm = new Vue({
el: '#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
data: {//data用于储存数据,数据供el指定的容器使用,值我们先暂时写成一个对象
name: 'world',
address: '地球',
a: {
b: 'nihao',
c: {
d: '第四层'
}
},
e: [
{
f: '数据里的'
},
{
g: {
h: '数据里再深一层'
}
}
]
}
})
</script>
3.模拟一个数据检测
<script>
let data = {
name: 'world',
a: {
b: 'nihao'
}
}
// let tmp = 'world'
// setInterval(() => {
// if (data.name !== tmp) {
// tmp = data.name
// console.log('name被改了')
// }
// }, (100))
// Object.defineProperty(data, 'name', {
// get() {
// return data.name
// },
// set(val) {
// data.name = val
// }
// })
//创建一个监视实例对象,用于监视data中属性的变化
const obs = new Observer(data)
console.log(obs)
//准备一个vm实例对象
let vm = {}
vm._data = data = obs
function Observer(obj) {
//汇总对象中所有的属性形成一个数组
const keys = Object.keys(obj)
//遍历
keys.forEach((k) => {
Object.defineProperty(this, k, {
get() {
return obj[k]
},
set(val) {
console.log(`$(k)被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了 `)
obj[k] = val
}
})
})
}
</script>
4.Vue.set的使用
<!-- 准备一个容器 -->
<div id="root">
<h1>名字:{{name}}</h1>
<h1>地址:{{address}}</h1>
<h2>学生姓名:{{students.name}}</h2>
<button @click="addsex">添加性别</button>
<h2 v-show="students.sex">学生性别:{{students.sex}}</h2>
<h2>学生真实年龄:{{students.age.realAge}};对外年龄:{{students.age.sAge}}</h2>
<ul>学生朋友:
<li v-for="f of friends">{{f.name}}-{{f.age}}</li>
</ul>
</div>
<script>
Vue.config.productionTip = false //设置为 false 以阻止 vue 在启动时生成生产提示。
//创建Vue实例
const vm = new Vue({
el: '#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
data: {//data用于储存数据,数据供el指定的容器使用,值我们先暂时写成一个对象
name: 'world',
address: '地球',
students: {
name: 'Tom',
// sex: '男',
age: {
realAge: 30,
sAge: 25
}
},
friends: [
{
name: 'Make',
age: 31
},
{
name: 'Mary',
age: 28,
}
]
},
methods: {
addsex() {
// Vue.set(this.students, 'sex', '男')
this.$set(this.students, 'sex', '男')
}
},
})
</script>
5.Vue检测数据改变的原理-数组
<!-- 准备一个容器 -->
<div id="root">
<h1>名字:{{name}}</h1>
<h1>地址:{{address}}</h1>
<h2>学生姓名:{{students.name}}</h2>
<button @click="addsex">添加性别</button>
<h2 v-show="students.sex">学生性别:{{students.sex}}</h2>
<h2>学生真实年龄:{{students.age.realAge}};对外年龄:{{students.age.sAge}}</h2>
<ul>学生爱好:
<li v-for="(h,index) in hobby" :key="index">{{h}}</li>
</ul>
<ul>学生朋友:
<li v-for="(f,index) in friends" :key="index">{{f.name}}-{{f.age}}</li>
</ul>
</div>
<script>
Vue.config.productionTip = false //设置为 false 以阻止 vue 在启动时生成生产提示。
//创建Vue实例
const vm = new Vue({
el: '#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
data: {//data用于储存数据,数据供el指定的容器使用,值我们先暂时写成一个对象
name: 'world',
address: '地球',
students: {
name: 'Tom',
// sex: '男',
age: {
realAge: 30,
sAge: 25
}
},
hobby: ['抽烟', '喝酒', '烫头'],
friends: [
{
name: 'Make',
age: 31
},
{
name: 'Mary',
age: 28,
}
]
},
methods: {
addsex() {
// Vue.set(this.students, 'sex', '男')
this.$set(this.students, 'sex', '男')
}
},
})
</script>
因此可以解决《1.更新时遇到的一个问题》
点击按钮后也会使马冬梅变成马老师
6.总结Vue数据监控
<!-- 准备一个容器 -->
<div id="root">
<h1>学生信息</h1>
<button @click="students.age++">年龄+1岁</button><br>
<button @click="addSex">添加性别属性,默认值:男</button><br>
<button @click=" students.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="removeSmoke">将爱好过滤掉抽烟</button><br>
<h2>学生姓名:{{students.name}}</h2>
<h2 v-show="students.sex">学生性别:{{students.sex}}</h2>
<h2>学生真实年龄:{{students.age}}</h2>
<ul>学生爱好:
<li v-for="(h,index) in students.hobby" :key="index">{{h}}</li>
</ul>
<ul>学生朋友:
<li v-for="(f,index) in students.friends" :key="index">{{f.name}}-{{f.age}}</li>
</ul>
</div>
<script>
Vue.config.productionTip = false //设置为 false 以阻止 vue 在启动时生成生产提示。
//创建Vue实例
const vm = new Vue({
el: '#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
data: {//data用于储存数据,数据供el指定的容器使用,值我们先暂时写成一个对象
students: {
name: 'Tom',
// sex: '男',
age: 18,
hobby: ['抽烟', '喝酒', '烫头'],
friends: [
{
name: 'Make',
age: 20
},
{
name: 'Mary',
age: 19,
}
]
},
},
methods: {
addSex() {
// Vue.set(this.students, 'sex', '男')
this.$set(this.students, 'sex', '男')
},
addFriend() {
this.students.friends.unshift({ name: 'jack', age: 3 })
},
updateFirstFriendName() {
this.students.friends[0].name = '张三'
// this.students.friends[0].age = 90
},
addHobby() {
this.students.hobby.push('学习')
},
updateHobby() {
// this.students.hobby.splice(0, 1, '开车')
// Vue.set(this.students.hobby, 0, '开车')
this.$set(this.students.hobby, 0, '开车')
},
removeSmoke() {
this.students.hobby = this.students.hobby.filter((h) => {
return h !== '抽烟'
})
}
},
})
</script>
总结