解決vue修改數(shù)據(jù)頁(yè)面不重新渲染問(wèn)題
vue渲染機(jī)制和如何解決數(shù)據(jù)修改頁(yè)面不刷新問(wèn)題的多種方法
本文不講原理,只講干貨易懂易學(xué)
首先 第一點(diǎn),vue底層是 將data對(duì)象傳人,使用Object.definePropety,轉(zhuǎn)換為getter和setter,所以,vue不支持IE8.
1.簡(jiǎn)單介紹一下Object.definePropety,
Object.defineProperty(obj, prop, descriptor) //參數(shù) obj 要在其上定義屬性的對(duì)象。 prop 要定義或修改的屬性的名稱。 descriptor 將被定義或修改的屬性描述符
var obj = {} Object.defineProperty(obj, 'name', { get: function() { console.log('我的名字叫'+name); return name; }, set: function(value) { console.log('你叫'+value) name = value; } }); obj.name ='張三';//你叫張三 obj.name//我的名字叫張三
從上述我們可以簡(jiǎn)單發(fā)現(xiàn)。當(dāng)我們對(duì)這個(gè)對(duì)象的name屬性賦值的時(shí)候,就會(huì)觸發(fā)set方法,獲取name屬性的時(shí)候就會(huì)觸發(fā)get方法;
2.因此在vue中寫在data中的屬性是是可以轉(zhuǎn)換成getter和setter,換一句話就是響應(yīng)式的,其他定義在data之外的數(shù)據(jù),是無(wú)法響應(yīng)的渲染,意思就是改變數(shù)據(jù)頁(yè)面也不會(huì)刷新,所以一切要渲染到頁(yè)面上的數(shù)據(jù),必須寫在data中,
不需要的,可以定義在this上,
var vm = new Vue({ data:{ a:1 } }) // `vm.a` 是響應(yīng)式的 vm.b = 2 // `vm.b` 是非響應(yīng)式的
3.簡(jiǎn)單介紹完了,我們來(lái)列舉幾個(gè)不刷新的實(shí)例當(dāng)然上述也是一種
第一種:修改對(duì)象的某一屬性
vue只會(huì)將已經(jīng)在data中聲明的屬性變?yōu)轫憫?yīng),沒(méi)有聲明的是不響應(yīng)的
<template> <div> <div v-for='item in list'>{{item}}</div> <button @click='click'>改變</button> <button @click='hadelClick'>解決方法</button> </div> </template> <script> export default({ data(){ return{ list:{a:'a',b:'b'}, } }, methods: { click() { // 未聲明不觸發(fā)渲染 this.list.c='c' }, hadelClick(){ // 解決方法,使用vue提供的$set方法來(lái)觸發(fā)渲染 this.$set(this.list,'d','d') } } }) </script>
當(dāng)然如果我們要添加多個(gè)屬性,可以使用 Object.assign() 用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對(duì)象復(fù)制到目標(biāo)對(duì)象,并返回目標(biāo)對(duì)象。(簡(jiǎn)單說(shuō)就是合并到第一個(gè)參數(shù)中)
this.list = Object.assign({},this.list,{c:'c',d:'d'})
第二種:修改數(shù)組對(duì)象的某一屬性
<template> <div> <div v-for='item in list'>{{item.a}}</div> <button @click='click'>改變</button> <button @click='hadelClick'>解決方法</button> </div> </template> <script> export default({ data(){ return{ list:[{a:'vue'},{a:'react'},{a:'js'}], } }, methods: { click() { //想這樣直接給數(shù)組中的某一個(gè)對(duì)象直接賦值,是無(wú)法動(dòng)態(tài)渲染的(即改變了數(shù)據(jù),頁(yè)面不渲染) this.list[0] = {a:'css'} //頁(yè)面不渲染 console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}] }, hadelClick(){ // 解決方法,使用vue提供的$set方法來(lái)觸發(fā)渲染 this.$set(this.list[1],'a','css') console.log(this.list)//[{a:'css'},{a:'css'},{a:'js'}] } } }) </script>
當(dāng)然前文講過(guò),vue會(huì)遍歷data中的數(shù)據(jù),將對(duì)象轉(zhuǎn)換成setter和getter。所以數(shù)組中的也不例外,所以上述操作
改成: click(){ this.list[0].a = css //依舊能夠觸發(fā)setter。實(shí)現(xiàn)數(shù)據(jù)重新渲染 } }
在vue中更多的是數(shù)組的操作不刷新,一種是通過(guò)索引賦值,一種是修改數(shù)組長(zhǎng)度,如何解決呢?
vue官方也給了方法
數(shù)組的API,中能夠改變?cè)紨?shù)組的都能觸發(fā)更新;
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
第二種是返回一個(gè)新數(shù)組的,這種數(shù)組在引用地址上已經(jīng)發(fā)生根本改變,這樣的賦值操作是能觸發(fā)更新的(這是處理不刷新的思路,就是改變引用地址,重新賦值觸發(fā)更新)
簡(jiǎn)單說(shuō),用數(shù)組的API就是直接用原數(shù)組接收改變的數(shù)組,
<template> <div> <div v-for='item in list'>{{item.a}}</div> <button @click='click'>改變?cè)瓟?shù)組</button> <button @click='hadelClick'>不改變?cè)瓟?shù)組</button> </div> </template> <script> export default({ data(){ return{ list:[{a:'vue'},{a:'react'},{a:'js'}], } }, methods: { click() { //改變數(shù)組刷新頁(yè)面 this.list.push({a:'css'}) }, hadelClick(){ //重新賦值刷新頁(yè)面 this.list = this.list.map(item=>{ item.a = 'css' return item }) } }) </script>
最后提供解決思路(以上都搞不定的話)
對(duì)象和數(shù)組都是引用傳遞,要變成新數(shù)組,來(lái)接受,就需要改變?cè)矗?/p>
第一種
let arr = []//新數(shù)組 this.list.forEach(item=>{ //需要渲染的數(shù)組 //執(zhí)行你的操作,最后用放到arr中 arr.push(item) }) this.list = arr //相當(dāng)于返回一個(gè)新數(shù)組可以觸發(fā)渲染
第二種
//想要直接改變渲染數(shù)組中的數(shù)據(jù),但沒(méi)有渲染 //解決方法: let arr = this.list.slice(0);//深拷貝,(等價(jià)一個(gè)新的數(shù)組) arr.forEach(item=>{ //執(zhí)行你的操作 }) //賦值操作 this.list = arr
上述如果都無(wú)法執(zhí)行,但你的數(shù)據(jù)缺實(shí)修改了,可以使用this.$forceUpdate()方法 (強(qiáng)制刷新)
//this.$forceUpdate();//強(qiáng)制刷新 <template> <div> <div v-for='item in list'>{{item.a}}</div> <button @click='click'>改變</button> <button @click='hadelClick'>解決方法</button> </div> </template> <script> export default({ data(){ return{ list:[{a:'vue'},{a:'react'},{a:'js'}], } }, methods: { click() { this.list[0] = {a:'css'} //頁(yè)面不渲染 console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}] }, hadelClick(){ this.list[0] = {a:'css'} //頁(yè)面不渲染 console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}] this.$forceUpdate();//強(qiáng)制刷新 } } }) </script>
到此這篇關(guān)于解決vue修改數(shù)據(jù)頁(yè)面不重新渲染問(wèn)題的文章就介紹到這了,更多相關(guān)vue修改數(shù)據(jù)頁(yè)面不渲染內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法
在父組件 App.vue 中引用子組件 A.vue,把 name 的值傳給 A 組件。這篇文章主要介紹了vue2.0 父組件給子組件傳遞數(shù)據(jù)的方法,需要的朋友可以參考下2018-01-01詳解基于vue-cli配置移動(dòng)端自適應(yīng)
本篇文章主要介紹了詳解基于vue-cli配置移動(dòng)端自適應(yīng),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01使用vite搭建ssr活動(dòng)頁(yè)架構(gòu)的實(shí)現(xiàn)
本文主要介紹了使用vite搭建ssr活動(dòng)頁(yè)架構(gòu),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07vue 通過(guò)綁定事件獲取當(dāng)前行的id操作
這篇文章主要介紹了vue 通過(guò)綁定事件獲取當(dāng)前行的id操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法分析
這篇文章主要介紹了Vue el-table表頭上引入組件不能實(shí)時(shí)傳參解決方法,總的來(lái)說(shuō)這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過(guò)程。希望通過(guò)這道題能給你帶來(lái)一種解題優(yōu)化的思路2022-11-11