vuex中遇到的坑,vuex數(shù)據(jù)改變,組件中頁面不渲染操作
vuex數(shù)據(jù)改變,組件中頁面不渲染
相信許多vuex新手都會遇到這樣的問題:
vuex數(shù)據(jù)更新后,插件中使用數(shù)據(jù)的地方?jīng)]有更新
這樣的代碼
data() {
return {
tableData: this.$store.state.AdminInfo
};
}
然后在 template 中使用 tableData
<el-table :data="tableData" class="tablePst"> <el-table-column label="登錄名" prop="loginname"></el-table-column> <el-table-column label="真實(shí)姓名" prop="realname"></el-table-column> </el-table>
這樣的話,就會出現(xiàn)數(shù)據(jù)改變不渲染的問題
問題
要解決問題,就得理解vue生命周期,頁面加載前 tableData 獲取 store 里的值賦給自己,這樣 tableData 只有一初始值,后續(xù)vuex中狀態(tài)發(fā)生改變,并不會再次賦值給 tableData ,除非頁面刷新重新加載,組件生命周期重新開始,才能拿到最新的值
解決
1.去掉組件中 tableData 的狀態(tài),在模板中直接使用 $store.state.AdminInfo 這樣就能隨時(shí)拿到最新的狀態(tài)值了
<el-table :data="$store.state.AdminInfo" class="tablePst"> <el-table-column label="登錄名" prop="loginname"></el-table-column> <el-table-column label="真實(shí)姓名" prop="realname"></el-table-column> </el-table>
2.使用mapState,把vuex中的狀態(tài)暴露給組件,再使用,具體見文檔 vuex mapState官方文檔.
補(bǔ)充知識:解決vue修改數(shù)據(jù)頁面不重新渲染問題(Vue中數(shù)組和對象更改后視圖不刷新)
vue渲染機(jī)制和如何解決數(shù)據(jù)修改頁面不刷新問題的多種方法
本文不講原理,只講干貨易懂易學(xué),(感覺能學(xué)到知識,麻煩給小編來個(gè)贊!)
首先 第一點(diǎn),vue底層是 將data對象傳人,使用Object.definePropety,轉(zhuǎn)換為getter和setter,所以,vue不支持IE8.
1.簡單介紹一下Object.definePropety,
Object.defineProperty(obj, prop, descriptor)
//參數(shù)
obj
要在其上定義屬性的對象。
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//我的名字叫張三
從上述我們可以簡單發(fā)現(xiàn)。當(dāng)我們對這個(gè)對象的name屬性賦值的時(shí)候,就會觸發(fā)set方法,獲取name屬性的時(shí)候就會觸發(fā)get方法;
2.因此在vue中寫在data中的屬性是是可以轉(zhuǎn)換成getter和setter,換一句話就是響應(yīng)式的,其他定義在data之外的數(shù)據(jù),是無法響應(yīng)的渲染,意思就是改變數(shù)據(jù)頁面也不會刷新,所以一切要渲染到頁面上的數(shù)據(jù),必須寫在data中,
不需要的,可以定義在this上,
var vm = new Vue({
data:{
a:1
}
})
// `vm.a` 是響應(yīng)式的
vm.b = 2
// `vm.b` 是非響應(yīng)式的
3.簡單介紹完了,我們來列舉幾個(gè)不刷新的實(shí)例當(dāng)然上述也是一種
第一種:修改對象的某一屬性
vue只會將已經(jīng)在data中聲明的屬性變?yōu)轫憫?yīng),沒有聲明的是不響應(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方法來觸發(fā)渲染
this.$set(this.list,'d','d')
}
}
})
</script>
當(dāng)然如果我們要添加多個(gè)屬性,可以使用 Object.assign() 用于將所有可枚舉屬性的值從一個(gè)或多個(gè)源對象復(fù)制到目標(biāo)對象,并返回目標(biāo)對象。(簡單說就是合并到第一個(gè)參數(shù)中)
this.list = Object.assign({},this.list,{c:'c',d:'d'})
第二種:修改數(shù)組對象的某一屬性
<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è)對象直接賦值,是無法動態(tài)渲染的(即改變了數(shù)據(jù),頁面不渲染)
this.list[0] = {a:'css'} //頁面不渲染
console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
},
hadelClick(){
// 解決方法,使用vue提供的$set方法來觸發(fā)渲染
this.$set(this.list[1],'a','css')
console.log(this.list)//[{a:'css'},{a:'css'},{a:'js'}]
}
}
})
</script>
當(dāng)然前文講過,vue會遍歷data中的數(shù)據(jù),將對象轉(zhuǎn)換成setter和getter。所以數(shù)組中的也不例外,所以上述操作
改成:
click(){
this.list[0].a = css //依舊能夠觸發(fā)setter。實(shí)現(xiàn)數(shù)據(jù)重新渲染
}
}
在vue中更多的是數(shù)組的操作不刷新,一種是通過索引賦值,一種是修改數(shù)組長度,如何解決呢?
vue官方也給了方法
數(shù)組的API,中能夠改變原始數(shù)組的都能觸發(fā)更新;
1、push()
2、pop()
3、shift()
4、unshift()
5、splice()
6、sort()
7、reverse()
第二種是返回一個(gè)新數(shù)組的,這種數(shù)組在引用地址上已經(jīng)發(fā)生根本改變,這樣的賦值操作是能觸發(fā)更新的(這是處理不刷新的思路,就是改變引用地址,重新賦值觸發(fā)更新)
簡單說,用數(shù)組的API就是直接用原數(shù)組接收改變的數(shù)組,
<template>
<div>
<div v-for='item in list'>{{item.a}}</div>
<button @click='click'>改變原數(shù)組</button>
<button @click='hadelClick'>不改變原數(shù)組</button>
</div>
</template>
<script>
export default({
data(){
return{
list:[{a:'vue'},{a:'react'},{a:'js'}],
}
},
methods: {
click() {
//改變數(shù)組刷新頁面
this.list.push({a:'css'})
},
hadelClick(){
//重新賦值刷新頁面
this.list = this.list.map(item=>{
item.a = 'css'
return item
})
}
})
</script>
最后提供解決思路(以上都搞不定的話)
對象和數(shù)組都是引用傳遞,要變成新數(shù)組,來接受,就需要改變源,
第一種
let arr = []//新數(shù)組
this.list.forEach(item=>{ //需要渲染的數(shù)組
//執(zhí)行你的操作,最后用放到arr中
arr.push(item)
})
this.list = arr //相當(dāng)于返回一個(gè)新數(shù)組可以觸發(fā)渲染
第二種
//想要直接改變渲染數(shù)組中的數(shù)據(jù),但沒有渲染
//解決方法:
let arr = this.list.slice(0);//深拷貝,(等價(jià)一個(gè)新的數(shù)組)
arr.forEach(item=>{
//執(zhí)行你的操作
})
//賦值操作
this.list = arr
當(dāng)然這里只是簡單介紹了,有關(guān)深拷貝的詳細(xì)介紹,還請自行百度
上述如果都無法執(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'} //頁面不渲染
console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
},
hadelClick(){
this.list[0] = {a:'css'} //頁面不渲染
console.log(this.list) //[{a:'css'},{a:'react'},{a:'js'}]
this.$forceUpdate();//強(qiáng)制刷新
}
}
})
</script>
以上這篇vuex中遇到的坑,vuex數(shù)據(jù)改變,組件中頁面不渲染操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue elementui 動態(tài)追加下拉框、輸入框功能
這篇文章主要介紹了vue elementui 動態(tài)追加下拉框、輸入框功能,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-04-04
element-ui 插槽自定義樣式居中效果實(shí)現(xiàn)思路
這篇文章主要介紹了element-ui 插槽自定義樣式居中效果,簡單來講實(shí)現(xiàn)思路是通過template標(biāo)簽可理解為一個(gè)內(nèi)嵌組件,寬高重新定義,可在自定義內(nèi)容外層套一層盒子,讓盒子占滿所有空間,再使用flex讓內(nèi)部元素居中,需要的朋友可以參考下2024-07-07
Vue使用Proxy監(jiān)聽所有接口狀態(tài)的方法實(shí)現(xiàn)
這篇文章主要介紹了Vue使用Proxy監(jiān)聽所有接口狀態(tài)的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

