vue2编写一个自定义指令,一键绑定事件委托

本文介绍了如何在Vue中创建一个名为entrust的自定义指令,用于处理元素点击事件并执行相应的方法。通过事件委托,指令在元素插入、更新和销毁时触发不同的回调。实例演示了如何在模板中使用该指令以及其在数据更新时的行为。
摘要由CSDN通过智能技术生成
import vue from "vue";
const NAME = "entrust";


const INIT = (el, node) => {
    if (el instanceof HTMLElement) {
        const {
            method,
            key,
            data
        } = node.value;
        el.onclick = (e) => {
            const dom = e.target;
            if (dom.tagName) {
                const index = dom.dataset[key];
                if (index || index == 0) {
                    const value = data[index]
                    if (value) {
                        method(data[index], key, data)
                    } else {
                        // console.error("MESSAGE  : value is undefined | null")
                        console.warn("MESSAGE  : value is undefined | null")
                    }
                } 
            }
        };
    }
}
/**
 * eg:
 * v-entrust = "{method:执行函数,key:自定义属性字段名称,data:数据}"
 */

export default () => {
    vue.directive(NAME, {
        //初始化
        bind(el, node) {
            console.log(NAME + "初始化");
            INIT(el, node)
        },
        inserted() {
            console.log(NAME + "绑定的元素插入html");
        },
        updated() {
            // 所在组件的`VNode`更新时调用.
            console.log(NAME + 'updated triggerd')
        },
        componentUpdated() {
            // 指令所在组件的 VNode 及其子 VNode 全部更新后调用。
            console.log(NAME + 'componentUpdated triggerd')
        },
        //解除绑定时,可以理解为被摧毁时
        unbind(el) {
            console.log(NAME + "解除绑定");
            el.onclick = null
        }
    });
};

使用
main.js文件

import Vue from 'vue'
import App from './App.vue'

import set_dir from '@/utils/注册事件委托的文件位置.js'
//...
set_dir()

new Vue({
  render: h => h(App),
  //...
}).$mount('#app')
<template>
  <div class="doc" v-entrust="{ method: fn, key: 'index', data: list }">
    <div v-for="(item, index) in list" :key="item.name">
      {{ item.name }}
      <!-- data-index,放到p标签上,说明要将事件触发是p标签,自定义属性名称与自定义指令保持一直即可,但是值必需是当前的索引值 -->
     
      <p :data-index="index">
        <span>xxx数据、no.{{ index }}</span>
      </p>
  <!-- 如果触发节点是其他标签,data-index放到其他标签上即可 -->
  <!-- <p>
        <span :data-index="index">xxx数据、no.{{ index }}</span>
      </p> -->
    </div>
  </div>
</template>

<script>
const list = {
  0: {
    name: "模板一",
  },
  1: {
    name: "模板二",
  },
  2: {
    name: "模板三",
  },
  3: {
    name: "模板四",
  },
};

export default {
  components: {},
  data() {
    return {
      list,
    };
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  methods: {
    fn(item, index, data) {
      console.log(JSON.stringify(item));
    },
  },
};
</script>
<style lang="scss" scoped>
.doc {
  div {
    display: inline-block;
    width: 60%;
    border: 1px solid;
    margin: 15px 0;
  }
  p {
    border: 1px solid;
  }
}
</style>

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值