前端框架Vue(10)——vuex 状态管理

来源:互联网 发布:js。push Array[0] 编辑:程序博客网 时间:2024/05/20 07:54

1、Vuex 是什么?

  Github vue-spa-demo 项目地址

  在使用 Vue 框架做单页面应用时,我们时常会遇到传值,组件公用状态的问题。(子父间传值文章传送门) ,如果是简单的应用,兄弟组件之间通信还能使用 eventBus 来作为中介。但是一旦应用比较庞大,那状态将会变得难以维持管理。

  Vue 为我们提供了进行大型状态管理的 Vuex,类似 Flux 。Vuex 采用了集中式存储管理所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

  直接用官方文档提供的关系图来讲:

这里写图片描述

一个 store 中包含了: Actions( 行为 ) 、Mutations( 突变 )、State( 状态 ),完整的 Vuex 动作是这样的 Components( 组件 )中 methods 里面一个方法 dispatch (调用)Actions,Actions 然后 commit 对应的Mutations, 只有 Mutations 可以操作 State 中的状态数据,状态一改变,组件中就重新渲染。路线:C——>A——>M——>S——>C。

2、Vuex 安装

(1)引入式

<script src="/path/to/vue.js"></script><script src="/path/to/vuex.js"></script>

(2)npm 安装

npm install vuex --save

3、Vuex 使用,结合小实例

一、这边提供两中目录结构共使用:

1、适合简单的项目,所有模块放到 store.js 中管理

import Vue from "vue"import Vuex from "vuex"Vue.use(Vuex)const store = new Vuex.Store({    state:{        count: 10,    },    mutations:{        //格式:类型(名字)+处理函数        //加1        INCREMENT(state) {            //console.log(state)//state对象            state.count++;        }    },    actions:{        increment({commit}){            commit("INCREMENT")        }    }}) export default store

2、将各个 js 单文件分开,便于管理

==store    =index.js    =mutations.js    =actions.js    =getters.js

index.js 主文件入口:

/***主要入口文件,引入其他四个js*/import Vue from "vue"import Vuex from "vuex"Vue.use(Vuex)//引入actions、mutations、gettersimport actions from "./actions.js"import mutations from "./mutations.js"import getters from "./getters.js"// 定义状态stateconst state = {}// 设置暴露接口export default new Vuex.Store({    state,    mutations,    actions,    getters})

mutations.js 、actions.js 、getters.js 文件类似:

export default {    //方法 对state数据进行统一操作}

main.js 进行全局注册:

import store from './store/index'/* eslint-disable no-new */new Vue({  el: '#app',  store,  router,  template: '<App/>',  components: { App }})

二、结合简易‘’不符合逻辑‘’计算器讲解 Vuex

1、先上简陋图:

这里写图片描述

2、逻辑: 输入框中进行数字输入,加减乘除按钮点击使用,点击确认输出结果。

3、目录结构:

这里写图片描述

*一 一对应

XTGL : 计算器
showBox : 最上方显示区
input : 输入区
calc : 四则运算区
output : 结果输出区

4、代码实现:
components 部分

inputBox.vue 负责初始值的输入,dispatch actions 中的 inputevent ,为了将输入的值显示到 showBox 中。

<template>    <div class="inputBox">        <div class="layui-form-item">            <label class="layui-form-label">输入:</label>            <div class="layui-input-block">              <input class="layui-input" v-model="inputNum" @blur="inputEvent">            </div>        </div>    </div></template><script>    export default {        data () {            return {                inputNum: '',            }        },        methods:{            inputEvent:function(){                //调用dispatch                this.$store.dispatch('inputevent',this.inputNum)            }        }    }</script>

showBox.vue 只需要将 store.js 中 state 里的初始值拿到并显示,这边 this.$store.state.inputNum 需要写在 computed 中。

<template>    <div class="showBox">        <div class="layui-form-item">            <div class="layui-input-block">              <input class="layui-input" v-model="inputNum">            </div>        </div>    </div></template><script>    export default {        data () {            return {            }        },        computed:{            //拿inputNum            inputNum () {                return this.$store.state.inputNum            }        }    }</script><style scoped>    .layui-input-block{        margin-left: 0!important;    }    .layui-input{        width: 100%!important;    }</style>

calc.vue

<template>    <div class="clacBox">        <div>            <button class="btn layui-btn" @click="increment">加1</button>            <button class="btn layui-btn" @click="decrement">减1</button>            <button class="btn layui-btn" @click="increment">乘2</button>            <button class="btn layui-btn" @click="increment">除2</button>        </div>    </div></template><script>    export default {        data () {            return {            }        },        methods:{            increment () {                //dispatch调用                this.$store.dispatch('increment')            },            decrement () {                this.$store.dispatch('decrement')            }        }    }</script><style scoped></style>

outputBox.vue 点击确认按钮,操作 store.js 中 actions 中 resultevent, 并且拿到结果值 resultNum。

<template>    <div class="inputBox">        <div class="layui-form-item">            <label class="layui-form-label">结果:</label>            <div class="layui-input-inline">              <input class="layui-input" v-model="resultNum">            </div>        </div>        <button class="btn layui-btn layui-btn-danger" @click="resultEvent">确认</button>    </div></template><script>import {mapState} from "vuex"    export default {        data () {            return {            }        },        computed:{            resultNum () {                return this.$store.state.resultNum            }        },        methods:{            resultEvent () {                this.$store.dispatch('resultevent')            }        }    }</script><style scoped>     .inputBox{        overflow: hidden;    }    .layui-form-item{        float: right;        margin-top: 15px;    }    button{        float: right;        margin-top: 15px;    }</style>

XTGL.vue 父组件

<template>    <div id="XTGLPage" class="XTGLPage">        <showBox></showBox>        <inputBox></inputBox>        <calcBox></calcBox>        <outputBox></outputBox>    </div></template><script>import showBox from "./chlidComponents/showBox.vue"import inputBox from "./chlidComponents/inputBox.vue"import calcBox from "./chlidComponents/calc.vue"import outputBox from "./chlidComponents/outputBox.vue"    export default {        name:'',        data () {            return {            }        },        components:{            inputBox,            showBox,            calcBox,            outputBox        }    }</script><style scoped>    .XTGLPage{        width: 500px;        height: 400px;        padding: 30px 20px 0;         border: 2px solid #ccc;        box-shadow: 10 10 0 0 #333;        background-color: #ccc;    }</style>

store 中 store.js 部分 完整操作是 ‘自下往上’

import Vue from "vue"import Vuex from "vuex"Vue.use(Vuex)const store = new Vuex.Store({    state:{        inputNum:'',        outputNum:'',        resultNum:''    },    mutations:{        //格式:类型(名字)+处理函数        //大写        //inputNum赋值        INPUTEVENT(state,value) {            state.inputNum += value            state.outputNum = value        },        //加        INCREMENT(state,value) {            state.inputNum += '+1'            state.outputNum++        },        //减        DECREMENT(state,value) {            state.inputNum += '-1'            state.outputNum--        },        //结果        RESULTEVENT(state){            state.resultNum = state.outputNum            console.log(state.resultNum)        }    },    actions:{        //小写        inputevent({commit},value){            commit("INPUTEVENT",value)        },        increment({commit},value){            commit("INCREMENT",value)        },        decrement({commit},value){            commit("DECREMENT",value)        },        resultevent({commit}){            commit("RESULTEVENT")        }    }}) export default store



代码比较多,文字解释待加入,先看效果图:

这里写图片描述

操作复杂度,逻辑复杂度为0,自己都尴尬的设计,希望对于学习、理解 Vuex 有些许帮助!

2 0
原创粉丝点击