Vue.js学习记录-12-Vue去哪儿网项目实战:城市列表页开发-Header + Vuex实现数据交互
-
Header:城市信息选择标题展示
在此组件中,主要做了向Home组件的页面路由跳转
<template>:需要注意的是被<router-link>包裹的标签会使原标签样式无效,类似<a>。
解决方案上篇文章已经给出:https://blog.****.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才可以直接操作State进行数据的变更调整
项目结构:参考官方给出的项目结构
安装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中进行说明