Vuex入门使用规则

一、Vuex的实例加载方式

安装方式vue-cli直接安装

1.微型项目

①创建vuex文件夹 src/store/index
//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
const store=new Vuex.Store({

state:{
//你的数据状态注册
count:0
},

})
②挂载vuex
//mian.js
import Vue from 'vue'
import App from './App.vue'
//引入Vuex
import Vuex from './store'

//全局挂载Vuex 与router一样
new Vue ({
store,
render:h=>h(app)
}).$mount('#app')

2.大型多状态项目(实际最常用)

大型項目于普通的小項目相似,
Vuex 允许我们将 store 分割成模块(module)
思路是把所有状态都集中到一个store/index.js里面
然后通过store的全局挂载实现信息同步,
但实际工作做用一般都属于第二种

①创建子组件状态js 空文件夹
//创建子状态文件及文件夹 store/global/button.js
const state={
count:0
}

const mutations={
//同步处理函数
}
const actions={
//异步处理函数
}

//共享出去
export default{
//namespaced解决不同模块命名冲突的问题,之后在
//不同页面中引入getter、actions、mutations时,需要加上所属的模块名
namespaced:ture,
state,
mutations,
actions
}
②引入子组件状态js到 store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
//引入你的子状态js文件
import button from './global/button.js'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
  //注册到模块化组件内 由store全局共享
    button,
    button1,
    button2
    ....
  },
   getters // store 的计算属性 接收参数state 与computed相似 一般单独一个文件夹
})

export default store

二、Vuex的传参数方式

①调用$store直接得到参数

//方法一
//注意:如果将数据count写到store/index.js文件夹中 
// this.store.state.变量名(js名.全局数据名称)
//注意:如果将数据count写到store/.文件夹名.count 
// this.store.state.文件夹名.变量名
//例子 调用第一章节中的count值
<template>
<div class='main-container'>
<h1>数据的最新值:{{this.$store.state.button.count}}</h1>
//在html结构中 此处this可省略 
</div>
</template>

②从Vuex中按需导入mapState函数方式

//方法二
import {mapState} from 'vuex'
// 通过此函数将全局数据映射为 当前组件 的计算属性
//例如 调用第一章节中的count值
<javascript>
...
computed:{
//可追加所需要的数据 前面 ‘... ’为对象展开运算符,
//与复制不同,映射可以随着原数据的更新,此组件也随之更新。
...mapState({
count:state=>state.button.count
})
//如果将数据count写到store/index.js文件夹中 则可简写
//num为组件应用处命名:

数据的最新值:{{num}}

...mapState({ num:'count' }) //如果不命名则可以:

数据的最新值:{{count}}

更简写
...mapState(['count']) } ... </javascript>
在实际项目开发中,可根据需求自己选用哪种方式

第一种:适合少量数据传输,写法简单快捷
第二种:更适合大量数据传输,方便查看更整洁

三、组件数据变化提交

在vuex中如果数据发生变化如何实现?
(注意:此案例vuex状态写在模块js内 路径为 src/store/global/button.js)

//创建子状态文件及文件夹 store/index.js
const state={
count:0
}

const mutations={
//同步处理函数
}
const actions={
//异步处理函数
}

//共享出去
export default{
namespaced:ture,
state,
mutations,
actions
}
<template>
<div class='main-container'>
//此处为双大括号 此处必须加上组件名字“button”
<h1>数据的最新值:{{this.$store.state.button.count}}</h1>
<button @click="countAdd"> +1 </button>
//在html结构中 此处this可省略 
</div>
</template>

<script>
export default {
  name: 'Home',
  data() {
    return {
    };
  },
  methods: {
 countAdd(){
   this.$store.state.button.count++ 
 }

  }
};
</script>
上述方法虽然能使count数字发生变化,但是这是一种错误的使用方法

不利于后期维护,无法检测数据变化
Vuex入门使用规则_第1张图片
简单的说Vuex就相当于一个班级的班长,
vue相当于班级班主任,不同的状态js文件相当于一个科目课代表,
所有的状态数据都通过js课代表存储到班长,
任何学生想要更改作业个人信息,不能自己随便更改,
需要通过课代表来更改,然后课代表汇总所有数据存储在班长哪里

*如果使用微型项目单文件store的形式不存在课代表 班长就相当于课代表

从组件中改变count数据在Vuex的框架下,应该叫做提交数据

1、 Mutations

在vuex中只能通过mutations提交变更Store数据,不能直接操作Store的数据
可通过vuex中的mutations此函数来改变数据

①第一种 触发 mutations函数

Ⅰ、 触发mutations函数(不传参)
//定义mutations  为简单在组件vuex的总文件夹index.js创建
const store=new Vuex.store({
//模块内部的 mutation,接收的第一个参数是模块的局部状态对象。
mutations:{
add(state){
 state.count++
}
}

})
//组件中
<script>
export default {
  name: 'Home',
  data() {
    return {
    };
  },
  methods: {
     countAdd(){
 //add为mutations函数中对应的函数名
    this.$store.commit('add')
    }
  }
};
</script>
Ⅱ、 触发mutations函数 (并且传递参数)
//定义mutations
const store=new Vuex.store({

mutations:{
add(state,num){ 
  //将vuex中的数据 num为传递来的参数
  //最新count=count+num  结果赋值给count
  state.count+=num
}
}

})
//组价触发mutations
const store=new Vuex.store({

methods:{
 handle(){ 
  //提交mutations并传递参数
  this.$store.commit("add",任意参数)
}
}

})

② 第二种 触发 mutations函数

官方文档在此处说明有些模糊,导致很不容易理解!!!

Ⅰ.绑定事件,从vuex中按需导入mapMutations 函数

<button @click='countAdd'></button>
import { mapMutations} from 'vuex'

Ⅱ.将指定的mutations 函数,映射为当前组件的methods函数

methods: {
   //可映射多个mutations中的函数映射过来  
   //注意:“ ... ” 为对象展开运算符
   
   //功能一 button点击触发事件countAdd()  
  ...mapMutations({countAdd:'add'})
  
   //功能二 当button点击触发事件时候需要传递参数 countAdd(value) 例如数字变量num 仍然可以保持这样写
  ...mapMutations({countAdd:'add'})
  //只是需要在mutations函数中加一个接收参数num就行
  
  //功能三 button点击触发事件@click='add'函数命名
  //如果与mutations中的函数名一致为add  则可简写为:  
  ...mapMutations(['add']) //{}变为[]
  
}

}
模块内注册的状态数据访问

注意点1、

数据的最新值:{{this.$store.state.button.count}}


此处一定要加上组件名 ‘button’
注意点2、 this.$store.commit('button/add',任意参数)
提交时一定要加上组件名 ‘button’
在store内函数commit内提交
可打印console.log(this.$store)查看更好理解
Vuex入门使用规则_第2张图片

2、Actions

action函数不能直接更改vuex中数据
他主要处理异步函数
比较相对繁琐的工作
处理完成后提交给mutations更改数据

异步与同步举例:

//还是刚才的数据count 
<template>
<div class='main-container'>
//此处为双大括号
<h1>数据的最新值:{{this.$store.state.count}}</h1>
<button @click="countAdd"> +1 </button>
//在html结构中 此处this可省略 
</div>
</template>

<script>
export default {
  name: 'Home',
  data() {
    return {
    };
  },
  methods: {
 countAdd(){
   this.$store.commit('add')
 }

  }
};
</script>

如果想实现点击按钮 让数据 count 延迟1秒再增加 如何实现?
可以通过增加一个定时器!!!
假如给mutations添加结果怎样?

//定义mutations
const store=new Vuex.store({

mutations:{
  add(state){
    setTimeout( ()=>{
    state.count++
    },1000)
  }
  
}

})

结果就是数字虽然会延时触发
但打开vue调试工具会发现add时间虽然触发 但右侧 state中count数据并未发生变化
这显然是不行的
Vuex入门使用规则_第3张图片
所有这里引入Action函数帮助处理这些异步函数
Actions就当于Mutations的个人助理
大大小小的事件都交给Actions,Mutations只做最终签字就行

③ 第三种 触发 mutations函数–Actions (实际开发项目基本这种)

//定义mutations
const store=new Vuex.store({

mutations:{
ADD(state){
  state.count++
}

}
actions:{
//Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,
//因此你可以调用 context.commit 提交一个 mutation函数。
add(context){
setTimeout( ()=>{
context.commit('ADD')
  },1000)
}
}



})

Vuex入门使用规则_第4张图片
这个例子很好的阐述Mutations函数与Actions的区别,各自分工。

实际开发中Mutations与Actions
一般都不会直接调用Mutations函数,
一般都通过调用Actions函数来提交更改数据申请
并且为了彼此对应,常常把Mutations中的函数名大写,Actions函数名小写

①Actions函数触发提交方式

运行流程如下
组件提交>Actions>Mutations>状态改变>同步到全局组件>组件再次改变…
一个完整闭环流程

//1、组件调用
this.$store.dispatch('add')
//2、Actions接受信号,并提交给Mutations
add(context){
 context.commit('ADD')
}
}
//3、Mutations修改数据
ADD(state){
 state.count++
}
}
实际开发采用 ES2015 的 参数解构 (opens new window)来简化代码

下面介绍两种提交:
未模块化单store.js 无参数提交 修改vuex
模块化并且携带参数提交

//1、组件调用
//单文件01 store.js
this.$store.dispatch('add')
//模块化1 提交到 user为user.js, user_Info为提交Actis函数名字, nickname为提交参数
this.$store.dispatch('user/user_Info', 'nickname'); 

//2、Actions接受信号,并提交给Mutations
//单vuex文件02 store.js
add:({commit}){
commit('ADD')
}
//模块化2 
user_Info ({ commit }, nickname) {
    commit('USER_INFO', 'nickname')
  }
//3、Mutations修改数据
//单vuex文件03 store.js
ADD:(state)=>{
 state.count++
}
//模块化3
USER_INFO (state, nickname) {
    state.nickname = nickname
  }

Actions同样有mapActions辅助函数帮助数据传输
与mapMutations用法类似 这里不做演示

区分:

1、mapState在computed中注册使用
2、mapActions与Actions在methods中注册使用

到这里再看这张图就简单多了,devtools为vue调试工具 能检测到vuex的变化状态
Vuex入门使用规则_第5张图片

四、Getter的使用

上面的看懂了解清楚,Getter就很容易明白了
主要意义处理state中的数据,然而这个数据又不能是原始数据,
Getter就可以作为一个过滤处理函数

1、Getters函数 使用方法一

例子1:查询水果中第一个水果数量(返回值)
const store=new Vuex.store({
state:{
 fruit: [
    { name: 'a', num: 5 },
    { name: 'b', num: 10 },
    { name: 'c', num: 16 }
   ],
  }
}
mutations:{}
actions:{}
getters:{
  fruitNum: state => {
      return state.fruit[0].num
   }

}
})
组件引用
...
<el-button> 第一个水果数量:{{ this.$store.getters.fruitNum }}</el-button>
...
...
  console.log(this.$store);
...

Vuex入门使用规则_第6张图片

例子2:查询水果信息 (返回函数)
getters:{
    //查询数据
    maxCount: (state) => (who) => {
      return state.fruit.find(fruit => fruit.name === who)
    }

}
...
<el-button> 第一个水果数量:{{ this.$store.getters.maxCount('a') }}</el-button>
...
...
//还能可以打印查看
console.log(this.$store.getters.maxCount('a'));
//注意 这里有一个坑
//你如果直接打印
console.log(this.$store.getters);
// 会发现找不到maxCount的数据,因为这里是需要传参数的

...

1、Getters函数 使用方法二

与其他Vuex的函数一样,Getters同样具备mapGetters

getters:{
    //计算返回数据
    maxCount: (state) => (who) => {
      return state.fruit.find(fruit => fruit.name === who)
    }

}
//引入函数注册提交
import { mapGetters} from 'vuex';
...
  computed: {
    ...mapGetters(['maxCount'])
  },
...
<h3> c水果的信息为:{{ maxCount('c') }}<h3>
//渲染结果为 

c水果的信息为:{ "name": "c", "num": 16}

...

此处注意点 若为模块化项目 getters也模块化独立文件js 例如:src/store/myCount.js
注册提交时要添加上文件名

  computed: {
    ...mapGetters('myCount',['maxCount'])
  },

在组件内重命名使用
注意 [ ] 改变{ }

  computed: {
    ...mapGetters('myCount',{yourname:'maxCount'})
  },

到此!vuex的所有内容基本完毕,你过你那种方法都能用的得心应手,那vuex恭喜你!加油!!

你可能感兴趣的:(vuex,vue,javascript,vue.js,前端)