Vuex——笔试题、Vuex简介、引入方式、State、Getter、Mutation、Action、Module

目录

 仓库vuex

一、Vuex简介

二、引入方式

1.自己下载引入

2.cli脚手架引入

1.手动引入(方法一)

2.引入(方法二)

三、State

1.创建state状态

2.组件中访问数据

四、Getter

1.设计

2.使用

五、Mutation

1.设计

2.组件中使用

2.1 第一种方式:直接触发并传值(提交载荷)

2.2 第二种方式:可以以一个对象的形式传入

六、 Action

1、设计

2、使用(两种):

1.直接分发

2.以对象形式分发

七、Module

八、笔试题


 仓库vuex

一、Vuex简介

1.简介

为了方便实现组件之间的数据共享,Vuex是他们团队借鉴了redux,用来实现vue组件全局状态(数据)管理的一种机制.

2.特点(面试)

能够在vuex中集中管理共享的数据,易于开发和后期维护

能够高效地实现组件之间的数据共享, 提高开发效率

存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步

一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;

对于组件中的私有数据,依旧存储在组件自身的data中即可.

3.使用场景

如果你实在不知道开发中什么数据才应该保存到Vuex中,那你就先不用Vuex,需要的时候自然就会想到它

Vuex的官网:

二、引入方式

1.自己下载引入

2.cli脚手架引入

1.手动引入(方法一)

安装: 

npm i vuex --save

导入:

import Vuex from "vuex"

Vue.use(Vuex)

创建仓库:

const store=new Vuex.Store({

           state:{msg:"我就是所有共享的数据"}

})

把仓库挂载到vm对象:

new Vue({

     render(h){return h(app)},

     router,

     store//挂载以后  所有的组件就可以直接从store中获取全局数据

}).$mount( "#app")

2.引入(方法二)

vue create init

选更多选项

选择Babel、router、vuex、scss、linter

选择2.x

回车

scss

回车

取消lint on save

回车

三、State

1.创建state状态

状态就是那个存数据的对象

const store=new Vuex.store({
           state:{msg:"我就是所有共享的数据"}
})

2.组件中访问数据

this.$store.state.msg

this.$store.state.msg =“修改”  ==>官方不建议使用此方法去修改,应该用官方提供的 mutation

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
  router,
  store,//让整个vue项目仓库生效
  render: h => h(App)
}).$mount('#app')

router下的index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [{
		path: '/',
		name: 'home',
		component: () => import("../views/home/index.vue")
	},
	{
		path: '/home',
		name: 'home2',
		component: () => import("../views/home/index.vue")
	},
	{
		path: '/login',
		name: 'login',
		component: () => import("../views/login/index.vue")
	},
	{
		path: '/car',
		name: 'car',
		component: () => import("../views/car/index.vue")
	},
	{
		path: '/news',
		name: 'news',
		component: () => import("../views/news/index.vue"),
		beforeEnter(to,from,next){
			console.log("beforeEnter",1111)
			next()
		}
	},
	{
		path: '/*',
		name: 'err',
		component: () => import("../views/err/index.vue")
	}
]
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})
export default router

store下的index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)//让组件的原型链中 有仓库的工具代码
export default new Vuex.Store({
  state: {
	  msg:"仓库中的数据",
	  arr:[{price:18,count:2,id:123},{price:15,count:2,id:124},{price:12,count:2,id:127}]
  },
  getters: {
	  total(state){
		  //笔试题: 字符串去前后空格  数组去重  求总价
		  return state.arr.reduce(function(n1,n2){return n1+n2.price*n2.count},0)
	  }
  },
  mutations: {
	  change1(state,agr2){
		  console.log(agr2,6666)
		  state.msg=agr2.a
	  },
	  change3(state,arg){
		  state.arr[0].count =arg.n	
		// mutations中修改仓库数据 只能在同步代码中实现  不要再异步函数中实现 否则会出现不刷新页面的情况	   
	  }
  },
  actions: {
  },
  modules: {
  }
})

home下面的components下的Box2.vue

<template>
	<div>
		box2组件---{
   
   {$store.state.msg}}
		<button @click="change1">box2的按钮修改msg(直接改 不推荐)</button>
		<button @click="change2">box2的按钮修改msg(提交mutation)</button>
		<button @click="change3">box2的按钮修改数量(提交mutation)</button>
	</div>
</template>
<script>
	export default {
		methods:{
			change1(){
				// this.$store.state.msg="box2修改了仓库数据"//官方说的 不要这样直接去修改数据
			},
			change2(){
				//提交载荷
				//第1种. this.$store.commit("change1","hello,box2修改了数据")
				//第2种. this.$store.commit("change1",{a:"hello,box2修改了数据"})
				//也是2种的另外一种写法,
				this.$store.commit({type:"change1",a:"hello,box2修改了数据"})
			},
			change3(){
				this.$store.commit({type:"change3",n:10})
				 // this.$store.state.arr[0].count=200	
			}
		}
	}
</script>

<style>
</style>

四、Getter

getter就就像是store的计算属性,它会传入state对象供我们操作

1.设计

const store = new Vuex.Store({
  state: {
    arr: [
      { id: 1, text: '...', birth: "1997-02-03" },
      { id: 2, text: '...', birth:  "2019-10-03" }
    ]
  },
  getters: {
     bigMans(state) {
      return state.arr.filter((man)=>{
    	  let manY=new Date(man.birth).getFullYear()
    	  let nowY=new Date().getFullYear()
    	  return (nowY-manY)>=18
    	  })
    }
  }
})

2.使用

this.$store.getters.bigMans


 

五、Mutation

mutation中修改仓库数据,只能在同步代码中实现,不要在异步函数中实现,否则会出现不刷新页面的情况

修改状态的唯一方式就是提交mutations,而且是同步的

如果要异步的修改数据,就可以使用actions异步的提交mutations

组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
不要用赋值表达式直接在组件中给store设置新数据
这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI

1.设计

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
	//默认传第一个参数传state
	increment (state,obj) {
	  // 变更状态
	  state.count=obj.n
	}
  }
})

2.组件中使用

2.1 第一种方式:直接触发并传值(提交载荷)

this.$store.commit('increment',{n:100})
increment是触发的函数名

2.2 第二种方式:可以以一个对象的形式传入

传入对象时,当相于把整个对象作为了第二个参数传入mutations

//第一种
this.$store.commit("increment",{a:"修改"}
//第二种:
this.$store.commit({
  type: 'increment',
  n:100
})

注意:一条重要的原则就是要记住 mutation 必须是同步处理
下面是错误的方式:

mutations: {
  increment (state,obj) {
	//如果fnAsync函数是一个异步业务函数,就会导致更新失败
	fnAsync(() => {
	  state.count=obj.n
	})
  }
}

六、 Action

Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。

如果要异步的修改数据,就可以使用actions异步的提交mutations

1、设计

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state,obj) {
      state.count=obj.n
    }
  },
  actions: {
	//默认第一个参数传一个跟store一样的对象
	increment (context,obj) {
		//假设fnAsync是一个异步业务函数
		fnAsync(() => {
		  context.commit('increment',obj)
		})      
	}
  }
})

2、使用(两种):

1.直接分发

this.$store.dispatch('increment',{n:100})
 

2.以对象形式分发

this.$store.dispatch({
  type: 'increment',
  n:100
})

七、Module

可用于业务分块开发:
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter

//分块设计:
const moduleA = {
  namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
  state: { msg:1 },
  mutations: { change(state,n){state.msg=n} },
  actions: { change(context,n){context.commit("change",n)} },
  getters: { x(state){return state.msg} }
}

const moduleB = {
   namespaced: true,//局部命名空间	
   state: {  msg:1 },
   mutations: { change(state,n){state.msg=n} },
   actions: { change(context,n){context.commit("change",n)} },
   getters: { x(state){return state.msg} }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

//组件中的使用:
this.$store.state.a.msg // -> moduleA 的状态
this.$store.state.b.msg // -> moduleB 的状态
this.$store.commit("a/change",100)-> moduleA 的mutations
this.$store.commit("b/change",200)-> moduleB 的mutations
this.$store.getters["a/x"]-> moduleA 的getters
this.$store.getters["b/x"]-> moduleB 的getters
this.$store.dispatch("a/change",100)-> moduleA 的actions
this.$store.dispatch("b/change",200)-> moduleB 的actions

 store下的index.js

import Vue from 'vue'
import Vuex from 'vuex'
import  Model1 from "./Model1.js"
import  Model2 from "./Model2.js"
import  Model3 from "./Model3.js"
import  Model4 from "./Model4.js"
Vue.use(Vuex) //让组件的原型链中 有仓库的工具代码

export default new Vuex.Store({
	state: {
	},
	getters: {				
	},
	mutations: {	
	},
	actions: {	
	},
	modules: {
		Model1,
		Model2:Model2,
		Model3,
		Model4
	}
})

store下的Model1.js

export default {
	namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
	state: {
		x:"张三的公共数据"
	},
	getters: {	
		getx(){
			return x+"6666"
		}
	},
	mutations: {
		setxsync(state,obj){
			state.x=obj.x
		}
	},
	actions: {	
		setxasync(ctx,obj){
			setTimeout(()=>{
				ctx.commit("setxsync",obj)
			},1000)
		}
	}
}

可以拓展:

mapState,mapGetters,mapMutation,mapAction和使用常量替代 Mutation 事件类型,

使用常量替代 mutation 事件类型在各种 Flux 实现中是很常见的模式。

同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然

用不用常量取决于你——在需要多人协作的大型项目中,这会很有帮助。但如果你不喜欢,你完全可以不这样做。

八、笔试题

下列关于 Vuex 的描述,不正确的是哪项?
A. Vuex 通过 Vue 实现响应式状态,因此只能用于 Vue
B. Vuex 是一个状态管理模式
C. Vuex 主要用于多视图间状态全局共享与管理
D. 在 Vuex 中改变状态,可以通过 mutations 和 actions

选C,多视图

猜你喜欢

转载自blog.csdn.net/qq_52301431/article/details/126832511