Vue.js學習記錄-12-Vue去哪兒網專案實戰:城市列表頁開發-Header + Vuex實現資料互動
-
Header:城市資訊選擇標題展示
在此元件中,主要做了向Home元件的頁面路由跳轉
<template>:需要注意的是被<router-link>包裹的標籤會使原標籤樣式無效,類似<a>。
解決方案上篇文章已經給出:https://blog.csdn.net/Nerver_77/article/details/83586432
<template> <div class="header"> 城市選擇 <router-link to="/"> <div class="iconfont header-back"></div> </router-link> </div> </template>
-
Vuex實現資料共享
功能點5:使用者選定的城市資訊將通過記憶體進行儲存,並且選定的城市資訊將展示在首頁Header右側的城市資訊展示區域和城市列表頁的當前城市資訊展示區域中。
為什麼先提到這塊內容呢?答案是,功能點5是貫徹Search、List、Alphabet元件的。
簡單概括:選定城市資訊 —> 城市資訊展示
在這個過程中:存在非父子、兄弟元件間的資料傳遞(City、Home),也存在兄弟元件間的資料傳遞。
以往我們解決此類問題,曾提到過匯流排BUS解決方案,但是Vue給我們提供了一套更加完善的解決方案:Vuex
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
狀態管理模式:這裡引入官方的一張截圖
圖中說的很明確,針對單項資料流的傳遞理念,當我們遇到多個元件共享狀態時,單項資料流的簡潔性很容易被破壞。
將元件的共享狀態抽取出來,交給一個全域性單例模式進行管理。
我們來梳理下這個狀態管理模式的執行流程:- State (儲存資料的資料來源) 向 元件進行資料傳遞render
- 元件通過dispatch進行資料操作排程,觸發Actions ( 元件也可以直接將資料操作排程資訊commit給Mutations )
- Actions 將資料操作排程資訊提交commit給Mutations
- 只有Mutations
專案結構:參考官方給出的專案結構
安裝Vuex
npm install vuex --save
目錄結構:座標**/src**
/store actions.js index.js 模組組裝管理 mutations.js state.js
基礎配置
-
專案入口檔案main.js引入store模組
import store from './store'
-
store/index.js引入子模組,並進行統一管理
-
引入模組
import Vue from 'vue' import Vuex from 'vuex' import state from './state' import actions from './actions' import mutations from './mutations'
-
在vue中使用vuex
Vue.use(Vuex)
-
store初始化,模組統一管理
export default new Vuex.Store({ // 部分拆分後,直接引用即可 state, actions, mutations, })
-
開始使用:以首頁Header右側的城市資訊展示區域為例,資料傳遞方法名為changeCity。
-
初始化state:使用了localStorage實現資訊儲存
let defaultCity = '上海' try { if (localStorage.city) { defaultCity = localStorage.city } } catch (e) {} export default { // 基礎資料來源 // 使用localStorage實現資訊儲存 city: defaultCity }
-
元件向actions進行資料排程
export default { // 元件通過dispatch方法傳遞引數:ctx上下文物件 city傳遞引數 changeCity(ctx, city) { // 使用上下文物件ctx的commit方法呼叫mutation ctx.commit('changeCity', city) } }
-
actions向mutations提交資料變更
export default { changeCity(state, city) { // mutation進行對state資料來源內容的修改 state.city = city // localStorage資訊更新 新增trycatch,針對瀏覽器匿名模式異常的解決方案 try { localStorage.city = city } catch (e) {} } }
高階用法:最終資料變化的接受者是Home.Header,該元件中通過vuex的資料對映以及計算屬性進行資料的接收展示。
<script>
// 引入vuex中的state資料進行對映到元件的計算屬性上 import { mapState } from 'vuex' computed: { // 將store中的名稱為city的state資料對映到元件中名稱為city的計算屬性上 ...mapState(['city']) }
<template>
<div class="header-right"> <!-- 完成mapState對映後,直接使用元件計算屬性即可 --> {{this.city}} <span class="iconfont arrow-icon"></span> </div>
TIPS:功能點5中城市列表頁的當前城市資訊展示區域將在元件List中進行說明