Tracy 小笔记 Vue - Vuex

9 篇文章 1 订阅

Vuex

  • 它是一个插件,提供了一个全局对象,并且这个对象可以实现响应式更新
    Vuex 使用单一状态树(Single Source of Truth: 也可叫单一数据源)来管理应用层的全部状态
  • 一般什么情况下应用?
    • 用戶的登入状态
    • 用户名称、头像、地理位置等信息
    • 商品的收藏、购物车中的物品
  • 它是一个插件,因此需要安装 npm install vuex
  • 它要存在 src 下的 store 文件夹 index.js 文件
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    //1.安装插件
    Vue.use(Vuex)
    
    const moduleA = {
      state: {counter: 66},
      mutations: {},
      actions: {},
      getters: {}
    }
    
    //2.创建对象
    const store = new Vuex.Store({
      state: { //这里放置全局变量
        counter: 5,
        students: [
          { name: "Tracy1", age: "11" },
          { name: "Tracy2", age: "21" },
          { name: "Tracy3", age: "31" },
        ],
        info: { name: '11', value: '22' }
      },
      mutations: {
        increaseCounter(state) { //这里的 state 是自动获取的
          state.counter++;
        }
      },
      actions: {
        addPropTimeOut(content) {
          setTimeout(() => {
            content.commit('addProp'); //action 只调用异步,真正修改对象的值还是得像这样调用 mutation 中的方法
          }, 3000);
        },
      },
      getters: {
        doubleCounter(state) {
          return state.counter * 2;
        }
      },
      modules: {
        a : moduleA,
      }
    });
    //3.导出 store 
    export default store
    
    
  • main.js 添加 code
    import store from './store'
    并且将 store 和 router 一样挂载在 Vue 实例中
    new Vue({
      el: '#app',
      router,
      store,
      render: h => h(App)
    })

  • Vuex 状态管理图例

这个图的一些解释

  • Vue components : 我们的组件树
  • State: 放我们各种数据的,任何组件都可以直接显示这个 State (eg:$store.state.name)
  • Mutations: 比如一个按钮点击的时候,调佣一个 mutation 里的函数,在这个函数里去修改 State 中的数据(如果在组件中直接更改全局变量的值:不通过Mutation,这个值也可以硬改,但是 Devtools 就监听不到了,不利于大型项目的追踪和维护)
  • Actions: 如果在本次提交的时候有一些异步的数据(比如网络请求)就需要在 Action 中处理,因为 Mutations 中是不可以处理异步请求的,这里和 Backend API (后端的一些接口)请求一些数据
  • Devtools 是 Vue 开发的一个浏览器插件,可以监听 Vuex 中全局变量的动态变化
Devtools 的安装

vue其实提供了一个devtools,方便我们对组件或者vuex进行调试:
我们需要安装beta版本支持vue3,目前是6.0.0 beta15;
它有两种常见的安装方式:
方式一:通过chrome的商店;

Chrome 添加扩展程序 : 打开 Chrome 网上应用商店 搜 devtool : 安装 Vue.js devtools

 


方式二:手动下载代码,编译、安装;

去 github 搜索 vue devtool

 或者直接打开下载:https://github.com/vuejs/devtools/tree/v6.0.0-beta.15

不推荐直接下载,我们找到 tag 找到这个版本来下载

 执行 yarn install 安装相关的依赖;

执行 yarn run build 打包;

打包之后回到浏览器 加载已解压的扩展程序,我们要找的文件夹就是:packages\shell-chrome

安装之后再控制台 “console” 那行会多出来一个 “Vue”

还要在浏览器右上角点亮它

 一个网站如果是 vue 开发的话 它就会亮起来

用了这个 tool 就可以看到插件的监听了,它会显示在什么时间,哪个全局变量被改成了什么

左边是组件,右边是组件里的各种状态

 想看 vuex 的话 切换这里

如果在使用中发现报错this.$store.commit is not a function ,请打开你项目的配置文件package.json,查看你正在使用的vuex的版本,我正在使用的是vuex2.0,如果想删除旧版本的vuex并安装新版本的vuex
请使用
npm rm vuex --save
然后安装最新的vuex
npm install vuex --save
即可解决这个错误,或者是查看vuex官网api修改提交mutation的语句

Vuex 核心概念

  • Vuex 对象中有几个比较核心的概念
    const store = new Vuex.Store()
  • State: 变量存储的地方
    页面直接显示{{$store.state.counter}}

    如果觉得这个写法有点长,那么我们可以使用一个辅助函数 mapState
  • / vue2 用法 options API
    
    import {mapState} from 'vue'
    
    
    1.数组写法 
    html 调用原来的名字 {{counter}}, {{userInfo}},{{conference}}
    
    computed:{
        ...mapState(["counter","userInfo", "conference"])
    }
    
    // ... 展开运算符,相当于我们目前有了 三个计算属性
    
    
    
    2.对象写法(可以重命名)
    html 调用新的名字 {{counterNew}}, {{userInfoNew}},{{conferenceNew}}
    computed:{
    
        ...mapState({
            counterNew:state => state.counter,
            userInfoNew:state => state.userInfo,
            conferenceNew:state => state.conference,
        })
    
    }
    
     Vue3 用法 setup 函数
    
    html 调用新的名字 {{sCounter}}
    
    
    import {mapState, useStore} from 'vue'
    import {computed} from 'vue'
    
    export default {
    setup(){
    
        // setup 函数是没有 this 的,因此这里是不能用 $this.store.state 调用vuex中的变量的
    
       const store = useStore; // 拿到 store
       const sCounter = computed(()=>store.state.counter)
    
        return {
            sCounter,
        }
    
    }
    }




     
  • Getters:就相当于计算属性,就是让 State 里的参数经过一系列变化展示到页面上而不改变参数本身的数据
    • Getter 调用: 页面直接显示 getter 中返回的变量 {{$store.getters.doubleCounter}}
    • Getter 设置
        daican(state) { //带参数返回一个带参数的函数即可
          return data => {
            return state.counter * data;
          }
        },
        ageMoreThan(state) { //返回年纪大于 age 的学生
            return age => {
              return state.students.filter(s => s.age >= age);
            }
          },
        ageMoreThanLength(age, getters) { //返回年纪大于 data 的学生的数量
          //这里涉及到getter 函数之间是如何调用的
          return age => {
            return getters.ageMoreThan(age).length;
          }
        }
      Getter 调用 : {{$store.getters.daican(5)}} //带参数的
    getters.js 可以自己单出来一个 js 文件,写法和引入方法参考 mutations.js
    getter 里的方法如果在某一个页面想要直接调用 {{daican(5)}}{{别名1(5)}},可以在调用的页面如此引用
    import {mapGetters} from "vuex" (mapGetter 辅助函数)
    然后在 computed 中写
    ...mapGetters(['daican','ageMoreThan']);//调用哪个写哪个
    或者 ...mapGetters({别名1:'daican', 别名2:'ageMoreThan'});
  • MutationVue Store 状态唯一的更新方式
    Vue 要求我们在 mutation 中的方法必须是同步方法 主要的原因是当我们使用追踪插件的时候用异步方法会失效。 也就是说有网络请求的时候不能在 mutation 中写
    更新变量的时候一定要在这里更新,在外面是能直接更新但是一旦在外面更新 vue 自带的追踪插件就会失效,程序小还可以,大型项目中就很不利于调试了。
    • Mutation 设置 : 这里的 state 是自动获取的,买个 mutation 函数都带这个默认的参数
      increaseCounter(state) { 
            state.counter++;
          }
      
      Mutation 调用: this.$store.commit('increaseCounter');
    • Mutation 设置 : 传参数 num
          decreaseCounter(state, num) {
            state.counter -= num;
          },
         
      Mutation 调用: this.$store.commit('decreaseCounter', 3);
    • Mutation 设置 : 传参数 payload 对象
      decreaseCounter1(state, payload) { 
            state.counter -= payload.num;
          },
      Mutation 调用 (另外一种调用方法): this.$store.commit({ type:"decreaseCounter1", num: 3 });
    • Mutation 设置: 给对象响应式的添加属性
          addProp(state) { 
            state.info = { ...state.info, 'newProp': 1 }
          }

    mutations-type.js
    • 在 mutation 定义了很多时间类型:也就是方法名称
    • 项目越来越大的时候,方法越来越多,所以可以创建一个 mutations-type.js 在单独管理 mutations 中的方法名
    • 使用方式:
      mutations-type.js 中写: export const INCREASECOUNTER = 'increaseCounter'
      然后 store/index.js 中要引入: import {INCREASECOUNTER} from "./mutations-type.js"
      原来的方法: increaseCounter(state) {} 现在就变成了 [INCREASECOUNTER](state) {},
      这里需要了解的知识是一个方法可以有这样两种书写方式 a(){} 和 ['a'](){}

      前端页面调用方法的时候就这样写: this.$store.commit(INCREASECOUNTER);
    mutations.js
    • mutations 可以自己单出来一个 js 文件
    • 如果有 mutations-type.js, 就先引入 import {想要引入的变量名1, 变量名2....} from "./mutations-type.js"
    • export default { 里面是各种方法}
    • index.js 中写 import mutations from './mutations.js'
  • Action: Action 类似于 mutation, 它是用来代替 mutation 进行异步操作的;如网络请求
     或者说一些复杂的逻辑也是在 Action 里写,尽量让 mutation 只执行最简单的操作,不涉及到任何逻辑判断
  • Action 设置: content参数代表上下文,每个 action 都带这个默认参数
    • addPropTimeOut(content) { 
            setTimeout(() => {
              content.commit('addProp'); //action 只调用异步,真正修改对象的值还是得像这样调用 mutation 中的方法
            }, 3000);
          },
      Action 调用 :this.$store.dispatch('addPropTimeOut');
    • Action 设置:返回 new Promise
      addPropTimeOutWithPromise(content) { 
            return new Promise((resolve, reject) => {
              setTimeout(() => {
                content.commit('addProp');
                resolve("往外带参数外面的 res 来接这个参数"); //Promise 成功后执行
              }, 3000);
            })
          },
      Action 调用:带参数 this.$store.dispatch('addPropTimeOutWithPromise').then(res =>{console.log(res, "new Promise");});
    • Action 设置
      addPropTimeOutWithParas(content, payload) { 
            setTimeout(() => {
              content.commit('addProp');
            }, payload);
          },
      Action 调用 this.$store.dispatch('addPropTimeOutWithParas', 1000);
    • Action 设置:带参数,参数是一个对象
      addPropTimeOutWithCallback(content, payload) { 
            setTimeout(() => {
              content.commit('addProp');
              console.log(payload.message);
              payload.success();
            }, 3000);
          }
      Action 调用:this.$store.dispatch('addPropTimeOutWithCallback', { message:"携带的参数", success:() => {console.log('属性添加完毕')} });
    actions.js 可以自己单出来一个 js 文件,写法和引入方法参考 mutations.js
    actions 函数的另外一个调用方式:辅助函数
    在想要调用的文件中 import { mapActions } from 'vuex'
    methods:{
        ...mapActions(['addToCart']), //mapActions 辅助函数,直接用 vueX 中 Action 的函数
        addGood(good) {
                this.addToCart(good);
            },
    }
  • Module: 模块, 当 应用非常复杂的时候,所有东西都存在一个 store 里不方便管理。 此时 Vuex 允许我们将 store 对象分割成模块,每个模块有自己的 state,mutation,action, getter 等
    这里的 action、mutation 和 getter 是注册在全局的,因此调用方式都是一样的,并且是不能重名的。
    state 是可以重名的
    • 前台调用 module a 中的 state : {{$store.state.a.counter}}
    • module a 中的 getters 中的 方法调用 root store 中的 State
      fullName3(statem getters, rootState){
                      return getter.fullname2 + rootState.counter
                    }
                    //这里的 fullname2 是本 module 中 getter 中的方法
                  
    • module a 中的 Actions 中的方法调用 root store 中的 State
                    incrementRoom({state, commit, rootState}){
                      if(state.count + rootState.count > 10) {commit('increment')}
                    }
                  
    moduleA.js 可以自己单出来一个 js 文件,写法和引入方法参考 mutations.js
  • 等 action, getter, mutation 等都变成单独的文件之后
    index.js 中的 写法就特别简单了,先各自引入,然后
    const state = { ...//state 不要自己写单独的文件,直接提出来单独的对象即可}
    
      const store = new Vuex.Store({
      state,
      mutations,
      actions,
      getters,
      modules: {
        a : moduleA,
      }
    });
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js是一个流行的JavaScript框架,它允许您构建动态Web应用程序。Vuex是一个专为Vue.js应用程序开发的状态管理模式。它允许您在应用程序中管理和维护状态,例如用户信息、购物车、主题等。Vuex将状态存储在一个集中的存储库中,称为store。Vuex的核心概念包括state、mutations、actions和getters。 - state:存储应用程序级别的状态,可以通过store.state访问。 - mutations:用于更改状态的函数,必须是同步函数。可以通过store.commit方法调用。 - actions:用于处理异步操作的函数,可以包含任意异步操作。可以通过store.dispatch方法调用。 - getters:用于从store中获取状态的函数,可以通过store.getters访问。 下面是一个简单的示例,演示如何在Vue.js应用程序中使用Vuex: 1.安装Vuex ```shell npm install vuex --save ``` 2.创建store ```javascript import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } }, getters: { getCount: state => { return state.count } } }) export default store ``` 3.在Vue组件中使用store ```javascript <template> <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="incrementAsync">Increment Async</button> </div> </template> <script> import { mapGetters, mapActions } from 'vuex' export default { computed: { ...mapGetters([ 'getCount' ]) }, methods: { ...mapActions([ 'increment', 'incrementAsync' ]) } } </script> ``` 在上面的示例中,我们创建了一个名为count的状态,并定义了一个名为increment的mutation和一个名为incrementAsync的action。我们还定义了一个名为getCount的getter,用于从store中获取count状态。在Vue组件中,我们使用mapGetters和mapActions帮助程序将getter和action映射到组件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值