当前位置: 首页 > news >正文

Vue(1)之—— Vuex学习笔记

  Vuex相当于一个商店,你可以在商店上架各种各样的商品,项目中的组件就相当于买家,他们可以购买商店中的任何商品,当一个组件买走了某样商品,那么商店中该样商品的数量就会减少一个。
  Vuex有五个核心概念,State,Getter,Mutations,Actions和Module。State,Getter和Mutations是必须的,它们的关系官网有一张图能非常清晰的说明:

  1. State(状态数据属性,数据驱动视图)
  2. Getters(获取状态中存储的值)
  3. Mutations(修改状态的唯一方法就是mutations,但mutations中的方法是同步的)
  4. Actions(Actions中方法是异步的,组件中通过dispatch触发Actions,在Actions中commit触发mutations,然后修改State)
  5. Module(分块管理相关状态)

  上图流程是这样的,你在State中声明了一个数据属性,在某个组件中引用了它,那么它就会被渲染render到这个组件,当这个组件想异步的修改这个State值时,它就需要想Actions分发dispatch某个方法,在Actions异步的触发commit Mutations中的某个方法,而只有Mutations中的被触发的这个方法才能修改State的值。

State

  在State中定义了一个count属性,之后这个count可以被项目中任意的组件所使用。

state: {
    count: 1,
}
复制代码

  获取State属性的方法有三种,第一种通过this.$store访问,后两种都是通过vuex提供的辅助函数mapState,使用它之前需要从vuex中导入。因为State中的属性是响应式的,从store实例中读取状态最简单的方法就是在计算属性中返回某个状态。

第一种方式:通过每个组件拥有的$store访问

computed:{
    count(){
        return this.$store.state.count
    }
}
复制代码

第二种方式,通过mapState访问

import {mapState} from 'vuex'

computed:mapState{
    //1.箭头函数
    count: state => state.count,
    //2.传字符串参数‘count’等同于state => state.count,counAlisa是别名,之前的都可以起别名
    countAlisa:'count',
    //3.传一个函数,在显示count值之前,还能在组件内做一些其他操作
    countLocalState(state){
      return state.count + this.num;
    }
}

//当计算属性的方法名与state中属性名同名时,就可以这样简写
computed: mapState([
  'count'
])
复制代码

第三种方式,对象的展开运算符,目的是将它与局部计算属性混合使用

computed:{
  ...mapState({
    //这里的操作与第二种方式是一样的
    count:state => state.count,
    countAlisa:'count',
    countLocalState(state){
        return state.count + this.num;
    }
  })
}

//当计算属性的方法名与state中属性名同名时,就可以这样简写
computed:{
    ...mapState([
      'count',
      'msg'
    ])
 },
复制代码

Getters

  可以认为是 store 的计算属性,可以对State中的数据做一些过滤,计算长度。在state中定义一个list列表。

state: {
    lists: [
        { id: 1, msg: "hi1" },
        { id: 2, msg: "hi2" },
        { id: 3, msg: "hi3" },
        { id: 4, msg: "hi4" },
        { id: 5, msg: "hi5" }
    ]
}

getters{
    
    //参数为state,通过属性访问
    listLength: state =>{
        return state.lists.length;
    }
    
    listFilter(state){
        return state.lists.filter(item => item.id < 4);
    }
    
    //第二个参数还可以传getters
    listFilterLength: (state, getters) => {
        return getters.listFilter.length
    }
    
    //通过函数访问
    getListById: (state) => (id) => {
        return state.todos.find(item => item.id === id)
    }
}
复制代码

  在组件中访问getters基本上与state相似,这里不过多赘述,可以参考vuex官方文档。

computed:{
    listLength(){
        return this.$store.getters.listLength
    },
    getListById(){
        return this.$store.getters.getListById(2);
}
复制代码
import { mapGetters } from 'vuex'

computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'listLength',
      'listFilterLength',
    ])
 }
复制代码

Mutations

  Mutations是改变State的唯一方法,但是它的方法必须是同步的,如果有异步操作,那么在stata中的数据可能和视图中的数值不同。

mutations: {
    addNum(state, num) {
        state.count += num;
    },
    //在mutations中做异步,在stata中的数据可能和视图中的数值不同,payload为载荷,此方式为错误示范
    addCountByasync(state, payload) {
        setTimeout(() => {
            state.count += payload.num;
        }, 1000)
    },
    addCountByasync2(state, num) {
        state.count += num;
    }
},
复制代码

  在组件内通过methods方法提交,也是有$store方式和辅助函数的方式:

methods{
    addCountByasync(){
        //1.第一个参数是事件的名字,第二个参数是传递的数据
        this.$store.commit('addCountByasync', {num: 5})
    
        //以对象方式提交
        this.$store.commit({
            type:'addCountByasync',
            num:5
        })
    },
}

复制代码

  以下的辅助函数访问方式参考vuex的官方文档

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

      // `mapMutations` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}
复制代码

Actions

  Actions的方法就是为了解决Mutations中不能做异步操作的问题,所有的异步操作放在Actions里面,只在Mutations中修改State的值。现在组件中dispatch Actions,Actions commit Mutations。

mutations: {
    addCountByasync2(state, num) {
        state.count += num;
    }
}
actions: {
    addCountByasync({ commit }, payload) {
        setTimeout(() => {
            commit('addCountByasync2', payload.num)
        }, 1000)
    }
}
复制代码

在组件内的methods中分发:

methods:{
    addCountByasync2(){
      this.$store.dispatch('addCountByasync', {num: 5})
    }
}
复制代码

Modules

  就是根据数据的业务类型分为几个模块,每个模块都有上述的四种对象,通过模块来调用,模块的用法请参考vuex手册。

vuex开发中遇到的坑

  在给State中的某个数据对象添加新属性时,无法更新到视图,需要手动设置,使得数据可以驱动视图。所以最好我们在Store中初始化好属性,不要临时添加。

state: {
    myProp: {

    }
},
getters: {
    myProp: (state) => {
        return state.myProp;
    }
},
mutations: {
    changeStateProp(state, name) {
        //这样修改数据视图是无法更新的
        // state.myProp.name = name;
        //手动设置,给State中的数据对象添加新属性
        Vue.set(state.myProp, 'name', name)
    }
},
actions: {
    changeStateProp({ commit }, payload) {
        commit('changeStateProp', payload.name);
    }
}
复制代码

某个组件内:

<h2>{{ myProp }}</h2>
<button  @click="changeStateProp">修改state数据</button>
复制代码
computed:{
    myProp(){
      return this.$store.getters.myProp
    }
},
methods: {
    changeStateProp(){
      this.$store.dispatch('changeStateProp', {name:'kitty'});
    }
}
复制代码

总结

  官网上有一段话,用来做总结:
  如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
  该笔记是听完某视频vue老师讲的课程之后做的笔记,如有侵权,请告知。

相关文章:

  • 内购掉单问题处理
  • 闲话队列
  • Linux 查看IP
  • Exchange Server无法通过脚本启用邮箱并关闭EAS功能
  • 行内元素和块级元素
  • ZFS的元数据
  • 算法不扎实的程序员,每个都很慌
  • 外媒表示大规模的恶意广告在肆虐 相关用戶恐受影响
  • KubeEdge:开源的Kubernetes原生边缘计算框架
  • PDF裁剪页面,PDF怎么裁剪页面的方法
  • Saltstack_使用指南03_配置管理
  • Python:游戏:写一个和 XP 上一模一样的“扫雷”
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 一墙之隔-看向世界和直面速度与激情
  • 金山云最新财报:Q4营收7.27亿,同比增长81%
  • Docker容器管理
  • Java方法详解
  • JS基础之数据类型、对象、原型、原型链、继承
  • Js基础知识(四) - js运行原理与机制
  • nginx 负载服务器优化
  • vue-router的history模式发布配置
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 记一次删除Git记录中的大文件的过程
  • 浏览器缓存机制分析
  • 每天10道Java面试题,跟我走,offer有!
  • 前端自动化解决方案
  • 全栈开发——Linux
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #预处理和函数的对比以及条件编译
  • (day 12)JavaScript学习笔记(数组3)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (二)pulsar安装在独立的docker中,python测试
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (十) 初识 Docker file
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (十六)一篇文章学会Java的常用API
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)【Hibernate总结系列】使用举例
  • .libPaths()设置包加载目录
  • .net core 6 集成和使用 mongodb
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • :not(:first-child)和:not(:last-child)的用法
  • @Valid和@NotNull字段校验使用
  • @vue/cli脚手架
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [Android Studio 权威教程]断点调试和高级调试