今天要来分享的是关于资料的观测及设定。
首先这是我们的html资料,点一下对应的图标,其图标数字会加一。
<div class="title row "> <div class="description col-12"> // 一般资料型态直接+即可 <div class="badge badge-light" @click="number++" > {{ number }} </div> </div> <div class="description col-12 "> // 纯物件型态也是直接+即可 <div class="badge badge-light" @click="obj.num++" > {{ obj.num }} </div> </div> <div class="description col-12 "> // 而阵列中包物件资料型态,我们呼叫函数来做+ <div v-for="(item,index) in objList" class="badge badge-light" @click="objListHandler(index)" > {{ item.num }} </div> </div> <div class="description col-12"> // 阵列资料型态,我们呼叫函数来做+ <div v-for="(number,index) in numberList" class="badge badge-light" @click="numberListHandler(index)" > {{ number }} </div> </div> </div>
对应至data中的资料。
let data = { number: 0, obj: { num: 0 }, objList: [{ num: 0 }, { num: 0 }, { num: 0 }], numberList: [0, 0, 0] }
vm.$set(target(目标物件或阵列), key(属性), value(赋予的值))
而在method部分,先处理我们所呼叫用来做加总计算的函数。
首先为objList的部分,直接获取对应下标的属性(num)做++。
methods: { { objListHandler(index) { this.objList[index].num++; } .... }
而在numberList的部分,我们使用像objList的方法直接获取对应下标的资料做++,会发现画面并没有改变。
而我们可透过$vm0在console去抓Vue里面的资料
。
可看出objList是一个observer的阵列,如果资料改动会被通知
// $vm0.objList(3)[{ // …}, { // …}, { // …}, __ob__: Observer]
可看出objList中下标0的资料是一个observer的物件,如果资料改动会被通知
// $vm0.objList[0] { // __ob__: Observer // }
可看出numberList是一个observer的阵列,如果资料改动会被通知
// $vm0.numberList(3)[1, 1, 1, __ob__: Observer]
但numberList中下标0的资料只是单纯的值,所以资料改动并不会通知
,所以只会在下次通知要更新时,才会更新
// $vm0.numberList[0] // 1
所以我们需透过vm.$set(target(目标物件或阵列), key(属性), value(赋予的值))
动态新增响应式的属性,且target本身将会进行通知。
numberListHandler(index) { // 所以不可直接去改变阵列中的纯值 // this.numberList[index]++; this.$set(this.numberList, index, this.numberList[index] + 1) }
watch: 可针对想观测的数据做function,可观测普通资料或是物件中的某笔资料或整陀资料。
对普通资料做观测
watch: { number(val, oldVal) { console.log('number:', val, oldVal); }, ...... }
针对obj里面某(单一)参数做观测
// ["obj.xxx"] ["obj.num"](val, oldVal) { console.log('obj:', val, oldVal); }
针对obj所有资料做观测,可发现旧的值及新值是相同,由于是对物件(或是阵列)做深度观测,因为会指向原始物件本身
,所以结论在观测的资料为物件,去观测oldValue及value没什么意义,只会观测到当前的值(Val)
,对于有物件型态皆要加上deep
。
obj: { // 对整陀资料做function handler(val, oldVal) { console.log('obj.number:', val, oldVal) // {__ob__: Observer} num: 1 ... // {__ob__: Observer} num: 1 ... }, // 我们改变的是objList中的物件,所以通知的是阵列中的物件,所以要加上deep,告诉vue 我们要观测很深。 deep: true },
对阵列做观测,因为我们改变的是numberList中的资料,故通知的应当是其资料,但由于动态新增属性的关係,是透过this.numberList通知,由于本身就会进行通知,故不需要再透过deep
。
numberList: { handler(val, oldVal) { console.log('numberList:', val, oldVal) }, // deep: true },