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

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 }}
      
     
      <p :data-index="index">
        <span>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>

你可能感兴趣的:(Vue,vue.js,javascript,前端)