理解new Vue({options.data})
样例
const myData = {n:0}
const vm = new Vue({
data:myData
})
如上例,我们将myData传给vm,{n:0}立马变成了{n:(…)}。
此时,通过Obect.defineProperty会让vm成为myData的代理``proxy;并且会让vm对myData的所有属性进行监控,可以对属性进行读写,进而就可以调用render进行渲染。
代理(设计模式)
对样例中myData对象的属性读写,对myData对象的属性读写,全权由另一个对象vm负责。那么vm就是myData的代理(中介就是房东租房的代理)。比如用vm.n代替操作myData.n
Object.defineProperty
- 可以给对象添加属性
value - 可以给对象添加
getter/setter getter/setter用于对属性的读写进行监控
Object.defineProperty
let data1 = {}
Object.defineProperty(data1, 'n', { //给data1创建一个虚拟属性n,属性值为0
value: 0
})
console.log(`需求一:${data1.n}`)
getter
let obj1 = {
姓: "张",
名: "小明",
姓名() {
return this.姓 + this.名;
},
age: 18
};
console.log("需求一:" + obj1.姓名());
let obj2 = {
姓: "张",
名: "小明",
get 姓名() { //getter
return this.姓 + this.名;
},
age: 18
};
console.log("需求二:" + obj2.姓名);//getter作用,调用的时候不用加括号
setter
let obj3 = {
姓: "张",
名: "小明",
get 姓名() {
return this.姓 + this.名;
},
set 姓名(xxx){ //setter
this.姓 = xxx[0]
this.名 = xxx.slice(1)
},
age: 18
};
obj3.姓名 = '张小红' //setter 用法
console.log(`需求三:姓 ${obj3.姓},名 ${obj3.名}`)
Object.defineProperty 的问题
必须要有一个'n',才能监听并代理data.n。
但是如果没有给出n怎么办?以下有两种情况:
new Vue({
data: {},
template: `
<div>{{n}}</div>
`
}).$mount("#app");
此时Vue会给出一个警告:
new Vue({
data: {
obj: {
a: 0 // obj.a 会被 Vue 监听 & 代理
}
},
template: `
<div>
{{obj.b}}
<button @click="setB">set b</button>
</div>
`,
methods: {
setB() {
this.obj.b = 1; //此时,页面中不会显示1
}
}
}).$mount("#app");
data中没有b属性,因此Vue无法监听和代理b。Vue只会检查第一层属性。
解决办法
- 一开始就设置好
data的所有key,就是属性。 - 使用
Vue.set或者this.$set
Vue.set 和 this.$set
new Vue({
data: {
obj: {
a: 0 // obj.a 会被 Vue 监听 & 代理
}
},
template: `
<div>
{{obj.b}}
<button @click="setB">set b</button>
</div>
`,
methods: {
setB() {
Vue.set(this.obj,'b',100)//在obj对象里新建属性b,b的value是100
}
}
}).$mount("#app");
data中的数据是数组怎么办?
用set新增key,会更新UI,但不会创建监听和代理。
不过尤玉溪篡改了7个API方便你对数组进行增删
这7个API不会更新UI,但不会自动处理监听和代理
this.array[n] = xxx,即不会更新 UI,也不会自动处理监听和代理
结论:数组新增key最好通过7个API
数据响应式
定义
如果一个物体能够对外界刺激做出反应,那么它就是响应式的。
Vue的data是响应式
const vm = new Vue({data: {n: 0}})
我如果修改vm.n,那么UI中的n就会响应我。Vue2通过Object.defineProperty来实现数据响应式
响应式网页
用户改变网页窗口大小,网页内容会做出响应,那么就是响应式网页
比如:www.smashingmagazine.com/