[英]Sharing a state store object to child components in Vue (without Vuex)
[英]Vuex/Redux store pattern - sharing single source of data in parent and child components that require variations of that data
我理解使用存儲模式和在應用程序中跨組件共享數據的單一真實來源以及在由組件調用的存儲操作中進行 API 調用而不是在需要數據的每個組件中單獨請求的好處.
據我了解,如果此數據需要以某種方式更改,具體取決於使用數據的組件,則可以通過使用適當的過濾器/參數調用存儲操作並相應地更新全局存儲變量來更新此數據。
但是,我很難理解如何解決父組件需要此數據的一個版本而該組件的子組件需要另一個版本的問題。
考慮以下示例:
在 API 中,端點上存在一個 GET 方法以返回所有人員。 可以傳遞一個標志來返回生病的人:
GET: api/people
返回['John Smith', 'Joe Bloggs', 'Jane Doe']
GET: api/people?isOffSick=true
返回['Jane Doe']
前端應用程序中的父組件需要未過濾的數據,但子組件需要過濾后的數據。 對於 arguments,API 不會在響應中返回 isOffSick boolean,因此需要進行 2 個單獨的請求。
考慮以下 Vue.js 中的示例:
// store.js
export const store = createStore({
state: {
people: []
},
actions: {
fetchPeople(filters) {
// ...
const res = api.get('/people' + queryString);
commit('setPeople', res.data);
}
},
mutations: {
setPeople(state, people) {
state.people = people;
}
}
});
// parent.vue - requires ALL people (NO filters/args passed to API)
export default {
mounted() {
this.setPeople();
},
computed: {
...mapState([
'people'
])
},
methods: {
...mapActions(['setPeople']),
}
}
// child.vue - requires only people who are off sick (filters/args passed to API)
export default {
mounted() {
this.setPeople({ isOffSick: true });
},
computed: {
...mapState([
'people'
])
},
methods: {
...mapActions(['setPeople']),
}
}
父組件用它需要的數據設置存儲變量,然后子組件用它需要的數據覆蓋那個存儲變量。
顯然,共享存儲變量與這兩個組件都不兼容。
對於商店模式,此問題的首選解決方案是什么? 在子組件中單獨存儲 state 似乎違反了數據的單一真實來源,這部分是首先使用存儲模式的部分原因。
編輯:
我的問題與商店模式的架構有關,而不是針對這個特定示例尋求解決方案。 我很欣賞此示例中的 API 響應沒有提供足夠的信息來過濾人員的全局存儲,即使用 getter,以便在子組件中使用。
我要問的是:如果我想忠於以商店為中心的設計模式,那么哪里是存儲第二批人的合適地點?
以某種方式創建另一個存儲變量來保存子組件的數據似乎是錯誤的,但將第二組數據存儲在子組件的 state 中似乎也違反直覺,因為這不符合存儲模式方法並保持組件“啞”。
如果有許多地方需要對只能通過單獨的 API 調用創建的人員數據進行變體,則要么 a) 數據的每個“變體”都有很多存儲變量,要么 b) 單獨的 API 調用和 state在每個組件中。
感謝 tao 我找到了我要找的東西:
最好的方法是在 API 響應中返回 isOffSick 屬性,然后過濾單個人員列表(例如使用商店 getter),從而為商店中的所有人提供單一的真實來源並避免需要另一個 API要求。
如果那不可能,那么為 isOffSick 人添加一個輔助存儲變量將是有意義的,以供子組件使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.