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

介绍

作用

方便组件通信, 状态管理模式(管理共享数据用的)

Vuex是采用集中式管理组件依赖的共享数据的一个工具, 可以解决不同组件数据共享的问题

项目当中引入 vuex

  1. 下载包 npm i vuex@3

    根据vue版本下载对应版本的vuex, 最新版的vuex仅支持vue3, 不支持vue2

  2. 配置项目 main.js

    import Vue from 'vue'
    import App from './App.vue'
    
    Vue.config.productionTip = false
    
    // 引入 vuex 的写法
    // 1. 引入库
    import Vuex from 'vuex'
    // 2. 安装
    Vue.use(Vuex)
    // 3. 创建仓库示例
    const store = new Vuex.Store()
    
    new Vue({
      // 4. 挂载new Vue 示例上
      store: store,
      render: h => h(App),
    }).$mount('#app')
    

概念一 state

state是放置所有公共状态的属性,如果你有一个公共状态数据 , 你只需要定义在 state对象中

1.创建state

const store = new Vuex.Store({
  // 配置对象
  // state 储存数据
  state: {
    count: 0,
    name: '小明',
    token: '123abc'
  }
})

2.使用

组件中可以使用 this.$store 获取到vuex中的store对象实例,可通过state属性属性获取count

 <div>
      插值表达式: 
      {{$store.state.count}} 
      {{$store.state.name}} 
      {{$store.state.token}}
    </div>

3.优化方案

<template>
  <div>
    <div>
      计算属性封装 {{name}}
    </div>
  </div>
</template>

<script>
export default {
  // 如果觉得模板中每次都写完整的state路径非常麻烦
  // 可以封装到计算属性当中, 
  // 1. 它本身是作为数据渲染 
  // 2. 他可能后续会改变
  computed: {
    name() {
      return this.$store.state.name
    }
  }
}
</script>

4.vuex 自带辅助函数用法

第一步引入方法 mapState

第二步在计算属性中通过延展运算符调用数据

第三步直接插值表达式渲染

<template>
  <div>
    <div>
      计算属性封装 {{name}} {{count}} {{token}}
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
// console.log(mapState(['count', 'name', 'token']));
export default {
  // 如果觉得模板中每次都写完整的state路径非常麻烦
  // 可以封装到计算属性当中, 
  // 1. 它本身是作为数据渲染 
  // 2. 他可能后续会改变
  computed: {
    ...mapState(['count', 'name', 'token']),
    // 相当于生成了以下三个函数
    // ...{count: ?, name: ?, token: ?},
    // name() {
    //   return this.$store.state.name
    // },
    // count() {
    //   return this.$store.state.count
    // },
    // token() {
    //   return this.$store.state.token
    // }
  }
}
</script>

<style>

</style>

概念二 mutations

mutations是一个对象,对象中存放修改state的方法

1.创建mutations

const store = new Vuex.Store({
  strict: true,
  // 配置对象
  // state 储存数据
  state: {
    count: 0,
    name: '小明',
    token: '123abc'
  },
  // 所有的变更都需要放在 mutations 里面
  mutations: {
    addCount(state) {
      // 这个函数被调用时默认会自动带上当前state对象
      state.count++
    }
  }
})

2.使用

<template>
  <div>
    <div>
      计算属性封装 {{name}} {{count}} {{token}}
    </div>
    <!-- <button @click="$store.state.count ++">直接增加</button> -->
    <button @click="$store.commit('addCount')">mutations增加</button>
  </div>
</template>

传参的用法

  mutations: {
    addCount(state, payload) {
      // 第二个参数可以用来传参, 调用commit时也在第二个参数放入即可
      // 这个函数被调用时默认会自动带上当前state对象
      state.count += payload
    }
  }

3.优化

注意, 由于mutations是要被执行的函数所以封装在 methods 里面

<template>
  <div>
    <!-- <button @click="$store.state.count ++">直接增加</button> -->
    <button @click="addCount(666)">mutations增加666</button>
    <button @click="addCount(888)">mutations增加888</button>
    <button @click="addCount(10)">mutations增加10</button>
  </div>
</template>

<script>
import { mapState } from 'vuex'
// console.log(mapState(['count', 'name', 'token']));
export default {
  methods: {
    addCount(data) {
      this.$store.commit('addCount', data)
    }
  }
}
</script>

4.辅助函数

<template>
  <div>
    <div>
      计算属性封装 {{name}} {{count}} {{token}}
    </div>
    <!-- <button @click="$store.state.count ++">直接增加</button> -->
    <button @click="addCount(666)">mutations增加666</button>
    <button @click="addCount(888)">mutations增加888</button>
    <button @click="addCount(10)">mutations增加10</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'
export default {
  computed: {
    ...mapState(['count', 'name', 'token'])
  },
  methods: {
    ...mapMutations(['addCount'])
    // 他可以自动生成以下的函数
    // addCount(data) {
    //   this.$store.commit('addCount', data)
    // }
  }
}
</script>

<style>

</style>

概念三 actions

state是存放数据的,mutations是同步更新数据,actions则负责进行异步操作

actions 是一个对象,对象中存放着方法

1.创建

const store = new Vuex.Store({
  strict: true,
  // 配置对象
  // state 储存数据
  state: {
   //...
  },
  // 所有的变更都需要放在 mutations 里面
  mutations: {
    //...
  },
  actions: {
    asyncAddCount(store, payload) {
      // actions 的函数由于默认不能直接修改state
      // 需要调用 mutations 所以第一个接到的参数是当前仓库的 store 本身
      // 可以直接当做组件内 的 this.$store 来使用
      setTimeout(() => {
        store.commit('addCount', payload)
      }, 2000);
    }
  }
})

2.使用

<template>
  <div>
    <button @click="$store.dispatch('asyncAddCount', 10)">异步修改state</button>
  </div>
</template>

3.封装

<template>
  <div>
    <button @click="asyncAddCount(10)">异步修改state</button>
  </div>
</template>

<script>
export default {
  methods: {
    asyncAddCount(data) {
      this.$store.dispatch('asyncAddCount', data)
    }
  }
}
</script>

<style>

</style>

4.辅助函数

<template>
  <div>
    <button @click="asyncAddCount(10)">异步修改state</button>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from 'vuex'

export default {

  computed: {
    ...mapState(['count', 'name', 'token']),
  },
  methods: {
    ...mapMutations(['addCount']),
    ...mapActions(['asyncAddCount'])
  }
}
</script>

<style>

</style>

概念四 getters

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters

1.创建

const store = new Vuex.Store({
  strict: true,
  state: {
    count: 0,
    list: [1,2,3,4,5,6,7,8,9,10,666,777,888]
  },
  // 能够派生出一个数据是list经过过滤返回所有大于5的数据
  getters: {
    // 每个属性都是一个函数
    // 默认第一个接收到的就是当前的 state 对象供我们进行数据的计算
    // filterList(state) {
    //   return state.list.filter(item=>item>5)
    // }
    filterList: state => state.list.filter(item=>item>5)
  }
})

2.使用

<template>
  <div>
    <!-- 基本用法 {{$store.getters.filterList}} -->
    {{filterList}}
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['filterList'])
    // 也可以手动封装函数
    // filterList() {
    //   return this.$store.getters.filterList
    // }
  }
}
</script>

<style>

</style>

3.常见用途(简化数据获取)

const store = new Vuex.Store({
  strict: true,
  state: {
    student: {
      name: '小明',
      school: {
        name: '吉山幼儿园',
        address: '珠吉路58号'
      }
    }
  },
  // 能够派生出一个数据是list经过过滤返回所有大于5的数据
  getters: {
    address: state => state.student.school.address
  }
})
<template>
  <dv>
    学校地址: {{$store.getters.address}}
  </div>
</template>

概念五modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象 state 当中。当应用变得非常复杂时,就有可能变得相当臃肿。Vuex会变得越来越难以维护, 由此,又有了Vuex的模块化

1.创建模块

const store = new Vuex.Store({
  strict: true,
  // state,
  // mutations,
  // actions
  modules: {
    // 每个属性都是一个模块对象
    user: {
      state: {
        token: 666
      }
    },
    setting: {
      state: {
        name: 'vuex 演示示例'
      }
    }
  }
})

2. 在模块状态下如何使用 state

<template>
  <div>
    <div>用户token {{$store.state.user.token}}</div>
    <div>设置name {{$store.state.setting.name}}</div>
  </div>
</template>

3.默认如何使用 mutations / actions

默认情况下 mutations / actions / getters 都是在全局使用

const store = new Vuex.Store({
  strict: true,
  // state,
  // mutations,
  // actions
  modules: {
    // 每个属性都是一个模块对象
    user: {
      state: {
        token: 666
      },
      mutations: {
        setToken(state) {
          state.token = 777
        }
      }
    },
    setting: {
      state: {
        name: 'vuex 演示示例'
      },
      mutations: {
        setName(state) {
          state.name = '我的测试页面'
        }
      }
    }
  }
})
<template>
  <div>
    <div>
      <button @click="$store.commit('setToken')">改token</button>
      <button @click="$store.commit('setName')">改name</button>
    </div>
    <div>用户token {{$store.state.user.token}}</div>
    <div>设置name {{$store.state.setting.name}}</div>
  </div>
</template>

5.namespaced设置高封闭性

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

意思是刚才的user模块还是setting模块,它的 action、mutation 和 getter 其实并没有区分,都可以直接通过全局的方式调用

如果我们想保证内部模块的高封闭性,我们可以采用namespaced来进行设置高封闭性

可以理解成 一家人如果分家了,此时,你的爸妈可以随意的进出分给你的小家,你觉得自己没什么隐私了,我们可以给自己的房门加一道锁(命名空间 namespaced),你的父母再也不能进出你的小家了

const store = new Vuex.Store({
  strict: true,
  // state,
  // mutations,
  // actions
  modules: {
    // 每个属性都是一个模块对象
    user: {
      // 希望提高封闭性,
      // 独立使用这个模块
      namespaced: true,
      state: {
        token: 666
      },
      mutations: {
        setToken(state) {
          state.token = 777
        }
      }
    },
    setting: {
      // ...
    }
  }
})

6.如何使用带命名空间的模块

1.基本的使用方式

调用时带上 模块名/ 即可

<template>
  <div>
    <div>
      <!-- <button @click="$store.commit('setToken')">改token</button> -->
      <button @click="$store.commit('user/setToken')">改token</button>
      <button @click="$store.commit('setName')">改name</button>
    </div>
    <div>用户token {{$store.state.user.token}}</div>
    <div>设置name {{$store.state.setting.name}}</div>
  </div>
</template>
2.使用辅助函数的方法

辅助函数,其实可以再第一个参数中, 放入一个可选的字符串作为模块名

<template>
  <div>
    <div>
      <!-- <button @click="$store.commit('setToken')">改token</button> -->
      <button @click="setToken">改token</button>
      <button @click="setName">改name</button>
    </div>
    <div>用户token {{$store.state.user.token}}</div>
    <div>设置name {{$store.state.setting.name}}</div>
  </div>
</template>

<script>
import {mapMutations} from 'vuex'
export default {
  methods: {
    ...mapMutations(['setName']),
    // 如果带有命名空间, 可以第一个参数加入一个可选的模块名字符串
    ...mapMutations('user', ['setToken'])
  }
}
</script>

<style>

</style>
3.创建基于模块的辅助函数方式
<template>
  <div>
    <div>
      <!-- <button @click="$store.commit('setToken')">改token</button> -->
      <button @click="setToken">改token</button>
      <!-- <button @click="setName">改name</button> -->
    </div>
    <div>用户token {{$store.state.user.token}}</div>
    <div>设置name {{$store.state.setting.name}}</div>
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
// import {mapMutations} from 'vuex'
// 默认情况下 mapMutations 是基于全局命名空间, 所以创建出来的函数也是全局有效
const {mapMutations} = createNamespacedHelpers('user')
export default {
  methods: {
    // ...mapMutations(['setName']),
    // 如果带有命名空间, 可以第一个参数加入一个可选的模块名字符串
    // ...mapMutations('user', ['setToken'])
    ...mapMutations(['setToken'])
  }
}
</script>

<style>

</style>

7.补充:如何使用 getters

一般是写在 modules 外部全局定义, 为的是可以获取到所有子模块的数据, 帮助简化数据的读取

const store = new Vuex.Store({
  strict: true,
  // state,
  // mutations,
  // actions
  modules: {
    // 每个属性都是一个模块对象
    user: {
      // ...
    },
    setting: {
      // ...
    }
  },
  // 一般不会将 getters 写到模块内
  // 因为在模块内如果要读取 state 每次都要点模块名点字段名
  // 写在 modules 外部的 getters 有一个特性 是他的 state 可以得到所有模块的数据
  getters: {
    token: state => state.user.token,
    name: state => state.setting.name
  }
})
<template>
  <div>
    <div>用户token {{token}}</div>
    <div>设置name {{name}}</div>
  </div>
</template>

<script>
import {mapGetters} from 'vuex'
export default {
  computed: {
    ...mapGetters(['token', 'name'])
  }
}
</script>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:07:38  更:2022-06-01 15:09:58 
 
开发: 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 17:19:27-

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