14.组件之间传递Object对象出现的_Observe{..} 无法获取值的问题

       今天,在做项目期间,遇到了一个问题。

       场景如下:在父组件中,引入了两个子组件,两个组件都是自己手工根据需求封装的,分别是<Selector>组件和<DatePicker>组件。Selector组件主要用于条件的筛选,DatePicker主要用于日期的选择。组件之间传值,毕竟传递的属性比较多,所以选择了通过对象Object的形式传递的。场景中,一个父组件包含两个子组件,两个子组件之间是兄弟关系。

       <Selector>组件有三个选项:(id=0)日、(id=1)周、(id=2)月。当选择日时,<DatePicker>组件需要展现"年月日"格式筛选,当选择周时,组件需要展现 xxxx 年  xxx周 两列的筛选,当选择月时,组件需要"年月"的筛选。

        <Selector>组件,可以通过this.$emit("result",data);的形式将数据由子组件传递给父组件,然后在父组件中通过@result 来接收。如果选择了"日",然后将id=0实时传给DatePicker组件,<DatePicker>子组件根据父组件传递的id来实时的变化<DatePicker>中的具体选项。

具体:就是如下图这个效果

         鼓捣了半天。发现子组件还是无法接收到父组件传递给它的值。最后想到了Vuex,但是这本就是个小功能,没有必要用到Vuex。

  父组件结构如下(部分代码):

<template>
    <div>
        <div class="date">
            <!-- 类型 -->
            <Selector :params="typeSelect" @result="getType"></Selector>
            <!-- 日期 -->
            <DatePicker :params="dateSelect" @result="getDate"></DatePicker>
        </div>
    </div>
</template>

<script>
    import Selector from '@/components/common/Selector';
    import DatePicker from '@/components/common/DatePicker';
    export default {
        data(){
            return {
                //1.如下是"类型"组件,数据需要通过父组件传递给子组件
                typeSelect:{
                    id:'typePicker',
                    defaultSelect:0,
                    defaultTip:'日',
                    resultData:[{index:'0',value:'0',text:'日'},{index:'1',value:'1',text:'周'},{index:'2',value:'2',text:'月'}],
                    allSelectId:0,
                    allSelectTip:'日',
                    isHasName:true,
                    name:'类型'
                },
                //2.如下是"日期"筛选组件,数据需要通过父组件传递给子组件
                dateSelect:{
                    id:'datePicker',
                    dateType:'date',
                    isHasName:true,
                    name:'时间'
                }
            }
        },
        components:{Selector,DatePicker},
        methods:{
            getType(data){
                this.typeValue = data[0].value;
                //同步传值给子组件(前提:dateSelect对象声明了个receiveType属性,属于修改属性范畴)
                this.dateSelect.receiveType = this.typeValue
                //同步传值给子组件(前提:dateSelect对象中没有receiveType属性,属于新增属性范畴)
                this.$set(this.dateSelect,"receiveType",this.typeValue);
                //如上两种二选一!!!!!!!!
            },
            getDate(data){
                if(this.typeValue == 0){
                    this.dateValue = data.y.value + data.m.value + data.d.value;
                }else if(this.typeValue == 1){
                    this.dateValue = data[1].value;
                }else if(this.typeValue == 2){
                    this.dateValue = data.y.value+data.m.value;
                }
            }
        },
        mounted() {
            
        },
    }
</script>

思路:在定义dateSelect对象时,声明一个receiveType属性,默认为空(1、声明后,则对该属性进行修改即可 2、不声明也可以,则是对该对象进行添加属性,区别:一个修改属性,一个添加属性)。因为Vue视图是基于数据驱动来实现的,我们通过getType方法获取"日周月"类型返回值,然后实时修改dateSelect对象信息,子组件DatePicker便可以根据传递的类型实时来变化

实现:①可以在子组件DatePicker中,使用watch来实时监听数据的变化

//1.针对属性存在,默认为空情况,通过如下对数据修改
  this.dateSelect.receiveType = this.typeValue
//子组件watch(子组件接收父组件传递过来的参数,名为params)
  watch{
      params(newValue,oldValue){
         //子组件无法监听到变化
      },
      receiveType(newValue,oldValue){
         //子组件无法监听到变化
      }
  }
//1.针对属性不存在,通过如下对数据新增属性
  this.$set(this.dateSelect,"receiveType",this.typeValue);
//子组件watch(子组件接收父组件传递过来的参数,名为params)
  watch{
      params(newValue,oldValue){
         //子组件能够监听到params对象的变化
      },
      receiveType(newValue,oldValue){
         //子组件无法监听到属性receiveType的变化
      }
  }

 总结:watch监听---只能监听①单独属性的变化   ②对象数据的变化(无法监听对象中具体属性的变化)

②针对①中【属性存在,默认为空情况,通过=的形式修改,无法监听到params的变化】,那么怎么才能够监听到呢?

//1.使用handler函数   2.添加deep属性
watch{
    params:{
        handler(newVal,oldVal){
            
        },
        deep:true 
    }
}

提示:只要params中的属性发生变化(可被监听到的),便会执行handler函数;如果想监测具体的属性变化,如receiveType变化时,才执行handler函数,则可以利用计算属性computed做中间层。

③子组件中,使用computed属性,来监听对象具体属性的变化

//通过watch监听receiveType属性的变化,然后通过计算属性computed来获取具体变化的值
computed:{
    receiveType(){
        return this.params.receiveType;
    }
},
watch:{
    //监听父组件传递的dateType,
    receiveType(newValue,oldValue){
        console.log(newValue);//此处即为变化后的receiveType属性值
    }
}

至此:子组件便可以监听到父组件实时传递过来的receiveType属性,然后同步做出一些相关操作,达到数据驱动的效果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扛麻袋的少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值