omputed+watch+Vuex实现多组件共享管理一个状态
好久没有写博客了,就最近写的一些东西给大家做一个分享
要实现的就是这种效果
页面1
页面2
点击菜单栏可以弹出菜单,再点击即可关闭
我是个菜鸟,初学vue还不太懂到底要怎么实现这个功能,通过各方查询最终决定用vuex这个状态管理模式来做,因为我的导航是一个组件,菜单栏也是一个组件,所以就涉及两个组件实时共享监听一个状态的变化
下面贴出我的Vuex的代码
//store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state={
show:false //show的含义为菜单栏的显示与否,false为隐藏,true为显示
}
const mutations={ //mutations 可改变自定义show的状态
show(state){
state.show=true;
},
hide(state){
state.show=false;
}
}
export default new Vuex.Store({
state,mutations
})
下面贴出导航栏的主要代码,导航栏既要改变Vuex中show的状态,也要监听show的状态,以改变导航按钮的形状
隐藏状态
显示状态
//模板部分
<div v-if="show">
<i class="el-icon-close" @click="dll"></i>
</div>
<div v-else>
<i class="iconfont icon-caidan" @click="dll"></i>
</div>
//js部分
import store from '../vuex/store' //导入store.js,即上文提到的Vuex
export default {
data() {
return {
name: 'header',
searchValue:'',
face:'../../../static/img/user.jpg',
show:false
}
},
computed:{
myValue() {
return this.$store.state.show
}
},
methods:{
chatList(){
this.$router.push("chatList");
},
blog(){
window.location.href="http://royalzhao.github.io";
},
dll(){
if(store.state.show){
store.commit('hide');
this.show = false
}else{
store.commit('show');
this.show = true
}
},
},
store,
watch: {
myValue: function(newVal) {
if(store.state.show){
this.show = true
}else{
this.show = false
}
}
}
}
模板部分通过v-if判断data内部的show状态来显示对应的图标按钮
通过computed和watch来实时监控vuex的show状态的变化,相应的改变本页面data中show的变化,从而改变图标按钮,这是导航栏改变vuex的show的状态,同时也作出对应的响应。
下面是导航栏
import store from '../vuex/store'
export default {
data(){
return{
d_name:'张三',
d_technicalTitle:'全科医生',
d_committee:'五湖居委',
d_tel:'17887878787',
d_patientNum:'787',
d_abstract:'如果你无法简洁的表达你的想法,那只说明你还不够了解它。',
d_face:'../../../static/img/doctor.jpg'
}
},
store,
computed:{
onRoutes(){
return this.$route.path.replace('/','');
},
myValue() {
return this.$store.state.show
}
},
mounted() {
//初始化
this.init()
},
methods:{
init(){
var left = document.getElementById('leftXs');
var modal = document.getElementById('modal');
if(store.state.show){
left.style.marginLeft = '0';
modal.style.display = 'block';
}else{
left.style.marginLeft = '-300px';
modal.style.display = 'none';
}
},
talk(){
this.$router.push('consult');
},
order(){
this.$router.push('order');
}
},
watch: {
myValue: function(newVal) {
var left = document.getElementById('leftXs');
var modal = document.getElementById('modal');
//其他业务代码
if(store.state.show){
left.style.marginLeft = '0';
modal.style.display = 'block';
}else{
left.style.marginLeft = '-300px';
modal.style.display = 'none';
}
},
onRoutes:function(){
var left = document.getElementById('leftXs');
var modal = document.getElementById('modal');
left.style.marginLeft = '-300px';
modal.style.display = 'none';
store.commit('hide');
}
}
}
页面先进行了初始化,判断vuex中的show状态,false为隐藏,true为显示,然后同样通过computed+watch进行监听,当show状态发生变化时做出相应的变化。
本文重点介绍 computed+watch+Vuex实现多组件共享管理一个状态 ,对于样式以及html模板的编写则没有过多强调,需要源码进行研究的同学请移步 https://github.com/royalzhao/sqylztc
注:此页面为响应式网页,如需查看效果请缩小浏览器窗口
<template> | |
<div> | |
分配;任务;作业;功课 | |
</div> | |
</template> | |
<script> | |
export default { | |
name: "task-assignment", | |
data () {//数据 | |
return {} | |
}, | |
props: { | |
//props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值。 | |
}, | |
computed: { | |
//计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果实例范畴之外的依赖 (比如非响应式的 not reactive) 是不会触发计算属性更新的。 | |
}, | |
methods: { | |
//methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。 | |
}, | |
watch: { | |
//一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用$watch(),遍历 watch 对象的每一个属性。 | |
}, | |
beforeCreate(){ | |
//在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用 | |
}, | |
created(){ | |
//实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见 | |
}, | |
mounted(){ | |
//el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。 | |
}, | |
beforeUpdate () { | |
// 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。该钩子在服务器端渲染期间不被调用。 | |
}, | |
updated(){ | |
// 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。 | |
}, | |
beforeDestroy(){ | |
//实例销毁之前调用。在这一步,实例仍然完全可用。 | |
}, | |
destroyed(){ | |
//Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 | |
} | |
} | |
</script> | |
<!-- Add "scoped" attribute to limit CSS to this component only --> | |
<style scoped> | |
</style> |