V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Shook
V2EX  ›  JavaScript

给 Vue 写了个继承 props 的模块,但放入 computed 中检测不到数据变化

  •  
  •   Shook · 2018-12-29 00:18:58 +08:00 · 4974 次点击
    这是一个创建于 2157 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是之前发布片段的地址: 码云代码片段

    这个模块主要的功能是,可以获取父传入的 props,并且与本组件设定好的默认数据整合起来。

    比方说我有个组件 Message。 我给 Message 设定了一个 prop,名为 options:

    props: {
        options: {
        	type: Object
        }
    }
    

    我希望 options 的默认值是这样的:

    options: {
        icon: '',
        name: '',
        href: '',
        onClick: () => {},
    }
    

    然后,我在父中传入值:

    <Message :options="{ name: 'shook' }" />
    

    那么正常来说,在 Message 中获取 this.options,就会得到一个只有 name 属性的对象。 但我想要得到的 options 对象是这样的:

    {
        icon: '',
        name: 'shook',
        href: '',
        onClick: () => {},
    }
    

    于是,这就是我写的这个文件的功能了… 使用的方法,就是引入到组件中:

    import { propExtender } from '...xxx'
    

    然后往 Message 组件的 computed 中加入一个名为 extender 的函数:

    computed: {
        extender () {
        	return propExtender.extender(this);
        }
    }
    

    于是在组件内,就能通过 this.extender.options 拿到混合后的属性了。

    但目前我遇到的问题是,这个功能获取的数据,在 prop 的值改变时,并不会触发 computed 的更新。

    于是 extender 拿到的数据,永远只有第一次是准确的。

    如果在那之后 prop 的值有所改变,这个 extender 都是获取不到变化的…十分弱鸡。

    虽然放到 methods 中就能够去掉缓存这个特性,但我还是十分担心性能会出问题。所以想请大家帮忙看看该如何做才能够让 vue 检测到这个方法获取到的属性改变。

    8 条回复    2018-12-29 12:45:44 +08:00
    yljcyct
        1
    yljcyct  
       2018-12-29 00:26:08 +08:00 via Android
    直接给这个 prop 设置一个 default 默认值不就好了吗
    Lax
        2
    Lax  
       2018-12-29 00:31:25 +08:00
    return propExtender.extender(this);
    -- 这里面 3 个依赖 propExtender,extender() 和 this 都没变化,不会触发刷新。
    Lax
        3
    Lax  
       2018-12-29 00:37:39 +08:00
    粗暴点直接 return {
    icon: '',
    name: '',
    href: '',
    onClick: () => {},

    ...this.options
    }
    tinybaby365
        4
    tinybaby365  
       2018-12-29 08:02:51 +08:00
    在 watch 函数里面,用$emit 通知
    Shook
        5
    Shook  
    OP
       2018-12-29 09:35:33 +08:00
    @yljcyct 如果 prop 的属性是复杂类型,简单地设置 default 不能达到想要的效果
    @Lax 我现在尝试给 extender 函数加入了一个形参,算是笨拙地解决了这个问题…

    原本:extender (self) { ... }
    Shook
        6
    Shook  
    OP
       2018-12-29 09:37:01 +08:00
    接上条
    原本:extender (self) { ... }
    解决办法:extender (self, originProps) { ... }
    也就是说使用的时候需要这样做了:return propExtender.extender(this, this.$props);
    yljcyct
        7
    yljcyct  
       2018-12-29 10:06:57 +08:00
    @Shook 嗯嗯, 但是我觉得你这样好麻烦, 还不如直接把 options 的属性都拆开来写, 不要放在一个对象
    royzxq
        8
    royzxq  
       2018-12-29 12:45:44 +08:00
    #3 已经解决了你的问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1003 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 23:08 · PVG 07:08 · LAX 15:08 · JFK 18:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.