vue全局?jǐn)?shù)據(jù)管理示例詳解
記賬頁(yè)面標(biāo)簽頁(yè)面新增
記賬頁(yè)面和標(biāo)簽頁(yè)面都可以新增標(biāo)簽??墒乾F(xiàn)在有一個(gè)bug。在標(biāo)簽頁(yè)面新增標(biāo)簽之后,在記賬頁(yè)面不會(huì)自動(dòng)同步,要刷新一下才能同步。
這是因?yàn)檫@兩個(gè)頁(yè)面的數(shù)據(jù)tagList都是分別從tagListModel里fetch的。所以就導(dǎo)致了數(shù)據(jù)不同步。
解決方案:在更高一層的地方統(tǒng)一去tagListModel里fetch一次,把取出來(lái)的設(shè)成一個(gè)全局的屬性,然后分別在兩個(gè)頁(yè)面直接使用。
我們選擇在main.ts入口文件里聲明這個(gè)全局屬性:
window.tagList=tagListModel.fetch()
可是這樣會(huì)報(bào)錯(cuò),說(shuō)window里沒(méi)有這樣一個(gè)屬性。
那么我們就只能在custom.d.ts里自定義聲明window里有這樣一個(gè)屬性。
interface Window {
tagList: Tag[]
}
這樣再回到main.ts,就沒(méi)有報(bào)錯(cuò)了。
然后就可以在兩個(gè)頁(yè)面直接使用。
在Money.vue:
export default class Money extends Vue{
tags=window.tagList
}
在Labels.vue:
export default class Labels extends Vue {
tags=window.tagList
}
這樣就沒(méi)有那個(gè)bug了。在標(biāo)簽頁(yè)面新增一個(gè)標(biāo)簽后,在記賬頁(yè)面也會(huì)自動(dòng)同步。
把數(shù)據(jù)放到window上以后,讀取數(shù)據(jù)就是通過(guò)window操作的。但是寫(xiě)數(shù)據(jù),比如刪除,增加,修改標(biāo)簽,還是通過(guò)tagListModel這個(gè)對(duì)象的API操作的。
將API封裝到window
那么為了看起來(lái)一致,我們最好把這些API也封裝到window上。
//main.ts
//record store
window.recordList=recordListModel.fetch()
window.createRecord=(record: RecordItem)=>{
recordListModel.create(record)
}
// tag store
window.tagList=tagListModel.fetch()
window.createTag=(name: string)=>{
const message=tagListModel.create(name)
if(message==='duplicated'){
window.alert('標(biāo)簽名重復(fù)')
}else{window.alert('添加成功')}
}
window.removeTag=(id: string)=>{
tagListModel.remove(id)
}
window.updateTag=(id: string,newName: string)=>{
return tagListModel.update(id,newName)
}
window.findTag=(id: string)=>{
return window.tagList.filter(tag=>tag.id===id)[0]
}
把recordListModel,tagListModel上的屬性,方法都封裝到window上以后,有一個(gè)問(wèn)題。
1. window上的變量太多了。
2. 太依賴window了,如果在不支持window的情況下,就無(wú)法操作。
解決辦法: 不要window,把這些API都封裝到一個(gè)store對(duì)象上。在store目錄里新建一個(gè)index2.ts
const store={
//record store
recordList: recordListModel.fetch(),
createRecord: (record: RecordItem) => {
recordListModel.create(record);
},
// tag store
tagList: tagListModel.fetch(),
createTag: (name: string) => {
const message = tagListModel.create(name);
if (message === 'duplicated') {
window.alert('標(biāo)簽名重復(fù)');
} else {
window.alert('添加成功');
}
},
removeTag: (id: string) => {
tagListModel.remove(id);
},
updateTag: (id: string, newName: string) => {
return tagListModel.update(id, newName);
},
findTag: (id: string) => {
return store.tagList.filter(tag => tag.id === id)[0];
}
}
export default store;
以后操作數(shù)據(jù)就全部調(diào)用store
可是這樣store對(duì)象里有兩種數(shù)據(jù)的操作,我們最好還是把他們分開(kāi):
import recordStore from '@/store/recordStore';
import tagStore from '@/store/tagStore';
const store={
...recordStore,
...tagStore
}
export default store;
分成recordStore和tagStore兩個(gè)文件。然后統(tǒng)一在store里淺復(fù)制
那么全局?jǐn)?shù)據(jù)管理的好處是什么?
- 解耦:將所有數(shù)據(jù)相關(guān)的邏輯放入 store(也就是 MVC 中的 Model,換了個(gè)名字而已)。即從localStorage里取數(shù)據(jù),存數(shù)據(jù),對(duì)數(shù)據(jù)增刪改查,都由store里的API提供,別人要對(duì)數(shù)據(jù)操作,直接調(diào)用API就可以,不需要關(guān)心里邊的邏輯。
- 數(shù)據(jù)讀寫(xiě)更方便:任何組件不管在哪里,都可以直接讀寫(xiě)數(shù)據(jù)。比如說(shuō),原來(lái)Tags子組件里的標(biāo)簽列表是由它的父組件Money傳進(jìn)去的,如果它要增加標(biāo)簽,不能自己增加,要把數(shù)據(jù)傳出去在外邊修改。現(xiàn)在做了全局?jǐn)?shù)據(jù)管理之后,Tags子組件完全可以自己直接調(diào)用store,讀寫(xiě)數(shù)據(jù),不需要由父組件操作。
- 控制力更強(qiáng):組件對(duì)數(shù)據(jù)的讀寫(xiě)只能使用 store 提供的 API 進(jìn)行(當(dāng)然也不排除有豬隊(duì)友直接對(duì) tagList 和 recordList 進(jìn)行 push 等操作,這是沒(méi)有辦法禁止的) 前提:
我們?cè)贛oney.vue里,通過(guò)recordList=store.recordList ,這個(gè)data是從存儲(chǔ)庫(kù)里取出來(lái)的,他是一個(gè)數(shù)組,所以他們共用一個(gè)地址。所以我在store里對(duì)store.recordList進(jìn)行增刪改查時(shí),我的vue實(shí)例的數(shù)據(jù)recordList也會(huì)隨著改變。
但是如果store里的數(shù)據(jù)不是對(duì)象,而是基本數(shù)據(jù)類型的數(shù)據(jù)呢?
我們知道,如果是基本數(shù)據(jù)類型,如字符串,數(shù)字等,傳遞時(shí)是復(fù)制值的。
如:如果在store里聲明一個(gè)數(shù)字,
const store={
count:0,
addCount(){
this.count+=1
},
...recordStore,
...tagStore
}
然后在Money里,
export default class Money extends Vue{
count=store.count
add(){
store.addCount()
console.log(store.count);
}
把store.count賦值給自己的data,然后點(diǎn)擊一個(gè)按鈕調(diào)用add。發(fā)現(xiàn)頁(yè)面里展示的count,沒(méi)有變,還是0.
因?yàn)檫@是值傳遞,改變的只是store里的count。
那怎么做能同步呢?使得修改store.count,我這個(gè)實(shí)例上的count也會(huì)跟著改變呢?
不要用data獲取,因?yàn)閐ata只會(huì)獲取一遍,后邊的就不會(huì)再更新了
用computed計(jì)算屬性
@Component({
components: {FormItem, Type, Tags, NumPad},
computed:{
count(){
return store.count
}
}
})
在ts里,computed寫(xiě)在@Component里。
我這個(gè)count是一個(gè)計(jì)算屬性,他的值是返回store.count的值。但是點(diǎn)擊之后,頁(yè)面上的0還是沒(méi)有加1 .
因?yàn)閂ue并沒(méi)有監(jiān)聽(tīng)store對(duì)象,所以改變store,Vue并不知道。那就把store寫(xiě)在data里,
import store from "@/store/index2.ts"
export default{
data(){
return {
store:store,
}
}
}
為了不重復(fù),我們把它放在App.vue里,這樣Vue就監(jiān)聽(tīng)了store對(duì)象。
這樣做了以后,點(diǎn)擊按鈕,成功加1.
之后為了方便,不管是對(duì)象,還是基本的數(shù)據(jù)類型,我們都放在計(jì)算屬性里,然后全局監(jiān)聽(tīng)store對(duì)象。
以上就是vue全局?jǐn)?shù)據(jù)管理示例詳解的詳細(xì)內(nèi)容,更多關(guān)于vue全局?jǐn)?shù)據(jù)管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue3 axios配置以及cookie的使用方法實(shí)例演示
這篇文章主要介紹了Vue3 axios配置以及cookie的使用方法,需要的朋友可以參考下2023-02-02
vue總線機(jī)制(bus)知識(shí)點(diǎn)詳解
在本篇文章中小編給大家整理的是關(guān)于vue總線機(jī)制(bus)知識(shí)點(diǎn)總結(jié),有興趣的朋友們可以跟著學(xué)習(xí)下。2020-05-05
nuxt 頁(yè)面路由配置,主頁(yè)輪播組件開(kāi)發(fā)操作
這篇文章主要介紹了nuxt 頁(yè)面路由配置,主頁(yè)輪播組件開(kāi)發(fā)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
基于Vue技術(shù)實(shí)現(xiàn)遞歸組件的方法
這篇文章主要為大家詳細(xì)介紹了基于Vue技術(shù)實(shí)現(xiàn)遞歸組件的方法 ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
vue3+element Plus實(shí)現(xiàn)在table中增加一條表單數(shù)據(jù)的示例代碼
這篇文章主要介紹了vue3+element Plus實(shí)現(xiàn)在table中增加一條表單數(shù)據(jù)的操作,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
Vue封裝DateRangePicker組件流程詳細(xì)介紹
在后端管理項(xiàng)目中使用vue來(lái)進(jìn)行前端項(xiàng)目的開(kāi)發(fā),但我們都知道Vue實(shí)際上無(wú)法監(jiān)聽(tīng)由第三方插件所引起的數(shù)據(jù)變化。也無(wú)法獲得JQuery這樣的js框架對(duì)元素值的修改的。而日期控件daterangepicker又基于JQuery來(lái)實(shí)現(xiàn)的2022-11-11
Vue?列表過(guò)濾與排序的實(shí)現(xiàn)
這篇文章主要介紹了Vue?列表過(guò)濾與排序的實(shí)現(xiàn),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值需要的小伙伴可以參考一下2022-05-05
vue實(shí)現(xiàn)登陸頁(yè)面開(kāi)發(fā)實(shí)踐
本文主要介紹了vue實(shí)現(xiàn)登陸頁(yè)面開(kāi)發(fā)實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
Vue+Openlayers實(shí)現(xiàn)實(shí)時(shí)坐標(biāo)點(diǎn)展示
這篇文章主要為大家詳細(xì)介紹了Vue+Openlayers實(shí)現(xiàn)實(shí)時(shí)坐標(biāo)點(diǎn)展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
vue單頁(yè)開(kāi)發(fā)父子組件傳值思路詳解
這篇文章主要介紹了vue單頁(yè)開(kāi)發(fā)父子組件傳值思路詳解,本文是小編抽空整理的思路,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05

