Vuex官网:https://vuex.vuejs.org/zh
Vuex是实现组件全局状态(数据)管理的一种机制,方便实现组件之间的数据共享。
一般只有组件之间共享的数据,才有必要存储到vuex中,对于组件的私有数据,依旧存储在组件自身的data中。
父传子:v-bind
属性绑定
字传父:v-on
事件绑定
兄弟组件之间共享数据:EventBus
$on
接收方$emit
发送方安装vuex依赖包
yarn add vuex --save
导入vuex包
vue2 搭配的是 vuex@3版本,vue3 搭配的是 vuex@4版本。
import vuex from 'vuex'
Vue.use(vuex)
创建 store 对象(共享数据对象)
const store = new Vuex.store({
// state中存放的是全局共享的数据
state: { count: 0 }
})
将 store 对象挂载到 vue 实例中
new Vue({
// 所有的组件,可以直接从store中获取全局的数据
store
})
在 src 下新建 stores
文件夹,并新建 index.js
文件。
import Vue from "vue"
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 源数据
},
mutations: {
// 修改state
},
actions: {
// 异步mutations
},
getters: {
// 更新state
}
})
引入到 main.js
import Store from '@/Stores'
new Vue({
Store
})
在项目根目录新建 .prettierrc
配置文件。
{
"semi": false, // 不使用分号
"singleQuote": true // 使用单引号
}
State 提供唯一的公共数据源,所有的共享数据都要统一放到 Store 的 State 中进行存储。
直接访问
{{ $store.state.属性名 }}
导入 mapState 函数访问
导入 mapState 函数,将当前组件需要的全局数据,映射为当前组件的 computed 计算属性。
<template>
<div> {{ count }} div>
template>
<script>
// 按需导入 mapState 函数
import { mapState } from 'vuex'
export default {
// 将全局数据,映射为当前组件的计算属性
computed: {
...mapState(['count'])
}
}
script>
- 创建一个空对象,循环遍历存储有要访问的变量数组。
- 在空对象内存储
this.$store.state[item]
挂载的每一项。- 返回这个对象。
- 调用即可。
function myMap (arr) {
const obj = {};
arr.forEach((item) => {
obj[item] = function () {
return this.$store.state[item];
};
});
return obj;
}
export default {
computed: {
...myMap(['name', 'age'])
}
}
Mutation
本质是一个 javascript 函数,用于修改 Store 中的数据。可以集中监控所有数据的变化。
- 只能通过 Mutation 变更 Store 数据,不可以直接操作 Store 中的数据。
在store.js中定义方法
const store = new Vuex.store({
// state中存放的是全局共享的数据
state: {
count: 0
},
// 变更State数据
mutations: {
// 加法函数:state 代表 state对象
add (state, num) {
state.count+=num
},
// 减法函数
Sub(state) {
state.count--
}
}
})
调用 mutations 中的方法
方式一:直接调用
// 语法格式:
this.$store.commit('方法名')
<script>
export default {
methods: {
add() {
this.$store.commit('add')
}
}
}
script>
方式二:按需导入
通过
mapMutations
函数 调用mutations
中的方法。
// 语法格式:
import { mapMutations } from 'vuex'
...mapMutations(['方法名'])
<script>
// 导入 mapMutations函数
import { mapState, mapMutations } from 'vuex'
export default {
// 将全局数据映射为计算属性
computed: {
...mapMutations(['add'])
},
}
script>
在store.js中定义方法
const store = new Vuex.store({
state: {
count: 0,
},
mutations: {
// 参数二是自定义传参
add (state, step) {
state.count += step;
}
}
})
调用 mutations 中的方法
方式一:直接调用
<script>
export default {
methods: {
add () {
this.$store.commit('add', 1);
}
}
}
script>
方式二:按需导入
通过 mapMutations 函数 调用 mutations 中的方法。
<script>
// 导入 mapMutations函数
import { mapState, mapMutations } from 'vuex'
export default {
// 将全局数据映射为计算属性
computed: {
...mapMutations(['add'])
}
}
script>
App.vue
<template>
<div>
<button @click="Sub(1)">-1button>
{{ $store.state.count }}
<button @click="Add">+1button>
div>
template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
methods: {
// 方法一:调用时传参
Add() {
this.$store.commit('Add', 2)
},
...mapMutations(['Sub'])
},
// 方法二:需要把用到的属性传过来
computed: {
...mapState(['count'])
},
}
script>
Store.js
import Vue from "vue"
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
Add (state, num) {
state.count += num;
},
Sub(state, num) {
state.count -= num;
}
}
})
Action 本质是一个 javascript 函数,用于处理异步任务。
如果通过异步操作变更数据,必须通过 Action,而不能使用 Mutation,但在 Action 中还是要通过触发 Mutation 的方式简介变更数据。
- 一般在网络请求和做延迟的时候使用。
在 actions 中,不能直接修改 state 中的数据。
必须通过 context.comit()
触发某个 mutations 才行。
const store = new Vuex.store({
state: { count: 0 },
// 定义方法
mutations: {
add (state) { state.count++ }
},
// 异步操作
actions: {
// 调用mutations中的方法,重新定义异步方法
addAsync (context) {
setTimeout( () => {
context.commit('add');
}, 1000)
}
}
})
调用 mutations 中的异步方法
方式一:直接调用
// 语法格式:
this.$store.dispatch('异步方法名')
<template>
<div>
<button @click="add">直接使用button>
div>
template>
<script>
export default {
methods: {
add () {
// dispatch 函数用来触发某个actions
this.$store.dispatch('addAsync');
}
}
}
script>
方式二:按需导入
通过
mapActions
函数 调用mutations
中的方法。
// 语法格式:
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState(['数据变量名']),
},
methods: {
...mapActions(['异步方法名']),
},
}
<template>
<div>
<button @click="addAsync">直接使用button>
div>
template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
// 将全局数据映射为计算属性
computed: {
...mapState(['count']),
},
methods: {
// 通过 mapActions 函数 调用 mutations 中的方法
...mapActions(['addAsync']),
},
}
script>
在store.js中定义方法
const store = new Vuex.store({
state: { count: 0 },
// 定义方法
mutations: {
add (state, step) { state.count += step }
},
// 异步操作
actions: {
// 调用mutations中的方法,重新定义异步方法
addAsync (context, step) {
setTimeout( () => {
context.commit('add', step);
}, 1000)
}
}
})
调用 mutations 中的异步方法
方式一:直接调用
// 语法格式:
$store.dispatch('异步方法名', 实参)
<script>
export default {
methods: {
add () {
// dispatch 函数用来触发某个actions
this.$store.dispatch('addAsync', 1);
}
}
}
script>
方式二:按需导入
通过 mapActions 函数 调用 mutations 中的方法。
<template>
<div>
<button @click="add(1)">直接使用button>
<button @click="addN">重新定义使用button>
div>
template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
// 将全局数据映射为计算属性
computed: {
...mapState(['count']),
},
methods: {
// 通过 mapActions 函数 调用 mutations 中的方法
...mapActions(['add']),
addN () {
this.add(1);
}
},
}
script>
App.vue
<template>
<div>
<button @click="strAsync">点击输出一句话button>
<p>{{ $store.state.msg }}p>
div>
template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState(['msg'])
},
methods: {
// 方法一:
str () {
this.$store.dispatch('strAsync')
},
// 方法二:
...mapActions(['strAsync'])
},
}
script>
Store.js
import Vue from "vue"
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
msg: ''
},
mutations: {
Str (state) {
state.msg = 'Hello World'
}
},
actions: {
strAsync (context) {
setInterval(() => {
context.commit('Str')
}, 1000)
}
}
})
Getter 本质是一个 javascript 函数,用于对 Store 中的数据进行加工处理形成新数据。类似于 Vue 的计算属性。
- Store 中的数据发生变化,Getter 的数据也会跟着发生变化。
const store = new Vuex.store({
state: { count: 0 },
// 定义方法
mutations: {
add (state) { state.count++ }
},
// 异步操作
actions: {
// 调用mutations中的方法,重新定义异步方法
addAsync (context) {
setTimeout( () => {
context.commit('add');
}, 1000)
}
},
// 更新数据
getters: {
showNum (state) {
return state.count
}
}
})
调用 mutations 中的方法
方式一:直接调用
// 语法格式:
this.$store.getters.方法名
<script>
export default {
methods: {
showNums () {
$store.getter.showNum();
}
}
}
script>
方式二:按需导入
// 语法格式:
import { mapState, mapMutations, mapGetters } from 'vuex'
...mapGetters(['getters中的方法名'])
<template>
<div>
<button @click="add">直接使用button>
<button @click="addN">重新定义使用button>
div>
template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
// 将全局数据映射为计算属性
computed: {
...mapState(['count']),
...mapGetters(['showNum'])
},
}
script>
按照模块化的思想开发,把不同的数据和方法,按照彼此的关联进行封装。
定义模块
在 stores 文件夹下新建 userStore.js 文件
export default {
state: {
name: '法外狂徒 张三',
time: 18,
navList: [
'首页',
'作品展示',
'商务合作',
]
},
mutations: {
changeTime (state, num) {
state.time += num
}
}
}
注册模块
在 stores 文件夹下的 index.js 中导入分类后的模块。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 导入不同的module模块
import userStore from './userStore'
export default nw Vuex.Store({
// 把 store 分离出去
modules: {
user: userStore
}
})
通过模块的注册名称访问模块下的成员
<template>
<div>
div>
template>
<script>
export default {
// 不能随便访问,只能在访问空间访问
namespaced: true,
computed: {
...mapState('user', ["name", "time", "navList"]),
},
methods: {
...mapMutations('user', ['changeTime'])
}
}
script>
// 不开启命名空间访问方法:
this.$store.state.命名空间名.变量名
// 开启空间语法格式:
...mapState('命名空间名', ["变量名/方法名"]),
下载组件库
Ant-design-vue 组件库官网:https://1x.antdv.com/docs/vue/introduce-cn/
yarn add ant-design-vue
引入组件库
在 src/main.js 中全局引入
// 引入 Button 样式
import Button from 'ant-design-vue/lib/button';
import 'ant-design-vue/dist/antd.css';
Vue.component(Button.name, Button);
样式模板
<template>
<div id="app">
<a-input placeholder="请输入任务" class="my_ipt" />
<a-button primary>添加事项a-button>
<a-list bordered class="dt_list">
<a-list-item slot="renderItem">
<a-checkbox>a-checkbox>
<a slot="actions">删除a>
a-list-item>
<div slot="footer" class="footer">
<span>0条剩余span>
<a-button-group>
<a-button>全部a-button>
<a-button>未完成a-button>
<a-button>已完成a-button>
a-button-group>
<a>清除完成a>
div>
a-list>
div>
template>
<script>
export default {};
script>
<style scoped>
#app {
padding: 10px;
}
.my_ipt {
width: 500px;
margin-right: 10px;
}
.dt_list {
width: 500px;
margin-top: 10px;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
}
style>
App.vue
<template>
<div>
<header class="header">
<h1>todosh1>
<input id="toggle-all" class="toggle-all" type="checkbox" />
<label for="toggle-all">label>
<input class="new-todo"
placeholder="输入任务名称-回车确认"
autofocus
/>
header>
<ul class="todo-list">
<li class="completed">
<div class="view">
<input class="toggle" type="checkbox" />
<label>任务名label>
<button class="destroy">button>
div>
li>
ul>
<footer class="footer">
<span class="todo-count">剩余<strong>数量值strong>span>
<ul class="filters">
<li>
<a href="javascript:;"
class="selected" >
全部
a>
li>
<li>
<a href="javascript:;">
未完成
a>
li>
<li>
<a href="javascript:;">
已完成
a>
li>
ul>
<button class="clear-completed">清除已完成button>
footer>
div>
template>
<script>
export default {
data () {
return {
list: []
}
}
};
script>
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
import axios from 'axios'
export default new Vuex.store({
// 源数据
state: {
},
// 方法
mutations: {
},
// 异步
actions: {
getList (context) {
axios({
})
}
},
// 更新
getters: {
}
})
created 与 mounted 的区别
mounted 与 methods 的区别
computed 与 watched 的区别