omputed+watch+Vuex实现多组件共享管理一个状态

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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值