IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 十二、 Vuex 状态管理 -> 正文阅读

[JavaScript知识库]十二、 Vuex 状态管理

一、Vuex 概述

1. 官方文档:https://vuex.vuejs.org/zh/Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

2. Vuex简单理解: Vue 应用中的每个组件在 data() 中封装着自己数据属性,而这些 data 属性都是私有的,完全隔离的。 如果我们希望多个组件都能读取到同一状态数据属性,或者不同组件的行为需要更新同一状态数据属 性, 这就需要一个将共享的状态数据属性进行集中式的管理。 这就是 Vuex 状态管理所要解决的问题。

3.上面复制的,我写不出这么深刻的理解。

二、整整试试

1.先创建一个Vue项目,手动安装,vuex Router ,2.x版本然后一顿回车,哈哈哈

2.然后运行一下服务

3.面试爱问:每一个 Vuex 应用的核心就是 store(仓库)

4.在store文件下的index.js中添加?count:?0:

export default new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {},
    actions: {},
    modules: {}
})

5.然后让他在页面中显示,找到views的home.vue:

<template>
  <div class="home">
     <h1>1111</h1>
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

6.效果:

7.用{{$store.state}}来获取状态对象,

<template>
  <div class="home">
     <h1>{{$store.state.count}}</h1>
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

8.效果:

?9.我们可以改变一下这个值count,通过mutations,回到store文件下的index.js中:

 mutations: {
        increment(state) {
            state.count++
        },
        decrement(state) {
            state.count--
        }
    },

10.再回到views的home.vue:

<template>
  <div class="home">
     <h1>{{$store.state.count}}</h1>
     <button @click="add">++</button>
     <button @click="decrement">--</button>
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

11.在export?default里添加方法:

export default {
  name: "Home",
  components: {
    HelloWorld,
  },
  methods: {
    add() {

      
    },
    decrement() {},
  },
};

12.官网--可以从组件的方法提交一个变更-----this.$store.commit:

methods: {
    add() {
      this.$store.commit("increment");
    },
    decrement() {
      this.$store.commit("decrement");
    },
  },

13.现在可以实现点击++时,0++,点击--时,0--

14.就像官网所说,store当成一个仓库,然后通过在组件中去调用它的内部的方法,来实现对它的改动。

三、试试奥----mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,不能直接调用一个 mutation,需要以相应的 type 调用?store.commit?方法

1.那么,我们可不可以在其他组件中使用它呢,在views的about.vue中,

<template>
  <div class="about">
     <h1>{{ $store.state.count }}</h1>
  </div>
</template>

2.结果发现也能拿到。

3.那么,我们可不可以在添加一个新值呢,加一个n,回到store文件下的index.js中:

 mutations: {
        increment(state, n) {
            state.count += n
        },
        decrement(state) {
            state.count--
        }
    },

在回到views的home.vue:

 methods: {
    add() {
      this.$store.commit("increment",10);
    },
    decrement() {
      this.$store.commit("decrement");
    },
  },

4.结果发现也能拿到。这叫载荷,可以向?store.commit?传入额外的参数,即 mutation 的?载荷(payload)

四、Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

1.在store文件下的index.js中:

    actions: {
        dec({ commit }) {
            commit("decrement")
        },
    },

2.在组件中使用?this.$store.dispatch('xxx')?分发 action,在回到views的home.vue:

decrement() {
      // this.$store.commit("decrement");
       this.$store.dispatch('dec')
    },

3.测试可以实现减操作。

4.在Action中,结构赋值形式添加一个新值,在store文件下的index.js中:

add({ commit }) {
            commit("increment", 10)
        }

在回到views的home.vue:

 add() {
      // this.$store.commit("increment",10);
       this.$store.dispatch('add')
    },

5.测试可以实现加10操作。

6.默认形式添加一个新值,在store文件下的index.js中,把原来的add()注释上,添加:

 add(contxt) {
            contxt.commit("increment", 10)
        }

7.测试发现也可以实现加10操作。

五、?派生属性 getter

1. 理解 :

有时候我们需要从 store 中的 state 中派生出一些状态。例如:基于上面代码,增加一个 desc 属性,当 count 值小于 50,则 desc 值为 吃饭 ; 大于等于 50 小于100,则desc 值为 睡觉 ; 大于100 , 则 desc 值为 打豆豆 。这时我们就需要用到 getter 为我们解决。getter 其实就类似于计算属性(get)的对象.组件中读取 $store.getters.xxx?

2.实操

修改 store\index.js ,增加 getters 选项注意:getters 中接受 state 作为其第一个参数,也可以接受其他 getter 作为第二个参数

getters: {
        desc(state) {
            if (state.count < 50) {
                return "吃饭"
            } else if (state.count < 100) {
                return "睡觉"
            } else {
                return "打豆豆"
            }
        }
    }

修改 views\Home.vue, 显示派生属性的值:

<template>
  <div class="home">
    <h1>{{ $store.state.count }}</h1>
    <h2>{{$store.getters.desc}}</h2>
    <button @click="add">++</button>
    <button @click="decrement">--</button>
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

3.效果:

?

六、Module模块化项目结构

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter 等,参见以下代码模型?

const moduleA = { ?

state: { ... }, ? mutations: { ... }, ? actions: { ... }, ? getters: { ... }

?} ?

const moduleB = { ?

state: { ... }, ? mutations: { ... }, ? actions: { ... }

?} ?

const store = new Vuex.Store({ ? modules: { ? a: moduleA, ? b: moduleB ?} ?})

store.state.a // -> moduleA 的状态

store.state.b // -> moduleB 的状态

1.举个例子,修改 store\index.js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

let A = {
    state: {
        count: 0
    }, //存值

    // 下面都是方法
    mutations: {
        increment(state, n) {
            state.count += n
        },
        decrement(state, n) {
            state.count -= n
        }
    },
    actions: {
        dec({ commit }) {
            commit("decrement", 10)
        },
        // add({ commit }) {
        //     commit("increment", 10)
        // },
        add(contxt) {
            contxt.commit("increment", 10)
        }
    },
    getters: {
        desc(state) {
            if (state.count < 50) {
                return "吃饭"
            } else if (state.count < 100) {
                return "睡觉"
            } else {
                return "打豆豆"
            }
        }
    }
}



export default new Vuex.Store({

    modules: {
        a: A
    },

})

2.修改views\Home.vue:

<template>
  <div class="home">
    <h1>{{ $store.state.count }}</h1>
    <h2>{{$store.getters.desc}}</h2>
    <h3>{{$store.state.a.count}}</h3>
    <button @click="add">++</button>
    <button @click="decrement">--</button>
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

3.效果:

?4.为了保证变量重复的情况下也能使用,我们在index.js中引入,使它变成局部作用:

namespaced: true,

5.在home.vue中:

methods: {
    add() {
      // this.$store.commit("increment",10);
       this.$store.dispatch('a/add')
    },
    decrement() {
      // this.$store.commit("decrement");
       this.$store.dispatch('a/dec')
    },
  },

6.效果:

7.在创建一个变量B:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

let A = {
    namespaced: true,
    state: {
        count: 0
    }, //存值

    // 下面都是方法
    mutations: {
        increment(state, n) {
            state.count += n
        },
        decrement(state, n) {
            state.count -= n
        }
    },
    actions: {
        dec({ commit }) {
            commit("decrement", 10)
        },
        // add({ commit }) {
        //     commit("increment", 10)
        // },
        add(contxt) {
            contxt.commit("increment", 10)
        }
    },
    getters: {
        desc(state) {
            if (state.count < 50) {
                return "吃饭"
            } else if (state.count < 100) {
                return "睡觉"
            } else {
                return "打豆豆"
            }
        }
    }
}

let B = {
    namespaced: true,
    state: {
        count: 0
    }, //存值

    // 下面都是方法
    mutations: {
        increment(state, n) {
            state.count += n
        },
        decrement(state, n) {
            state.count -= n
        }
    },
    actions: {
        dec({ commit }) {
            commit("decrement", 10)
        },
        // add({ commit }) {
        //     commit("increment", 10)
        // },
        add(contxt) {
            contxt.commit("increment", 10)
        }
    },
    getters: {
        desc(state) {
            if (state.count < 50) {
                return "吃饭"
            } else if (state.count < 100) {
                return "睡觉"
            } else {
                return "打豆豆"
            }
        }
    }
}

export default new Vuex.Store({

    modules: {
        a: A,
        b: B
    },

})

?在home.vue:

<template>
  <div class="home">
    <h1>{{ $store.state.count }}</h1>
    <h2>{{$store.getters.desc}}</h2>
    <h3>{{$store.state.a.count}}</h3>
    <h3>{{$store.state.b.count}}</h3>
    <button @click="add">++</button>
    <button @click="decrement">--</button>
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

修改方法:

 methods: {
    add() {
      // this.$store.commit("increment",10);
      this.$store.dispatch("a/add");
      this.$store.dispatch("b/add");
    },
    decrement() {
      // this.$store.commit("decrement");
      this.$store.dispatch("a/dec");
      this.$store.dispatch("b/dec");
    },
  },

8.效果:

?七、标准项目结构

如果所有的状态都写在一个 js 中,这个 js 必定会很臃肿,Vuex 并不限制你的代码结构。但是它建议你按以下代码结构来构建项目结构:

1.?重构项目结构

1. 1在src下新建一个newStore文件夹,?在此文件夹下创建?index.js,actions.js,mutations.js和modules 目录,在该目录下创建?demo1.js?和demo2.js?

demo1.js:

let A = {
    namespaced: true,
    state: {
        count: 0
    }, //存值

    // 下面都是方法
    mutations: {
        increment(state, n) {
            state.count += n
        },
        decrement(state, n) {
            state.count -= n
        }
    },
    actions: AA,
    getters: {
        desc(state) {
            if (state.count < 50) {
                return "吃饭"
            } else if (state.count < 100) {
                return "睡觉"
            } else {
                return "打豆豆"
            }
        }
    }
}
export default A

demo2.js :

let B = {
    namespaced: true,
    state: {
        count: 0
    }, //存值

    // 下面都是方法
    mutations: {
        increment(state, n) {
            state.count += n
        },
        decrement(state, n) {
            state.count -= n
        }
    },
    actions: {
        dec({ commit }) {
            commit("decrement", 10)
        },
        // add({ commit }) {
        //     commit("increment", 10)
        // },
        add(contxt) {
            contxt.commit("increment", 10)
        }
    },
    getters: {
        desc(state) {
            if (state.count < 50) {
                return "吃饭"
            } else if (state.count < 100) {
                return "睡觉"
            } else {
                return "打豆豆"
            }
        }
    }
}
export default B

?newStore\index.js:

import Vue from 'vue'
import Vuex from 'vuex'

import A from './modules/demo1.js'
import B from './modules/demo2.js'

Vue.use(Vuex)

export default new Vuex.Store({

    modules: {
        a: A,
        b: B
    },

})

在main.js中把原来的注释上,导入新的store,也就是newStore:

import store from './newStore'

在actions.js中:

let AA = {
    dec({ commit }) {
        commit("decrement", 10)
    },
    add(contxt) {
        contxt.commit("increment", 10)
    }
}
export { AA }

2. 正常访问, 与重构前一样

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-15 11:41:41  更:2021-10-15 11:42:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:36:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码