Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。因为我们是MVVM框架,view取决于我们model(数据),view如何展示称为元素状态,那么model数据也就是状态数据。
vuex是基于flux设计原理实现的一个单向数据流状态管理器,但他不是唯一的状态管理器,还有个pinia
管理状态数据的库
全局数据:
全局变量会导致全局数据污染,所以vuex一定是一个闭包
集中式存储管理应用的所有组件的状态
实现数据共享:简化Vue组件间通讯,可跨组件(子传父、父传子)
eventBus:两个组件必须同时存在,并且监听要早于触发:数据不会缓存
provide+inject:修改数据不能在子组件中进行,可以用computed缓存
父子传子:不能跨组件传值,只能是父子关系才可以
数据可预测化:使用发布订阅机制来实现;保证状态以一种可预测的方式发生变化(有序进行数据存储获取)
页面状态管理容器对象。集中存储Vue components状态数据
定义和初始化全局需要托管的数据,因为托管的数据是状态,所以这个属性是state
修改数据/扭转状态数据
状态改变操作方法,由actions中的commit(‘mutation 名称’)来触发。
是Vuex修改state的唯一推荐方法。该方法只能进行同步操作,且方法名只能全局唯一。
因为异步函数,什么时候结束,不清楚,但是setToken方法执行以后,会立刻发布更新消息,那么这样,发布出去的消息有问题,数据更新还没有执行完成。
而且flux设计原理,规定mutation必须为一个纯函数--输出必须完成依赖输入,不能修改外部数据
状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。
是一个提交数据的方法
操作行为处理模块,执行数据处理的动作属性。这个动作不可以修改数据,因为修改数据只能在mutations可以。所以它获取到异步数据后需要一个commit方法进行数修改。
actions可以定义异步任务,由组件中的$store.dispatch('action 名称', data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。
操作行为触发方法,是唯一能执行action的方法。
state对象读取方法,取数据。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。
getters和state是两个不同的模块,所以数据不能共享,那么只有这个方法把值传递进来
getters是获取数据的getter方法
因为getter方法传递给vuex以后,他还需要加工,所以可以把state传递进来
this.$store中只有三个属性可用:getters、commit、dispatch,其他都是 _ 开头的私有属性
getters是获取数据的getter方法
commit提交数据,定义接口commit('type提交给这个方法中去',提交的数据),是一个提交数据的方法
dispatch调遣/派遣一个动作,即actions
1.下载安装
- npm install vuex@4.0.2 --save
- npm install vuex@next --save
2.在src下的main.js引入、注册
- //src/main.js
- import { createApp } from 'vue'
- import App from './views/index.vue'
- import Vuex from 'vuex'
- //Store这个方法/类执行以后会得到一个Store实例
- const store = new Vuex.Store({
- state:{//定义和初始化全局需要托管的数据,因为托管的数据是状态,所以这个属性时state
- token: 100,
- userInfo: {}
- },
- getters:{
- mytoken(_state) {
- return _state.token
- },
- userInfo: _state => _state.userInfo
- },
- // 执行数据处理的动作属性中去执行--dispatch方法--调遣、派遣一个动作
- actions: {
- // 这个动作没有办法执行数据修改,因为数据修改只有mutations可以,所以它获取到异步数据以后需要一个commit方法进行数据修改
- async getUserInfo(_store, id) {
- let result = await ajax(id)
- _store.commit('setUserInfo', result)
- }
- },
- mutations: {
- setToken(_state, _token) {
- // 修改的是state的数据,这里没有state对象,那么只有这个方法把state传递进来
- // 第二个参数才是我们传递的数据
- _state.token = _token
- },
- setUserInfo(_state, _userInfo) {
- console.log('----------------- 赋值', _userInfo)
- _state.userInfo = _userInfo
- }
- }
-
- })
- // 也需要注入store
- createApp(App).use(store).mount('#root')
3.主页 views/index.vue 获取后显示值
- //views/index.vue
- <template>
- <div class="box">
- <h3>系统的名字h3>
- <p>
- 当前的token值:{{$store.getters.mytoken}}
- p>
- <Home/>
- div>
- template>
- <script>
- import Home from './Home.vue'
- export default {
- components: { Home },
- created() {
- console.log(this.$store.getters.mytoken)
- }
- }
- script>
4.首页 主页的子组件 src/views/Home.vue 修改上面首页token的值 commit(传递值)
- //src/views/Home.vue
- <template>
- <div class="box">
- <hr>
- <h4>首页 -- 欢迎您 -- {{name}}h4>
- <p>
- <button @click="changeToken">修改token数据button>
- p>
- <Child/>
- div>
- template>
- <script>
- import Child from './Child.vue'
- export default {
- components: { Child },
- computed: {
- name() {
- // console.log('userInfo-----',this.$store.getters.userInfo);
- return this.$store.getters.userInfo.name
- }
- },
- methods: {
- changeToken() {
- let value = this.$store.getters.mytoken
- this.$store.commit('setToken', value + 1)
- }
- }
- }
- script>
5.首页子组件 传递值给首页的欢迎您
- //src/views/Child.vue
- <template>
- <div class="box">
- <hr>
- <h5>这里是Home的子组件h5>
- <p>
- 名字: <input v-model='myname' type="text">
- p>
- <p>
- <button @click="asyncFunc">异步请求数据修改button>
- p>
- div>
- template>
- <script>
- export default {
- data() {
- return {
- myname: ''
- }
- },
- methods: {
- asyncFunc() {
- this.$store.dispatch('getUserInfo', this.myname)
- }
- }
- }
- script>
npm install vuex@4.0.2 --save 或 npm install vuex@next --save
- import {createStore} from 'vuex' //引入vuex,解构createStore
- const store = createStore({ //使用createStore
- state:{ //状态
- count:0 //状态数据
- },
- mutations:{ //方法
- //state:状态,第二个及以后的参数是传入的参数用逗号隔开
- PLUS(state,user){ //大写_大写
- state.count++
- //stare.count = user
- },
- MINUS(state){
- state.count--
- }
- },
- actions:{ //方法
- plus({commit}){ //commit方法调用
- commit('PLUS') //mutations下的方法名
- },
- minus({commit}){
- commit('MINUS')
- }
- },
- getters:{ //获取值
- num:(state)=>state.count
- }
- })
- export default store
- import { createApp } from 'vue'
- import App from './App.vue'
- import router from './router'
- import store from './store' //store文件下的store
- const app = createApp(App)
- app.use(router)
- app.use(store) //集成
- app.mount('#app')
- <template>
- <div>
- <p>显示vuex状态count : {{num}}p>
- <button type="button" @click="onPlus">加一button>
- div>
- template>
- <script>
- export default {
- //methods - 创建方法
- methods:{
- onPlus(){ //actions里的定义的名字,
- this.$store.dispatch('plus',参数) //调用方法.将参数传回store
- }
- },
- computed:{
- num(){
- return this.$store.getters.num
- }
- }
- }
- script>
mapGetters 直接获取getters值
mapActions 直接操作行为处理
下载、创建、引入集成与前面一样 ,使用方法有些不同
1.在组件里引入 .vue
- <script>
- import { mapGetters,mapActions } from 'vuex' //引入
- script>
- <template>
- <div>
- <p>显示vuex状态count : {{ num }}p>
- <button type="button" @click="minus">减一button>
- div>
- template>
2.使用 .vue
- export default {
- data() {
- return {}
- },
- //methods - 创建方法
- methods: {
- // onMinus() {
- // this.$store.dispatch('minus')
- // }, 上下实现的效果一样
- // ...mapActions({
- //计算属性名: vuex中actions定义名称
- // onMinus:'minus'
- // }) 计算属性名随意取,如果和actions名一样就用下面这个方式
- ...mapActions(['minus']) //当计算属性名和vuex中getters定义名称相同时,使用如下方式实现
- },
- computed: {
- // num(){
- // return this.$store.getters.count
- // },
- // ...mapGetters({
- //计算属性名: vuex中getters定义名称
- // num:'count'
- // })
- ...mapGetters(['num']),
- },
- }
npm install vuex-persistedstate --save
该插件默认持久化所有state,当然也可以指定需要持久化的state:
- import { createStore } from 'vuex'
- import createPersistedState from 'vuex-persistedstate' //引入持久化 哪个vue需要持久化就在哪里引入
- const store = createStore({
- plugins: [
- createPersistedState({
- storage: window.sessionStorage, //默认 修改存储的状态
- key: 'userkey', //上下两个可以不写 默认key为vuex
- reducer(data) {
- return {
- // 设置只储存state中的myData 不设置为存储所有
- myData: data.myData
- }
- }),
- ],
- })
应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter
1.在store文件下创建modules文件夹,文件夹内创建各种所需要处理的模块
- //cart.js
- const cart = { //在cart这个命名空间下
- namespaced: true, //命名空间指定模块名
- state: {
- list: [],
- },
- mutations: {
- ADD_Cart(state, product) {
- state.list.push(product)
- },
- },
- actions: {
- addCart({ commit }) {
- commit('ADD_Cart')
- },
- },
- getters: {
- // list:state=>state.list
- list(state) {
- return state.list
- },
- },
- }
- export default cart
store中的index.js
- import { createStore } from 'vuex'
- import createPersistedState from 'vuex-persistedstate'
- import user from './modules/user' //导入user.js
- import cart from './modules/cart' //导入cart.js
- const store = createStore({
- modules: { //集成模块
- user,
- cart,
- }
- })
- export default store
- //Home.vue
- import { mapGetters } from "vuex";
- export default {
- data() {
- return {
- // user: null,
- }
- },
- computed:{
- user(){
- return this.$store.getters['cart/list'] //cart这个命名空间下的list
- }
- // ...mapGetters(['user'])
- },
- NPM****
- $ npm install element-plus --save
- # Yarn
- $ yarn add element-plus
- # pnpm
- $ pnpm install element-plus
首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
- import { defineConfig } from 'vite'
- import AutoImport from 'unplugin-auto-import/vite'
- import Components from 'unplugin-vue-components/vite'
- import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
- export default defineConfig({
- // ...
- plugins: [
- // ...
- AutoImport({
- resolvers: [ElementPlusResolver()],
- }),
- Components({
- resolvers: [ElementPlusResolver()],
- }),
- ],
- })
npm install @element-plus/icons-vue
直接通过设置类名为 el-icon-iconName
来使用即可
- //Login.vue
- <el-icon> <User /> el-icon>
- <script>export default {
- components: {
- User,
- Lock,
- },
- }script>
-
- //或者
- <i class="el-icon-share">i>
- <i class="el-icon-delete">i>
- <el-button type="primary" icon="el-icon-search">搜索el-button>