vuex
Vuex概念 : 在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态(数据)进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
使用场景:在多个组件间都需要共享同一个数据时,使用vuex;相当于如果有一个数据,然后有很多个组件都需要使用(读取/修改这个数据)时就用vuex 因为如果是使用emit / $on
Vuex 工作原理图:
state:state中存储着数据,更改状态(数据)的唯一方法是提交mutation,
例
this.$store.commit('SET_VIDEO_PAUSE', video_pause),
SET_VIDEO_PAUSE为mutations属性中定义的方法 ,一般我们都全部大写,actions中一般小驼峰命名。actions-mutations:在组件中通过this.$store.dispatch(a,b) 进行发送信息 ,在Actions里面有相应的方法a a(context,value)同时传递过来有数据value=b context里面有方法
context.rootState :访问大仓库数据. context.rootGetters:访问大仓库里面的getter. state:自己仓库数据
如果有数据就可直接转发给Mutations 在actions里面commit(A,数据) ,在mutations里面对数据进行操作。
大仓库$store 里面有dispatch、commit、getters、state........
搭建vuex环境 Vue2-Vuex3 Vue3-Vuex4
创建文件:
src/store/index.js//引入Vue核心库 import Vue from 'vue' //引入Vuex import Vuex from 'vuex' //应用Vuex插件 Vue.use(Vuex) //准备actions对象——响应组件中用户的动作 const actions = {} //准备mutations对象——修改state中的数据 const mutations = {} //准备state对象——保存具体的数据 const state = {} //创建并暴露store export default new Vuex.Store({ actions, mutations, state })在
main.js中创建vm时传入store配置项...... //引入store import store from './store' ...... //创建vm new Vue({ el:'#app', render: h => h(App), store })
getters的使用
概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
在
store.js中追加getters配置...... const getters = { bigSum(state){ return state.sum * 10 } } //创建并暴露store export default new Vuex.Store({ ...... getters })组件中读取数据:
$store.getters.bigSum
四个map方法的使用
mapState方法: 用于帮助我们映射
state中的数据为计算属性computed: { //借助mapState生成计算属性:sum、school、subject(对象写法) ...mapState({sum:'sum',school:'school',subject:'subject'}), //借助mapState生成计算属性:sum、school、subject(数组写法) ...mapState(['sum','school','subject']), },mapGetters方法: 用于帮助我们映射
getters中的数据为计算属性computed: { //借助mapGetters生成计算属性:bigSum(对象写法) ...mapGetters({bigSum:'bigSum'}), //借助mapGetters生成计算属性:bigSum(数组写法) ...mapGetters(['bigSum']) },mapActions方法: 用于帮助我们生成与
actions对话的方法,即:包含$store.dispatch(xxx)的函数methods:{ //靠mapActions生成:incrementOdd、incrementWait(对象形式) ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) //靠mapActions生成:incrementOdd、incrementWait(数组形式) ...mapActions(['jiaOdd','jiaWait']) }mapMutations方法: 用于帮助我们生成与
mutations对话的方法,即:包含$store.commit(xxx)的函数methods:{ //靠mapActions生成:increment、decrement(对象形式) ...mapMutations({increment:'JIA',decrement:'JIAN'}), //靠mapMutations生成:JIA、JIAN(对象形式) ...mapMutations(['JIA','JIAN']), }备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。
模块化+命名空间
目的:让代码更好维护,让多种数据分类更加明确。
修改
store.jsconst countAbout = { namespaced:true,//开启命名空间 state:{x:1}, mutations: { ... }, actions: { ... }, getters: { bigSum(state){ return state.sum * 10 } } } const personAbout = { namespaced:true,//开启命名空间 state:{ ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { countAbout, personAbout } })开启命名空间后,组件中读取state数据:
//方式一:自己直接读取 this.$store.state.personAbout.personList //方式二:借助mapState读取: ...mapState('countAbout',['sum','school','subject']),开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取 this.$store.getters['personAbout/firstPersonName'] //方式二:借助mapGetters读取: ...mapGetters('countAbout',['bigSum'])开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch this.$store.dispatch('personAbout/addPersonWang',person) //方式二:借助mapActions: ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})开启命名空间后,组件中调用commit
//方式一:自己直接commit this.$store.commit('personAbout/ADD_PERSON',person) //方式二:借助mapMutations: ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
Vuex与localStorage
vuex 是 vue 的状态管理器,存储的数据是响应式的。但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state。
这里需要注意的是:由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要用JSON转换:
JSON.stringify(state.subscribeList); // array -> string JSON.parse(window.localStorage.getItem("subscribeList")); // string -> array
组件间的通信方式
组件中的数据共有三种形式:data、props、computed
父子组件之间通信(父传子:props - v-bind(:) 、子传父:$emit - v-on(@) )
- 父传子:在父组件中通过自定义属性v-bind 传 在子组件中通过prpos收
传:
<users v-bind:users="users"></users>//前者自定义名称传递给子组件调用,后者要传递数据名收:props:['users'],
- 子传父:在子组件中通过this.$emit('myName')传 在父组件中通过v-on收
传:
this.$emit("titleChanged","子向父组件传值");//自定义事件 传递值“子向父组件传值”收:
<app-header v-on:titleChanged="updateTitle" ></app-header>//与子组件titleChanged自定义事件保持一致事件总线 emit, 收:$on) 任意组件之间的通信 vue中全局事件总线是添加到vm的原型身上,每个组件实例对象vc都可以可以访问到
`
`
Vuex (任意组件之间间的通信) 数据集中式的管理(仓库)
$parent/$children与ref(父子组件通信)
- ref (父传子)如果添加到普通标签上拿到的就是普通的标签,如果加到组件标签上拿到的就是这个组件的实例对象vc 所以在父组件中给子组件便签打上ref 通过this.$refs.comA 就可以得到子组件vc从而操作里面的属性和方法。
- children 属性 this.$children 可以得到所有子组件的实例对象vc 这里需要注意得到的子组件需要forEach遍历 如果子组件很多通过索引的方式拿到的不一定是想要的那个。
- parent 属性 this.$parent 可以得到父组件的实例对象
listeners (父传子 (好像还可以跨级))
$attrs:是组件实例上的一个属性,可以通过this.attrs获取到的就得刨开props接收的属性剩下的才是$attrs实际接收到的。在使用这些属性时必须使用v-bind 不能使用简写形式(:) 。
$listeners:是组件实例上的一个属性 ,可以通过this.listeners" 传入内部组件】
- ???
\