Vuex项目 state mutations actions getters Module(学习与使用)

2 篇文章 0 订阅

简介

非关系型组件的数据共享 - Vuex(状态共享框架)
Vuex 是采用集中式管理组件依赖的共享数据的一个工具,可以解决不同组件数据共享的问题

  • state - 存储共享状态数据,可以在组件中引用
  • mutations - 修改 state 必须通过 mutations ,只能执行同步代码,类似 ajax ,定时器之类的代码不能在 mutations 中执行
  • actions - 执行异步操作,数据提交给 mutations 进行修改
  • 组件 - 组件调用 action

步骤

  1. 创建项目
    在这里插入图片描述
// vue 命令
vue create demo
  1. 选择模式
    在这里插入图片描述
  2. 下载相关依赖
    在这里插入图片描述
    在这里插入图片描述
// 运行时依赖,命令二选一
// npm i vuex --save
npm i vuex -S
  1. 初始化及注册
    在这里插入图片描述
// src/main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'

Vue.config.productionTip = false

Vue.use(Vuex)

const store = new Vuex.Store({})

new Vue({
  render: h => h(App),
  store // es6写法
}).$mount('#app')

Vuex - state

state 是存放所有公共状态的属性

定义

在这里插入图片描述

const store = new Vuex.Store({
  // 实例化Vuex的构造参数 state mutations actions
  state: {
    // 存储的状态
    count: 0
  }
})

使用 - 原始形式

在这里插入图片描述

// src/App.vue
<template>
  <div>
    <!-- 原始形式应用 -->
    <div>原始形式获取state状态:{{ $store.state.count }}</div>
  </div>
</template>

<script>
export default {}
</script>

<style></style>
// 项目启动命令
npm run serve

【如果项目启动报错,看 package.json 中的命令配置】
在这里插入图片描述

效果

在这里插入图片描述

使用 - 计算属性

  • 使用
    在这里插入图片描述
// src/App.vue
<template>
  <div>
    <p>计算属性状态:{{ count }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}
</script>
  • 效果
    在这里插入图片描述

使用 - 辅助函数( mapState )

mapStatus - 辅助函数,用于把 store 中的数据映射到组件的计算属性中,属于一种简便用法

  • 步骤
    在这里插入图片描述
// src/App.vue
<template>
  <div>
    <p>计算属性状态:{{ count }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex' // 导入mapState
export default {
  computed: {
    // 利用延展运算符将导出的状态映射给计算属性
    ...mapState(['count'])  // 采用数组形式引入state属性
  }
}
</script>
  • 效果
    在这里插入图片描述

Vuex - mutations

state 数据的修改只能通过 mutations,并且 mutations 必须是同步更新,目的是形成 数据快照
数据快照 - 一次 mutation 的执行,立即得到一种视图状态,因为是立即,所有必须是同步定义 mutation
不能写异步代码,如果有异步的 ajax 请求,应放到 actions 中

使用 - 原始形式

组件内使用

步骤

在这里插入图片描述

// src/main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex' // 引入

Vue.config.productionTip = false

Vue.use(Vuex) // 注册 Vuex 的功能

// 实例化一个Vuex
const store = new Vuex.Store({
  // 实例化Vuex的构造参数 state mutations actions
  state: {
    // 存储的状态
    count: 0
  },
  mutations: {
    addCount (state) {
      state.count += 1
    },
  }
})

在这里插入图片描述

// src\components\chila-a.vue
<template>
  <button @click="test">+1</button>
</template>

<script>
export default {
  methods: {
    test () {
      this.$store.commit("addCount")
    }
  }
}
</script>

在这里插入图片描述

// src\App.vue
<template>
  <div>
    <div>原始形式获取state状态:{{ $store.state.count }}</div>
    <p>计算属性状态:{{ count }}</p>
    <ChildA />
  </div>
</template>

<script>
import { mapState } from 'vuex' // 导入mapState
import ChildA from './components/chila-a.vue'
export default {
  components: {
    ChildA,
  },
  computed: {
    // 利用延展运算符将导出的状态映射给计算属性
    ...mapState(['count'])  // 采用数组形式引入state属性
  }
}
</script>

效果

在这里插入图片描述

使用 - 原始形式(传参)

代码

在这里插入图片描述

// src\main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex' // 引入

Vue.config.productionTip = false

Vue.use(Vuex) // 注册 Vuex 的功能

// 实例化一个Vuex
const store = new Vuex.Store({
  state: {
    // 存储的状态
    count: 0
  },
  // 修改state必须通过mutations
  mutations: {
    // 修改state的mutation方法
    addCount (state, payload) {
      state.count += payload
    },
  }
})

new Vue({
  render: h => h(App),
  store // es6写法
}).$mount('#app')

// src\components\chila-a.vue
<template>
  <button @click="test">+10</button>
</template>

<script>
export default {
  methods: {
    test () {
      this.$store.commit("addCount", 10)
    }
  }
}
</script>

效果

在这里插入图片描述

使用 - 辅助函数(mapMutations)

代码

在这里插入图片描述

// src\components\chila-a.vue
<template>
  <div>
    <button @click="test">+1(原始形式)</button>
    <!-- vue 中方法的默认第一个参数,事件参数对象 -->
    <button @click="addCount(100)">+100(辅助函数)</button>
  </div>
</template>

<script>
import { mapMutations } from 'vuex'
export default {
  methods: {
    // 原始方式调用
    test () {
      this.$store.commit("addCount", 1)
    },
    ...mapMutations(['addCount']) // 此时组件方法中就会拥有一个对应的addCount方法
  }
}
</script>

效果

在这里插入图片描述
【扩展】使用 $event 事件参数对象
代码
在这里插入图片描述

// src\components\chila-a.vue
<button @click="addCount($event)">+100(辅助函数)</button>

效果
在这里插入图片描述

Vuex - actions

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

定义

在这里插入图片描述

// src\main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex' // 引入

Vue.config.productionTip = false

Vue.use(Vuex) // 注册 Vuex 的功能。 Vue.use的方法实际上是调用了 Vuex 中的一个 install 的方法

// 实例化一个Vuex
const store = new Vuex.Store({
  state: {
    // 存储的状态
    count: 0
  },
  // 修改state必须通过mutations
  mutations: {
    // 修改state的mutation方法
    addCount (state, payload) {
      state.count += payload
    },
  },
  // 异步操作
  actions: {
    // 方法
    getAsyncCount (context) {
      // 模拟异步请求
      setTimeout(function () {
        // 获取到一个值
        context.commit("addCount", 123)
      }, 1000)
    },
  }
})

new Vue({
  render: h => h(App),
  store // es6写法
}).$mount('#app')

使用 - 原始调用

步骤

在这里插入图片描述

// src\components\chila-a.vue
<template>
  <div>
    <button @click="test1">异步调用(原始形式)</button>
  </div>
</template>

<script>
export default {
  methods: {
    test1 () {
      // 原始形式
      this.$store.dispatch('getAsyncCount')
    },
  }
}
</script>

效果

在这里插入图片描述

使用 - 原始调用(传参)

步骤

在这里插入图片描述

// src\main.js
actions: {
    getAsyncCount (context, params) {
      // 做异步的请求
      setTimeout(function () {
        // 获取到一个值
        context.commit("addCount", params)
      }, 1000)
    },
  }
// src\components\chila-a.vue
methods: {
    test1 () {
      this.$store.dispatch('getAsyncCount', 111)
    },
  }

效果

在这里插入图片描述

使用 - 辅助函数

将 action 导入数组中

步骤

在这里插入图片描述

// src\components\chila-a.vue
<template>
  <div>
    <button @click="getAsyncCount(222)">异步调用(辅助函数)</button>
  </div>
</template>

<script>
import { mapActions } from 'vuex'
export default {
  methods: {
    test1 () {
      // 原始形式
      // commit 是提交 mutations
      // dispatch 调用 action
      // dispatch(action的名称)
      this.$store.dispatch('getAsyncCount', 111)
    },
    ...mapActions(['getAsyncCount'])  // 引入异步的 action
  }
}
</script>

效果

在这里插入图片描述

Vuex - getters

除了 state 之外,有时我们还需要从 state 中派生出一些状态,这些状态是依赖 state 的(需要再异一步进行处理),所以会用到 getters

定义

在这里插入图片描述

// src\main.js
const store = new Vuex.Store({
  state: {
    // 存储的状态
    count: 0,
    list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  },
  getters: {
    // 放置的所有的Vuex的计算属性
    // state:当前 store 中的 state
    // filterList: function (state) {
    //   return state.list.filter(item => item > 5)
    // },
    filterList: state => state.list.filter(item => item > 5)
  },
})

使用 - 原始形式

步骤

在这里插入图片描述

// src\components\chila-a.vue
<template>
  <div>
    <div>原始形式getters: {{ $store.getters.filterList }}</div>
  </div>
</template>

效果

在这里插入图片描述

使用 - 辅助函数(mapGetters)

步骤

在这里插入图片描述

// Asrc\components\chila-a.vue
<template>
  <div>
    <div>原始形式getters: {{ $store.getters.filterList }}</div>
    <div>辅助形式getters: {{ filterList }}</div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    // 将getters中的计算属性导入到组件的计算属性中
    ...mapGetters(['filterList'])
  },
}
</script>

效果

在这里插入图片描述

Vuex - Module(模块化)

使用 - 简单应用

定义

在这里插入图片描述

// src\main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex' // 引入

Vue.config.productionTip = false

Vue.use(Vuex) // 注册 Vuex 的功能

// 实例化一个Vuex
const store = new Vuex.Store({
  modules: {
    // 放置子模块的属性
    user: {
      state: {
        token: '12345'
      },
    },
    setting: {
      state: {
        name: 'Vuex实例'
      },
    }
  }
})

new Vue({
  render: h => h(App),
  store // es6写法
}).$mount('#app')

步骤

$store.state.子模块.属性

在这里插入图片描述

// src\components\chila_b.vue
<template>
  <div>
    <!-- $store.state.子模块.属性 -->
    <div>用户名称:{{ $store.state.user.token}}</div>
    <div>应用名称: {{ $store.state.setting.name}}</div>
  </div>
</template>

在这里插入图片描述

// src\App.vue
<template>
  <div>
    <ChildA/>
    <child-b/>
  </div>
</template>

<script>
import ChildA from './components/chila-a.vue'
import ChildB from './components/chila_b.vue'
export default {
  components: {
    ChildA,
    ChildB,
  },
}
</script>

效果

在这里插入图片描述

mapGetters 引用

这个 getters 是根级别的 getters

步骤

在这里插入图片描述

// src\main.js
const store = new Vuex.Store({
  getters: {
    token: state => state.user.token,
    name: state => state.setting.name,
  },
  modules: {
    // 放置子模块的属性
    user: {
      state: {
        token: '12345'
      },
    },
    setting: {
      state: {
        name: 'Vuex实例'
      },
    }
  }
})

在这里插入图片描述

// src\components\chila_b.vue
<template>
  <div>
    <!-- 用户的token和应用名称name -->
    <!-- $store.state.子模块.属性 -->
    <div>用户名称:{{ $store.state.user.token}}</div>
    <div>快捷访问: {{ token }}</div>
    <div>应用名称: {{ $store.state.setting.name}}</div>
    <div>快捷访问: {{ name }}</div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['token', 'name'])
  }
}
</script>

效果

在这里插入图片描述

使用 - 命名空间(namespaced)

默认情况下,模块内部的 action、mutation 和 getter 是注册在 全局命名空间的 —— 这样可以使多个模块能对同一 mutation 或 action 做出响应。
如果想保证内部模块的高封递性,可以采用 namespaced 来进行设置。

命名空间 - 直接调用(带上模块的属性名路径)

步骤

在这里插入图片描述

// src\main.js
modules: {
    // 放置子模块的属性
    user: {
      namespaced: true, // 给true就表示枷锁
      state: {
        token: '12345'
      },
      mutations: {
        updateToken (state) {
          state.token = '67890'
        }
      },
      actions: {}
    },
    setting: {
      state: {
        name: 'Vuex实例'
      },
    }
  }

在这里插入图片描述

// An highlighted block
<template>
  <div>
    <!-- 用户的token和应用名称name -->
    <!-- $store.state.子模块.属性 -->
    <div>用户名称:{{ $store.state.user.token}}</div>
    <div>快捷访问: {{ token }}</div>
    <div>应用名称: {{ $store.state.setting.name}}</div>
    <div>快捷访问: {{ name }}</div>
    <button @click="updateToken">更新子模块的token</button>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  computed: {
    ...mapGetters(['token', 'name'])
  },
  methods: {
    updateToken() {
      // 采用路径形式 - 直接调用
      this.$store.commit('user/updateToken')
    }
  }
}
</script>
效果

在这里插入图片描述

命名空间 - 辅助函数(-带上模块的属性名路径)

步骤

在这里插入图片描述

// src\components\chila_b.vue
<template>
  <div>
    <!-- 用户的token和应用名称name -->
    <!-- $store.state.子模块.属性 -->
    <div>用户名称:{{ $store.state.user.token}}</div>
    <div>快捷访问: {{ token }}</div>
    <div>应用名称: {{ $store.state.setting.name}}</div>
    <div>快捷访问: {{ name }}</div>
    <button @click="updateToken">更新子模块的token</button>
    <button @click="test">子模块的mutations辅助函数</button>
  </div>
</template>

<script>
import { mapGetters, mapMutations } from 'vuex'
export default {
  computed: {
    ...mapGetters(['token', 'name'])
  },
  methods: {
    updateToken() {
      // 采用路径形式 - 直接调用
      this.$store.commit('user/updateToken')
    },
    ...mapMutations(['user/updateToken']),
    test() {
      this['user/updateToken']()
    }
  }
}
</script>
效果

在这里插入图片描述

命名空间 - espacedHelpers(创建基于某个命名空间辅助函数)

步骤

在这里插入图片描述

// src\components\chila_b.vue
<template>
  <div>
    <!-- 用户的token和应用名称name -->
    <!-- $store.state.子模块.属性 -->
    <div>用户名称:{{ $store.state.user.token}}</div>
    <div>快捷访问: {{ token }}</div>
    <div>应用名称: {{ $store.state.setting.name}}</div>
    <div>快捷访问: {{ name }}</div>
    <button @click="updateToken">更新子模块的token</button>
  </div>
</template>

<script>
import { mapGetters, createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('user')
export default {
  computed: {
    ...mapGetters(['token', 'name'])
  },
  methods: {
    ...mapMutations(['updateToken']),
  }
}
</script>
效果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

259-aaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值