vue指令源码实现

1.v-if

本文章详细讲解vue的directive指令,实现几个基本指令

import Vue from 'vue'

Vue.directive('my-if', {
  bind: function(el, binding, vNode, oldVNode) {},
  inserted: function(el, binding, vNode, oldVNode) {
    let comment = document.createComment('')
    const index = Array.from(el.parentNode.childNodes).findIndex(i => i === el)
    el.domIndex = index
    el.pNode = el.parentNode
    if (binding.value) {
      el.parentNode.replaceChild(comment, el)
    }
  },
  update: function(el, binding, vNode, oldVNode) {
    let comment = document.createComment('')
    binding.value
      ? el.pNode.replaceChild(el, el.pNode.childNodes[el.domIndex])
      : el.pNode.replaceChild(comment, el)
  },
  componentUpdated: function(el, binding, vNode, oldVNode) {},
  unbind: function(el, binding, vNode, oldVNode) {}
})

复制代码

2.v-show

import Vue from 'vue'

Vue.directive('my-show', {
  bind: function(el, binding, vNode, oldVNode) {},
  inserted: function(el, binding, vNode, oldVNode) {
    binding.value ? (el.style.display = 'block') : (el.style.display = 'none')
  },
  update: function(el, binding, vNode, oldVNode) {
    binding.value ? (el.style.display = 'block') : (el.style.display = 'none')
  },
  componentUpdated: function(el, binding, vNode, oldVNode) {},
  unbind: function(el, binding, vNode, oldVNode) {}
})
复制代码

3.v-model

import Vue from 'vue'

Vue.directive('my-model', {
  bind: function(el, binding, vNode, oldVNode) {
    el.value = binding.value
  },
  inserted: function(el, binding, vNode, oldVNode) {
    el.addEventListener('keyup', function(event) {
      if (vNode.context[binding.expression] !== el.value) {
        vNode.context[binding.expression] = el.value
      }
    })
  },
  update: function(el, binding, vNode, oldVNode) {
    if (el.value !== binding.value) {
      el.value = binding.value
    }
  },
  componentUpdated: function(el, binding, vNode, oldVNode) {},
  unbind: function(el, binding, vNode, oldVNode) {}
})

复制代码

v-loading

import Vue from 'vue'
import LoadingComponent from '@/components/ContentLoading'

let LoadingConstructor = Vue.extend(LoadingComponent)
let initComponent

Vue.directive('loading', {
  bind: function(el, binding, vNode, oldVNode) {},
  inserted: function(el, binding, vNode, oldVNode) {
    el.style.position = 'relative'
    if (binding.value) {
      initComponent = new LoadingConstructor()
      initComponent.$mount()
      el.appendChild(initComponent.$el)
    }
  },
  update: function(el, binding, vNode, oldVNode) {
    if (binding.value) {
      initComponent = new LoadingConstructor()
      initComponent.$mount()
      el.appendChild(initComponent.$el)
    } else {
      el.removeChild(initComponent.$el)
    }
  },
  componentUpdated: function(el, binding, vNode, oldVNode) {},
  unbind: function(el, binding, vNode, oldVNode) {}
})

复制代码

clickOutside

import Vue from 'vue'

Vue.directive('outerside', {
  bind: function(el, binding, vNode, oldVNode) {},
  inserted: function(el, binding, vNode, oldVNode) {
    document.addEventListener('click', (e) => {
      if (el.contains(e.target)) {
        return false
      }
      if (binding.value) {
        binding.value(e)
      }
    }, false)
  },
  update: function(el, binding, vNode, oldVNode) {
  },
  componentUpdated: function(el, binding, vNode, oldVNode) {},
  unbind: function(el, binding, vNode, oldVNode) {}
})
复制代码

numberAnimation

import Vue from 'vue'
Vue.directive('numberAnimate', {
  bind: function(el, binding, vNode, oldVNode) {},
  inserted: function(el, binding, vNode, oldVNode) {
    let from = binding.value.from
    let to = binding.value.to
    let index = 0
    let step = () => {
      index += 4
      el.innerHTML = index
      if (index < to) {
        requestAnimationFrame(step)
      }
    }
    requestAnimationFrame(step)
  },
  update: function(el, binding, vNode, oldVNode) {},
  componentUpdated: function(el, binding, vNode, oldVNode) {},
  unbind: function(el, binding, vNode, oldVNode) {}
})

复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值