V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
faceRollingKB
V2EX  ›  Vue.js

vue directive 上下文问题

  •  
  •   faceRollingKB · 2020-05-23 19:36:02 +08:00 · 2113 次点击
    这是一个创建于 1406 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我需要写一个 directive,directive 绑定的值是 data 中的一个状态,bind 只能获取到状态的初始值,update 只能获取到状态的更新值,我在 bind 中给 el 添加了一个点击事件,现在的问题是这个事件只能获取到初始值,我想问一下是否有办法在事件中获取到 directive 的最新值?
    已经尝试过如下代码:
    export default function(Vue) {
    Vue.directive('copy', {
    value: '-',
    listener: null,
    bind (el, binding) {
    const fn = function(){
    copyToClipboard(this.value)
    }
    binding.def.listener = fn.bind(binding.def)
    binding.def.value = binding.value
    el.addEventListener('click',binding.def.listener)
    },
    unbind (el, binding) {
    el.removeEventListener('click',binding.def.listener)
    },
    update(el, binding){
    binding.def.value = binding.value
    }
    })
    }
    但这段代码问题是所有的 directive 实例都会共享同一个 binding.def ,我看了文档并没有发现 directive 有上下文的概念,不知道应该怎么搞
    3 条回复    2020-05-24 16:46:41 +08:00
    doommm
        1
    doommm  
       2020-05-24 12:35:42 +08:00
    下面这么写似乎是可以的,不知道有没有更好的办法

    ```
    <template>
    <div>
    <div v-copy="text">
    {{ text }}
    </div>

    <input type="text" v-model="text" />
    </div>
    </template>

    <script>
    export default {
    name: 'LabelSmall',
    directives: {
    copy: {
    bind(el, binding) {
    const copy = {};
    Reflect.defineProperty(el, '__copy__', { value: copy });

    copy.value = binding.value;
    const fn = () => {
    console.log('val', copy.value);
    };
    copy.cb = fn;

    el.addEventListener('click', fn);
    },

    componentUpdated(el, binding) {
    const copy = Reflect.get(el, '__copy__');
    copy.value = binding.value;
    },

    unbind(el, binding) {
    const copy = Reflect.get(el, '__copy__');
    el.removeEventListener('click', copy.cb);

    Reflect.deleteProperty(el, '__copy__');
    },
    },
    },
    data() {
    return {
    text: 'small',
    };
    },
    };
    </script>
    ```
    faceRollingKB
        2
    faceRollingKB  
    OP
       2020-05-24 14:13:17 +08:00
    @doommm 也就是说可以使用 el 来实现 directive 实例的上下文概念,把所有上下文内容绑定到 el 的 property 上,我先试试看
    faceRollingKB
        3
    faceRollingKB  
    OP
       2020-05-24 16:46:41 +08:00
    @doommm 可行的

    export default function(Vue) {
    const key = 'copy'
    const property = '__v_'+key+'__'
    Vue.directive(key, {
    bind (el, binding) {
    el[property]={
    value:binding.value,
    listener:function(){
    copyToClipboard(this.value)
    }
    }
    el[property].listener = el[property].listener.bind(el[property])
    el.addEventListener('click',el[property].listener)
    },
    unbind (el) {
    el.removeEventListener('click',el[property].listener)
    },
    update(el, binding){
    el[property].value = binding.value
    }
    })
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2812 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:59 · PVG 22:59 · LAX 07:59 · JFK 10:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.