VUE—用vuex进行状态管理
1、cnpm install vuex -D
2、在src中新建store文件夹(公共状态管理库)并新建index.js文件,并输入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { // 存放公共变量
text: '请选择', // input框内的原始内容
isShow: false // 下拉列表隐藏
},
mutations: { // 存放公共方法
changedFn: function state, ops) {
state[ops.target] = ops.cont
}
}
})
3、main.js中输入
import store from './store' // 引入store
new Vue({
router,
store, // 写在router下面,和router一样,就可以在全局使用 this.$store
})
4、在components中新建三个vue文件
select.vue
<template>
<div id="select">
<Input></Input>
<List :listData="listData" v-show="isShow"></List>
// isShow是公共变量,在store的index里定义
// listData是父路由传给子路由的数组,用来循环下拉列表项
</div>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
// mapState, mapMutations是辅助函数,顾名思义就是获取store的index里的state里的参数和mutations里的方法所用
import Input from './Input'
import List from './List'
let listData = [
{name: '北京'},
{name: '上海'},
{name: '广州'},
{name: '深圳'},
{name: '杭州'}
]
export default {
name: "Select",
data () {
return {
listData
}
},
computed: {
...mapState(['isShow']) // 获取store的index的参数,来控制下拉列表框的显示和隐藏
},
components: {
Input,
List
}
}
</script>
<style lang="less"> // 注意使用less依赖需要添加lang="less"
#select{ // 使用less需要下载less依赖 cnpm install less less-loader -D
width: 300px;
border: 2px solid #ccc;
border-radius: 6px;
padding: 10px;
margin: 100px auto;
input{
width: 100%;
height: 40px;
border: 2px solid #ccc;
border-radius: 6px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ul{
padding: 0;
margin: 0;
li{
list-style-type: none;
padding: 10px;
border-bottom: 1px solid #ccc;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
}
}
</style>
input.vue
<template>
<div>
<input @click="toggleShow" v-model="text" type="text" readonly>
// text是公共变量,在store的index里定义
</div>
</template>
<script>
import {mapState, mapMutations} from 'vuex'
export default {
name: "Input",
computed: {
...mapState(['text']) // 获取store定义的text变量
},
watch: {
'text': function () {
this.changedFn({
target: 'isShow',
cont: false
})
}
},
methods: {
...mapMutations(['changedFn']), // 获取store定义的changedFn方法
toggleShow: function () { // 点击input框是触发此方法
this.changedFn({ // 调用store定义的changedFn方法并传参
target: 'isShow',
cont: true
})
}
}
}
</script>
list.vue
<template>
<div>
<ul>
<li @click="getVal(item)" v-for="(item, index) in listData" :key="index">{{item.name}}</li>
// 子路由从select父路由里获取到的数组用props接收了
// 点击每个li触发getVal方法并传参
</ul>
</div>
</template>
<script>
import {mapMutations} from 'vuex'
export default {
name: "List",
props: {
listData: {
type: Array,
default: function () {
return []
}
}
},
methods: {
...mapMutations(['changedFn']),
getVal: function (item) {
this.changedFn({
target: 'text',
cont: item.name
})
}
}
}
</script>
router文件夹的index.js
import Vue from 'vue'
import Router from 'vue-router'
import Select from '@/components/Select'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Select',
component: Select
}
]
})
效果:
初始状态:
点击input框
点击下拉列表