Vue2.5 学习笔记8.9 使用Vuex实现数据共享
现在要实现的功能是在城市列表页无论是点击列表中的城市还是点击搜索栏搜索出来的城市。都能够自动跳转到首页。并且将所点击的城市名带到首页。
现在的情况是 City.vue和Home.vue是两个独立的组件。他们没有公用的父级组件(App.vue那个不算)
可以用BUS总线的技术进行传递。不过我这里说的是另一种方法: Vuex
Vuex--数据层框架
官方文档:https://vuex.vuejs.org/zh/
state:存放公用数据
actions: 一些操作。 执行mutations中的函数
mutations:放置对state中数据修改的函数
组件(components)通过Dispatch方法调用actions
actions通过commit方法调用mutations
好了 理论就说这些 反正就一句话: vuex是个数据仓库。大家都可以往里面存取数据。只是不能直接拿,要走流程,写申请。不然跟领导不好交代。
那流程怎么走呢。首先 组件通过Dispatch方法跟actions申请操作数据。 actions呢,它收到了你的申请,会通过mutations来执行你要的操作(mutations就相当于工具。 存取数据的工具。打个比方 我们找办公室要一张报销单。那办公室肯定不会直接手写给你,肯定要通过电脑打印一份出来给你。 那这个电脑就是mutations。 而报销单就是state了。大概这意思)
那具体咋使用捏:
1.先安装:
npm install vuex --save
2. 创建vuex区域
在src目录下创建store文件夹
然后在该文件夹下创建index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 这货就是仓库中的数据了
state: {
city: '上海'
}
})
然后在main.js中引入Vuex
import Vue from 'vue'
import App from './App'
import router from './router'
import fastClick from 'fastclick'
import 'styles/reset.css'
import 'styles/border.css'
import 'styles/iconfont.css'
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
// 这里
import store from './store'
Vue.config.productionTip = false
fastClick.attach(document.body)
Vue.use(VueAwesomeSwiper)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
// 这里
store,
components: { App },
template: '<App/>'
})
删除City.vue中对Header.vue的数据传递
将City.vue中的组件Header.vue修改下
<template>
<div class="Header">
<div class="Header-left">
<div class="iconfont back-icon"></div>
</div>
<div class="Header-input">
<span class="iconfont"></span>
输入城市/景点/主题
</div>
<router-link to="/city">
<div class="Header-right">
//这里改成state中的数据
{{this.$store.state.city}}
<span class="iconfont arrow-icon"></span>
</div>
</router-link>
</div>
</template>
<script>
// 这里也将props删掉
export default {
name: 'HomeHeader'
}
</script>
然后将json中的city数据也删掉
List.vue:
<template>
<div class="list" ref="wrapper">
<div>
<div class="area">
<div class="title border-topbottom">当前城市</div>
<div class="button-list">
<div class="button-wrapper">
//这里
<div class="button">{{this.$store.state.city}}</div>
</div>
</div>
</div>
3. 接下来完成列表页的各个城市的点击跳转动作:
<div class="area">
<div class="title border-topbottom">热门城市</div>
<div class="button-list">
<div
class="button-wrapper"
v-for="item of hot"
:key="item.id"
// 这里
@click="handleCityClick(item.name)"
>
<div class="button">{{item.name}}</div>
</div>
</div>
</div>
<div class="area"
v-for="(item, key) of cities"
:key="key"
:ref="key"
>
<div class="title border-topbottom">{{key}}</div>
<div class="item-list">
<div class="item border-bottom"
v-for="innerItem of item"
:key="innerItem.id"
// 这里
@click="handleCityClick(innerItem.name)"
>
{{innerItem.name}}
</div>
</div>
</div>
</div>
</div>
// 这里
methods: {
handleCityClick (city) {
this.$store.dispatch('changeCity', city)
// 如果数据量不大 也可以直接操作mutations:
// this.$store.commit('changeCity', city)
// 编程式导航 跳转到首页。
this.$router.push('/')
}
}
//store/index.js
actions: {
changeCity (ctx, city) {
//ctx代表这个vuex的区域
ctx.commit('changeCity', city)
}
},
mutations: {
changeCity (state, city) {
//state代表的就是数据仓库state
state.city = city
}
}
4.Search.vue的改进:
<ul>
<li
class="search-item border-bottom"
v-for="item of list"
:key="item.id"
@click="handleCityClick(item.name)"
>
{{item.name}}
</li>
<li class="search-item border-bottom" v-show="hasNoData">
没有找到匹配数据
</li>
methods: {
handleCityClick (city) {
this.$store.commit('changeCity', city)
this.$router.push('/')
}
},
结束 撒花