vue3知识点7 vue3.0+cli4.5 vuex vuex安装配置 state mutations actions modules命名空间 getters

#vue3知识点7 vue3.0+cli4.5 vuex

1.vuex是什么?

Vuex 是一个专为 Vue.js 的SPA单页组件化应用程序开发的状态管理模式插件。

由于Vue SPA应用的模块化,每个组件都有它各自的数据(state)、界面(view)、和方法(actions)。这些数据、界面和方法分布在各个组件中,当项目内容变得越来越多时,每个组件中的状态会变得很难管理。

vuex是集中管理组件中可以共享的状态值 , 组件和组件之间可以共享的值放在vuex的state里 ,即定义的时候就把它定义为全局变量。

state里的值是全局的,哪个组件都可以用。

比如说之前的父传子,子传父,数值的传递比较繁琐,现在都可以用vuex实现。

或者是两个毫无关系的组件要共用一个数据,那么也可以写在vuex.

2.安装

先看看项目package.json里面有没有vuex,有可能在创建的时候就指定了vuex.

vue3知识点7 vue3.0+cli4.5 vuex vuex安装配置 state mutations actions modules命名空间 getters_第1张图片

如果没有,再安装。

安装命令:

npm install vuex --save
#或
npm install vuex@next

3.配置

系统自带配置

由于我在创建项目时指定安装了vuex,所以vuecli3都给配置好了,不用像cli2一样手动配置。所以我们看着理解一下就好了。

如果创建项目时没有指定,按下面的配置即可。

配置vuex和配置路由类似:在根目录下有store文件夹,里面有index.js:

index.js的内容

//引入
import { createStore } from 'vuex'


//创建并导出store实例
export default createStore({
    //存储状态值
  state: {
      //全局状态的数据源
  },
  mutations: {
      //提交mutations是更改Vuex状态的唯一方法
  },
  actions: {
      //动作  什么情况下状态值要发生变化,什么情况下调用mulations
      //异步调用mutations
  },
  modules: {
      //因为项目里有很多模块,在vuex中使用同一个store会很乱,所以,modules可以分割.
  }
})

main.js 的配置

import store from './store'


const app=createApp(App)
app.use(store)
app.use(router)
app.mount('#app')

4.vuex的运行机制

1.state 状态值

state数据源写在store/index.js的state里。

state:{
    price:100,
    count:10
}

那组件里怎么得到state里全局的值呢?

在templete里得到state中的值:
<div>
   价格: {{ $store.state.price }}
 div>
在script里得到state中的值:
console.log(this.$store.state.price)

2.mutations

状态值有几个,mu’tations就有几个,一个state状态值对应一个mutations。状态值修改必须通过mutations。

mutations是操作state的唯一方法,只有mutations方法能够改变state状态值。

mutations方法必须是同步方法,不能带ajax之类的。

2.1mutations改变状态值操作流程:

1)mutations里的一个方法func1,里面改变state里的值count.

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
  //注意方法里面必须传一个state用于接收state的数据
    func1 (state) {
      // 变更状态
      state.count++
    }
  }
})
  1. 组件里面通过commit提交mutations里的方法increment请求改变state的值。
this.$store.commit('func1')

并且,mutations方法是可以传参的。

2.2传参

函数:

mutations: {
    add(state, n) {
      state.count += n
    }
  },

组件里调用:

通常,参数会是一个对象,方便包含多个字段的读取。

this.$store.commit('add', 10)

3.actions

actions也能修改state状态值,但它是通过提交mutations方法来修改store中的状态值。

官方推荐我们使用actions来修改state的属性,当然组件中可以直接用commit调用mutations方法。

之前说mutations方法必须只能是同步方法,为了处理异步方法,actions出现了。

context

代表vuex实例对象,它可以通过commit触发mutations里的方法。

下面是actions的两种用法:

第一种:调用mutations。来修改值,也可以传参数。

第二种,异步处理

mutations: {
    func1(state) {
      state.count++
    }
  },  

actions: {
    //第一种:调用mutations。来修改值
    //直接触发mutations的func1
    func1 (context) {
      context.commit('func1')
    },
     //第二种,异步处理
     //异步处理让func1的调用延时
    func2 (context) {
      // 延时1秒  
      setTimeout(() => {
        context.commit('func1')  
      }, 1000)
    }
  },
  
 
组件调用actions
 //不同于mutations使用commit方法,actions使用dispatch方法。
  this.$store.dispatch('func2 ')

actions改变状态值流程 例:

store/index.js

export default createStore({
    //1.1 state里写全局变量count
  state: {
	  count:1,
	  
  },
  mutations: {
      //2.2 MUTATIONS里写参数替换state的count值的func1
	  func1(state,otherdata){
	  		  state.count=otherdata
	  }
  },
  actions: {
      //2.3 actions里面写调用mutations的函数,带参给func1
	  actionfunc(context,n){
		  context.commit("func1",n)
	  }
  },
  modules: {
    
  }
})

vuextest.vue

<template>
	<div>
		<h1>vuex的使用h1>
        
		<h4>1.state全 局变量count:  {{$store.state.count}}h4>
		<h4>2.  actions带参改变count做法h4>
         
		<button @click="clickfunc">点击我触发clickfuncbutton>
	div>
template>

<script>
	export default {
	  name: 'vuextest',
	  data() {
	    return {
	      arr:[],
	    }
	  },
	  created(){
		  console.log(this.$store.state.count)
	  },
	  methods:{
		  clickfunc(){
			  //通过提交actions来修改vuex中的count值
			  //参数,如果是多个参数,就定义一个对象再传
              
              //2.4 定义代替count的参数n,并在函数里调用actions
              //带参给actionfunc
			  let n=2
			  this.$store.dispatch("actionfunc",n)
			  
			  
			  
		  }
	  }
	  
	  
	 
	
	}
script>

4.modules

模块,在大型项目中为了方便状态的管理,将store拆分成多个子模块modules,每个子模块都有完整的store,mutation,action,getter.

比如说:大型项目要进行模块划分,针对模块进行状态值的管理,比全部写进state要好。

把仓库划分成多个模块,一个模块可以包含多个组件。

划分模块流程:

在store中创建modules文件夹,里面写js文件,每个js文件代表一个模块,js文件的内容是每个模块的index.js。每个模块导出后,在store/index.js的modules引入它们的模块名。

下面举一个例子:

划分模块例:

需求:

vue3demo3中有helloword.vue和vuextest1.vue,假如这俩是一个模块,有公共值count, 起名为hellovuex模块,另外axios文件夹是另一个模块axios. 在vuextest1里面引用count值,并改变它的值为2。

所涉及文件:

store/modules/axios.js
store/modules/hellovuex.js
store/index.js
vuextest1.vue

所以,modules里创建hellovuex.js和axios.js。代表两个模块。

vue3知识点7 vue3.0+cli4.5 vuex vuex安装配置 state mutations actions modules命名空间 getters_第2张图片

每个模块.js的内容是这样的:

hellovuex.js

创建hellovuex对象,里面写上和store/index.js一样的内容,导出hellovuex对象。

//hellovuex.js
const hellovuex={
	//helloworld和vuextest1 里面共用一个值count
    
	  state: {
		  count:1,
		  
	  },
	  mutations: {
	      //2.2 MUTATIONS里写参数替换state的count值的func1
		  func1(state,otherdata){
		  		  state.count=otherdata
		  }
	  },
	  actions: {
	      //2.3 actions里面写调用mutations的函数,带参给func1
		  actionfunc(context,n){
			  context.commit("func1",n)
		  }
	  },
}
export default hellovuex;

axios.js

const axios={
	// ... 同上
}
export default axios;

store/index.js

store/index.js里面引入这两个模块js, 然后在modules里注册上两个模块。

导出store/index.js

// 模块化之后

import { createStore } from 'vuex'
//引入时注意 一定是这个带./的路径。相对路径,不然就是针对整个目录来说的
import hellovuex from "./modules/hellovuex.js"
import axios1 from "./modules/axios.js"

export default createStore({
  
  modules: {
	hellovuex:hellovuex,
	axios1:axios1
	
  }
})

组件中使用模块化后的值

在组件中使用模块化后的值的时候,要带上模块名。

<template>
原来是:
{{$store.state.count}}
模块化后:hellovuex是模块名
{{$store.state.hellovuex.count}}
template>

<script>
  原来是:
  console.log(this.$store.state.count)
  模块化后:
  console.log(this.$store.state.hellovuex.count)
    
  调用模块化后的actions或者mulations的函数,则不需要改变
  this.$store.dispatch("actionfunc",n)
script>

vuextest1.vue: 调用公共hellovuex.js里count值的组件

<template>
	<div>
		<h1>vuex 模块化的使用  helloworld 和vuex1公用h1>
		
		<h4>1.state全 局变量count: {{$store.state.hellovuex.count}}h4>
		<h4>2.  actions带参改变count做法h4>
		<button @click="clickfunc">点击我触发clickfunc改变countbutton>
	div>
template>

<script>
	export default {
	  name: 'vuextest1',
	  data() {
	    return {
	      arr:[],
	    }
	  },
	  created(){
		  console.log(this.$store.state.hellovuex.count)
	  },
	  methods:{
		  clickfunc(){
			  let n=2
			  // 调用函数是不用考虑模块化的,站在整个仓库的角度上调用,不用加模块名
			  this.$store.dispatch("actionfunc",n)
			  
		  }
	  }

	}
script>

5.命名空间

此时会有一个问题:假如两个模块.js中有一个相同名字的actions方法,一个a.js,一个b.js, 比如他们的actions都叫“actionfunc”,所做的事情是不一样的,我在a模块下的vuextest1.vue中调用actionfunc,执行的时候会在全局找actionfunc名字,这两个都会执行。

只想执行a.js下的actions方法怎么办?此时就要用到命名空间,指定actions了。

mutation也同样适用。

命名空间用法:

//hellovuex.js
const hellovuex={
	//命名空间
      namespaced:true,
	  ...
      ...
	  actions: {
		  actionfunc(context,n){
              console.log("我是hellovuex的actions")
			  context.commit("func1",n)
		  }
	  },
}
export default hellovuex;

组件里调用的时候:

//vuextest1.vue
<script>
	export default {
	  name: 'vuextest1',
	  data() {
	    return {
	      arr:[],
	    }
	  },
	  created(){
		  console.log(this.$store.state.hellovuex.count)
	  },
	  methods:{
		  clickfunc(){
			  let n=2
              //调用的时候加上模块目录
			this.$store.dispatch("hellovuex/actionfunc",n)
			  
		  }
	  }
	
	}
script>

效果:

vue3知识点7 vue3.0+cli4.5 vuex vuex安装配置 state mutations actions modules命名空间 getters_第3张图片

6.getters

基于store的派生状态,相当于组件中的计算属性computed,我们可以认为,getters是store的计算属性。当state中的值变化时,它自动更新。

getters用法:

假如我们要计算state中的price*count。

//hellovuex.js
//和state同级
getters:{
		  getterfunc(state){
			  return state.price*state.count
		  }
		  
	  }

vuextest1.vue

<template>
	<div>
		
		<h4>3. getters的用法:h4>
		
		
		
		<p>count*price=: {{$store.getters['hellovuex/getterfunc']}}p>
	div>
template>

<script>
    created(){
         //原getters
		  console.log("--getters--"+this.$store.getters.getterfunc)
		  //getters命名空间 用法: this.$store.getters['模块名/属性名']
		  console.log("--getters--"+this.$store.getters['hellovuex/getterfunc'])
    }
script>

效果:

vue3知识点7 vue3.0+cli4.5 vuex vuex安装配置 state mutations actions modules命名空间 getters_第4张图片

你可能感兴趣的:(vue基础,前端,vue3.0,vue3-cli4.5,vuex,store仓库)