美文网首页
Vue中 directive 用法

Vue中 directive 用法

作者: HHHHy2019 | 来源:发表于2020-04-19 23:38 被阅读0次

    directive的官方文档

    Vue.directive( id, [definition] )

    • 参数

      • {string} id
      • {Function | Object} [definition]
    • 用法

      注册或获取全局指令。

      // 注册
      Vue.directive('my-directive', {
        bind: function () {},
        inserted: function () {},
        update: function () {},
        componentUpdated: function () {},
        unbind: function () {}
      })
      
      // 注册 (指令函数)
      Vue.directive('my-directive', function () {
        // 这里将会被 `bind` 和 `update` 调用
      })
      
      // getter,返回已注册的指令
      var myDirective = Vue.directive('my-directive')
      
    • 案例:
    
    <html>
      <head>
        <title>directive 用法</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      </head>
      <body>
        <div id="root">
          <div v-loading="isLoading">{{data}}</div>
          <button @click="update">更新</button>
        </div>
        <script>
          Vue.directive('loading', {
            //当我们的isLoading发生变化的时候会触发update
            //1. 传入的是object
            update(el, binding, vnode) {
              // 会触发两次
              console.log(el, binding, vnode)
              /*
              第一次调用:
              <div></div>
              {name: "loading", rawName: "v-loading", value: true, expression: "isLoading", modifiers: {…},name: "loading",oldArg: undefined,oldValue: false,rawName: "v-loading",value: true, …} 
              VNode {tag: "div", data: {…}, children: Array(1), text: undefined, elm: div, …}
              第二次调用:
              <div>用户数据 </div> 
              {name: "loading", rawName: "v-loading", value: false, expression: "isLoading", modifiers: {…},name: "loading",oldArg: undefined,oldValue: true,rawName: "v-loading",value: false, …} 
              VNode {tag: "div", data: {…}, children: Array(1), text: undefined, elm: div, …}
              */
              if (binding.value) {
                // 非侵入的创建一个遮罩,可以封装成固定的静态组件
                const div = document.createElement('div')
                div.innerText = '加载中...'
                div.setAttribute('id', 'loading')
                div.style.position = 'absolute'
                div.style.left = 0
                div.style.top = 0
                div.style.width = '100%'
                div.style.height = '100%'
                div.style.display = 'flex'
                div.style.justifyContent = 'center'
                div.style.alignItems = 'center'
                div.style.color = 'white'
                div.style.background = 'rgba(0, 0, 0, .7)'
                document.body.append(div)
              } else {
                document.body.removeChild(document.getElementById('loading'))
              }
            },
          })
          /*
          2.传入的是function
           Vue.directive('loading', {
            update(el, binding, vnode) {
              console.log(el, binding, vnode)
              if (binding.value) {
                const div = document.createElement('div')
                div.innerText = '加载中...'
                div.setAttribute('id', 'loading')
                div.style.position = 'absolute'
                div.style.left = 0
                div.style.top = 0
                div.style.width = '100%'
                div.style.height = '100%'
                div.style.display = 'flex'
                div.style.justifyContent = 'center'
                div.style.alignItems = 'center'
                div.style.color = 'white'
                div.style.background = 'rgba(0, 0, 0, .7)'
                document.body.append(div)
              } else {
                // 因为是function时会直接绑定到bind和update两个生命周期上,当时bind时,我们的loading还没有加入当页面当中,所以会找不到这个dom节点
                const div = document.getElementById('loading')
                div && document.body.removeChild(div)
              }
            },
          })
          */
    
          new Vue({
            el: '#root',
            data() {
              return {
                isLoading: false,
                data: '',
              }
            },
            methods: {
              update() {
                this.isLoading = true
                setTimeout(() => {
                  this.data = '用户数据'
                  // 获取请求时我们可以使用try catch方法防止未知错误
                  this.isLoading = false
                }, 3000)
              },
            },
          })
        </script>
      </body>
    </html>
    
    
    
    • directive的源码
    //vue.js:5210
    
    function initAssetRegisters(Vue) {
      /**
       * Create asset registration methods.
       */
      ASSET_TYPES.forEach(function (type) {
        //type => directive
        Vue[type] = function (id, definition) {
          //id => "loading",definition = >{update:f}
          if (!definition) {
            return this.options[type + 's'][id]
          } else {
            /* istanbul ignore if */
            if (type === 'component') {
              validateComponentName(id)
            }
            if (type === 'component' && isPlainObject(definition)) {
              definition.name = definition.name || id
              definition = this.options._base.extend(definition)
            }
            if (type === 'directive' && typeof definition === 'function') {
              //我们的definition是object
              definition = { bind: definition, update: definition } //如果是function,直接添加到bind和update这两个生命周期上
            }
            this.options[type + 's'][id] = definition //this.options.directives.loading = f
            /*
            =>
            options:{
              components: {KeepAlive: {…}, Transition: {…}, TransitionGroup: {…}}
              directives:{
                loading: {update: ƒ}
                model: {inserted: ƒ, componentUpdated: ƒ}
                show: {bind: ƒ, update: ƒ, unbind: ƒ}
              }
              filters: {}
              _base: ƒ Vue(options)
            }
            */
            return definition
          }
        }
      })
    }
    
    

    相关文章

      网友评论

          本文标题:Vue中 directive 用法

          本文链接:https://www.haomeiwen.com/subject/ltsgbhtx.html