3Vue-数据响应式

103 阅读1分钟

3.1 getter和setter

getter

let obj2 = {
  姓: "高",
  名: "圆圆",
  get 姓名() {
    return this.姓 + this.名;
  },
  age: 18
};

console.log("需求二:" + obj2.姓名);
// 总结:getter 就是这样用的。不加括号的函数,仅此而已。

setter

let obj3 = {
  姓: "高",
  名: "圆圆",
  get 姓名() {
    return this.姓 + this.名;
  },
  set 姓名(xxx){
    this.姓 = xxx[0]
    this.名 = xxx.slice(1)
  },
  age: 18
};

obj3.姓名 = '高媛媛'

console.log(`需求三:姓 ${obj3.姓},名 ${obj3.名}`)
//总结:setter 就是这样用的。用 = xxx 触发 set 函数

3.2 Object.defineProperty

Object.defineProperty用法, 当对象实例化好后, 又想添加getter,setter时候使用.

let obj3 = {
  姓: "高",
  名: "圆圆",
  get 姓名() {
    return this.姓 + this.名;
  },
  set 姓名(xxx) {
    this.姓 = xxx[0];
    this.名 = xxx.slice(1);
  },
  age: 18
};

var _xxx = 0

Object.defineProperty(obj3, "xxx", {
  get(){
    return _xxx
  },
  set(value){
    _xxx = value
  }
})


obj3.姓名 = "高媛媛";

console.log(`需求三:姓 ${obj3.姓},名 ${obj3.名}`);
console.log(obj3)

3.3 代理和监听

let data0 = {n: 0}

// 需求一:用 Object.defineProperty 定义 n
let data1 = {}
Object.defineProperty(data1, 'n', {
value: 0
})

console.log(`需求一:${data1.n}`)

//结果
// 需求一:0

// 需求二:n 不能小于 0
// 即 data2.n = -1 应该无效,但 data2.n = 1 有效

let data2 = {}
data2._n = 0 // _n 用来偷偷存储 n 的值

Object.defineProperty(data2, 'n', {
get(){return this._n},
set(value){
if(value < 0) return
this._n = value
  }
})
console.log(`需求二:${data2.n}`)
data2.n = -1
console.log(`需求二:${data2.n} 设置为 -1 失败`)
data2.n = 1
console.log(`需求二:${data2.n} 设置为 1 成功`)


// 需求二:0
// 需求二: 0      设置为 -1 失败
// 需求二: 1      设置为 1 成功
// 需求三:使用代理
let data3 = proxy({ data:{n:0} }) // 括号里是匿名对象,无法访问
function proxy({data}/* 解构赋值,别TM老问 */){
const obj = {}
// 这里的 'n' 写死了,理论上应该遍历 data 的所有 key,这里做了简化
Object.defineProperty(obj, 'n', {
get(){return data.n},
set(value){
if(value<0)return
data.n = value
  }
})

return obj // obj 就是代理}
// data3 就是 obj
console.log(`需求三:${data3.n}`)
data3.n = -1
console.log(`需求三:${data3.n},设置为 -1 失败`)
data3.n = 1
console.log(`需求三:${data3.n},设置为 1 成功`)



// 0
// 0,设置为 -1 失败
// 1,设置为 1 成功
// 需求四
let myData = {n:0}
let data4 = proxy({ data:myData }) // 括号里是匿名对象,无法访问
// data3 就是 obj
console.log(`杠精:${data4.n}`)
myData.n = -1
console.log(`杠精:${data4.n},设置为 -1 失败了吗!?`)

// 我现在改 myData,是不是还能改?!你奈我何

// 艹,算你狠
// 需求五:就算用户擅自修改 myData,也要拦截他

\


let myData5 = {n:0}

let data5 = proxy2({ data:myData5 }) // 括号里是匿名对象,无法访问

\


function proxy2({data}/* 解构赋值,别TM老问 */){

// 这里的 'n' 写死了,理论上应该遍历 data 的所有 key,这里做了简化

// 因为我怕你们看不懂

let value = data.n

Object.defineProperty(data, 'n', {

get(){

return value

},

set(newValue){

if(newValue<0)return

value = newValue

}

})

// 就加了上面几句,这几句话会监听 data

\


const obj = {}

Object.defineProperty(obj, 'n', {

get(){

return data.n

},

set(value){

if(value<0)return//这句话多余了

data.n = value

}

})

return obj // obj 就是代理

}

\


// data3 就是 obj

console.log(`需求五:${data5.n}`)

myData5.n = -1

console.log(`需求五:${data5.n},设置为 -1 失败了`)

myData5.n = 1

console.log(`需求五:${data5.n},设置为 1 成功了`)

\
\


// 这代码看着眼熟吗?

// let data5 = proxy2({ data:myData5 })

// let vm = new Vue({data: myData})

\


// 现在我们可以说说 new Vue 做了什么了

3.4 看Vue.js源代码

3.5 小结

image.png

3.6 Vue的data的bug

3.7 数组的变异方法

3.8 纠错$set作用于数组时, 不会添加监听

3.9 总结

image.png