Vue_小白个人学习历险记-Vuex的使用

135 阅读3分钟
  1. 什么是Vuex?

基础概念:Vuex是一套组件状态管理维护的解决方案

优点:

  • 完善了代码功能
  • 使Vue组件状态更容易维护
  • 为大型形目开发提供了强大的技术支持
  1. 创建第一个实例(store实例)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuex单文件引入</title>
    <script src="lib/vue.js"></script>
    <!--  1,在引入vue.js包的基础上通过<script>标签src属性引入vuex包  -->
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
<!--  4,通过this.$store.state.name插入数值  -->
    <p>{{this.$store.state.name}}</p>
</div>
<script>
    //3,通过new关键字创建store实例
    var store = new Vuex.Store({
        state:{
            name:'vuex.js直接引入'
        }
    })
    var app = new Vue({
        el:'#app',
        //2,挂在store实例
        store

    })
</script>
</body>
</html>

store中的状态是响应式的:

在使用时,组件中调用store中的状态时仅需要在计算属性中返回即可

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vuex的使用</title>
    <script src="lib/vuex.js"></script>
    <script src="lib/vue.js"></script>
</head>
<body>
<div id="app">
    <p>{{name}}</p>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            name:'Vuex.js单文件的引入'
        }
    })
    var app = new Vue({
        el:'#app',
        store,
        computed:{
            name(){
                //这里的this指的是Vue实例
                return this.$store.state.name
            }
        }
    })
</script>
</body>
</html>

mapState辅助函数:

当一个组件需要获取多个状态时,用mapState辅助函数来生成计算属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mapState辅助函数</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    {{name}}
</div>
<script>
    var store = new Vuex.Store({
        state:{
            name:'vuex.js引入'
        }
    })
    //这里需要创建mapState实例
    var mapState = Vuex.mapState
    var app = new Vue({
        el:'#app',
        store,
        computed:mapState({
            //箭头函数更加便捷
            // name(){
            //     return this.$store.state.name
            // }
            name:state => state.name
        })
    })
</script>
</body>
</html>

如何创建使用vuex的vue项目

npm安装vue脚手架   npm install vue-cli --save
    创建vue项目    vue init webpack dome1
创建完成进入demo1  cd dome1
   npm安装vuex   npm install vuex@3.1.1 --save

Vuex应用的核心:

store(仓库),即响应式仓库.用来定义应用这种数据以及数据处理工具

Vuex的状态存储:

响应式的,store中数据发生变化时,页面中store中的数据发生改变.当然改变store中状态的唯一途径是显示的提交mutation,方便跟踪每一个状态的变化

vuex实现的计算器案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mutation状态管理</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    <button @click="increament">+1</button>
    <p>{{this.$store.state.count}}</p>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            count:0
        },
        mutations:{
            //在mutations中对state中数据进行管理
            increase(state){
                return state.count++
            }
        }
    })
    var app = new Vue({
        el:'#app',
        store,
        methods:{
            //通过按钮点击触发函数
            increament(){
                //通过this.$store.commit()函数提交到mutatiom
                this.$store.commit('increase')
            }
        }
    })
</script>
</body>
</html>

Vuex状态管理模式---单向数据流机制 组件的状态变化是通过Vue单向数据流的设计理念

image.png

单行数据流组成部分主要包括:

State:驱动应用的数据源
View:以声明式的方式将state映射到视图
Actions:响应在View上的用户输入导致的状态变化

Vuex工作流程关系图(action,mutations和state的关系)

image.png

action特性:

类似于mutations,不同之处在于action异步执行 事件处理函数可以接收{commit}对象,完成mutations提交 dispath()用于完成状态分发

mutations:mutations选型中的事件处理方法接受state对象作为参数,即初始数据.在mutations中方法用来对state数据进行操作

action传递参数和mutation传递参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>action和mutation的区别</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    <button @click="action">action传参</button>
    <button @click="mutation">mutation传参</button>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            name:'张三',
            age:27,
            gender:'男'
        },
        actions:{
            test(context,params){
                //将传递参数打印输出
                console.log(params)
            }
        },
        mutations:{
            test(state) {
                console.log(state)
            }
        }
    })
    var app = new Vue({
        el:'#app',
        store,
        methods:{
            action(){
                //actions通过dispath()将参数提交到$store中的actions
                //无参函数传递
                // this.$store.dispatch('test')
                //使用payload传入参数
                // this.$store.dispatch('test','我是传递的参数')
                //action对象参数传递
                this.$store.dispatch({type:'test',name:'我是传递的参数'})
            },
            mutation(){
                //mutation通过commit()将参数提交到$store中mutations
                this.$store.commit('test')
            }
        }
    })
</script>
</body>
</html>

计算器案例通过mutations对state中数据进行改变

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算器增加案例</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    <p>{{this.$store.state.count}}</p>
    <button @click="add">+1</button>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            count:0
        },
        mutations:{
            //mutations通过方法对state数据进行管理
          increament(state){
              state.count++
          }
        },
        actions:{
            increasing(context){
                //通过参数.commit完成状态提交及参数传递给mutations
                context.commit('increament')
            }
        }
    })
    var app = new Vue({
        el:'#app',
        store,
        methods:{
            add(){
                //1,通过this.$store.dispath('')将函数传给store实例中的actions
                this.$store.dispatch('increasing')
            }
        }
    })
</script>
</body>
</html>

自定义参数传递

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mutation传递参数</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    <button @click="commit">传递参数</button>
    <p>{{this.$store.state.param}}</p>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            param:''
        },
        mutations:{
          recives(state,params) {
              state.param = params
          }
        },
        actions:{
            receive(context){
                //这里可以将组件状态和参数传递到mutations
                context.commit('recives','我是传递过来的参数')
            }
        }
    })
    var app = new Vue({
        el:'#app',
        store,
        methods:{
            commit(){
                this.$store.dispatch('receive')
            }
        }
    })
</script>
</body>
</html>

mutations同步:

同步方法是同步执行的,主要可以用来记录状态的变化,同步到页面中

  • 在调试组件状态时,mutations提交的日志信息都会被记录下来
  • 通过devtools完成前一状态和后一状态的信息记录
  • 触发mutations中的事件处理方法来更新页面状态的变化,这是一种同步状态

image.png

mutation异步回调函数:通过定时器setTimeout()实现异步的操作

mutations中setTimeout()可以实现异步操作

getters计算属性:

getters计算属性定义在store实例中,类似于Vue实例中的computed

getters获取数值方法案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>getters获取属性</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
<!--  这里利用插值语法打印store实例中的getters  -->
    <p>{{this.$store.getters}}</p>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            todos:[
                {
                    id:1,
                    text:'我已完成',
                    done:true
                },{
                    id:2,
                    text:'我未完成',
                    done:false
                }
            ]
        },
        getters:{
            doneTodos:state =>{
                return state.todos.filter(todo => todo.done)
            }
        }
    })
    var app = new Vue({
        el:'#app',
        store
    })
</script>
</body>
</html>

mutations实例应用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>getters列表查询</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    <div>
        <h2>列表查询</h2>
        <input type="text" v-model="query">
        <button @click="search">搜索</button>
    </div>
    <div>
        <p>搜索结果:{{this.$store.getters.search}}</p>
        <ul>
            <li v-for="item in this.$store.state.list">{{item}}</li>
        </ul>
    </div>
</div>
<script>
    var store = new  Vuex.Store({
        state:{
            list:[
                {
                    id:1,
                    text:'列表1'
                },{
                    id:2,
                    text:'列表2'
                },{
                    id:3,
                    text:'列表3'
                },{
                    id:4,
                    text:'列表4'
                }
            ],
            result:''
        },
        getters:{
            search:state =>{
                return state.list.filter(
                  item => item.id == state.result
                )
            }
        },
        mutations:{
            getValue(state,value){
                state.result = value
            }
        }
    })
    var  app = new  Vue({
        el:'#app',
        data:{
            query:''
        },
        store,
        methods:{
            search(){
                //实现思路,想要把输入的id值传到state中,这时我们需要通过mutations将state中数据进行更改
                this.$store.commit('getValue',this.query)
            }
        }
    })
</script>
</body>
</html>

modules

modules用来在store实例中定义模块对象

modules是store实例对象的选项

对store对象仓库进行标准化管理

modules的配置选项(与store数据仓库中的参数相同)

key:{ //key:模块名称 state,//state,初始数据 mutations,//mutations,//状态提交,同步 actions,//状态分发,异步 getters,//计算属性 modules//模块 }

image.png

modules案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>modules的使用</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">

</div>
<script>
    var modulesA = {
        state:{
            nameA:'A'
        }
    }
    var modulesB = {
        state:{
            nameB:'B'
        }
    }
    var store = new Vuex.Store({
        modules:{
            a:modulesA,
            b:modulesB
        }
    })
    var app = new Vue({
        el:'#app',
        store
    })
    console.log(store.state.a)
    console.log(store.state.b)
</script>
</body>
</html>

plugins选项:Vuex的插件配置选项为plugins,插件本身为函数

函数接收参数store对象为参数 Store实例对象的subscribe函数可以用来处理mutation 函数接收参数为mutation和state

plugins案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>plugins案例</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">

</div>
<script>
    var myPlugin = store => {
        //store初始化后调用
        store.subscribe((mutations,state) =>{
            //每次mutations提交后调用,mutations格式为{type,payload}
            console.log(mutations.type,mutations.payload)
            }
        )
    }
    var store = new Vuex.Store({
        state:{

        },
        mutations:{
            do(state){
                console.log(state)
            }
        },
        plugins:[myPlugin]
    })
    var app = new Vue({
        el:'#app',
        store,
    })
    store.commit('do','plugin')
</script>
</body>
</html>

介绍一下devtools

devtools选项用来设置是否在devtools调试工具中启用Vuex

默认值true,启动Vuex功能

常用于一个页面中存在多个Store实例的情况

模块注册

store.registerModule():store实例对象提供了动态创建模块的接口

Store.registerModule()实际案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态模块创建</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app"></div>
<script>
    var app = new Vue({
        el:'#app',
        //将Store实例挂载到vue实例中
        store
    })
    //定义Store实例
    var store = new Vuex.Store({})
    //通过store.registerModule('模块名称',{
    //  state:{
    //          name:''
    //  }
    // })
    store.registerModule('myModule',{
        state:{
            name:'我是Store.registerModule()定义的模块'
        }
    })
    document.write(store.state.myModule.name)
</script>
</body>
</html>

store.replaceState():可以通过store.replaceState()方法实现状态替换

state:数据状态管理,该方法接收新的State对象

用来在组件中展示新对象的状态

使用store.replaceState()动态改变name的初始数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>状态替换</title>
    <script src="lib/vue.js"></script>
    <script src="lib/vuex.js"></script>
</head>
<body>
<div id="app">
    <p>{{this.$store.state.name}}</p>
</div>
<script>
    var store = new Vuex.Store({
        state:{
            name:'我是初始数据'
        }
    })
    store.replaceState({
        name:'我是替换后的state数据'
    })
    var app = new Vue({
        el:'#app',
        store
    })
</script>
</body>
</html>