Vue2:自定义指令,如 v-if

Posted

技术标签:

【中文标题】Vue2:自定义指令,如 v-if【英文标题】:Vue2: Custom Directive Like v-if 【发布时间】:2018-02-20 06:06:25 【问题描述】:

我正在尝试创建一个像 v-if 这样的自定义指令,因此它只会在传递给元素的数据不为空时呈现。例如:

<div v-if="!_.isEmpty(data.employer)"> data.employer.name </div>

仅当 data.employer 不为空时才会呈现,因此不会引发引用错误。我正在尝试创建一个指令,将其简化为 v-notEmpty="data.employer" 并在指令内运行逻辑,但问题是它在呈现元素后对自定义指令执行挂钩,因此它会引发参考错误雇主未定义。

有什么方法可以让自定义指令与 v-if 完全一样,它在实际创建元素之前运行逻辑。这是我到目前为止所拥有的:

    Vue.directive('notEmpty', (el, binding) => 
  if (_.isEmpty(binding.value)) 
    el.style.display =  'none';
   else 
    el.style.display =  'initial';
  
);

【问题讨论】:

这通常可以通过使用 Vue 提供的 slot API 来解决:vuejs.org/v2/guide/… 抱歉,有点迷惑……使用插槽可以解决什么问题?我使用插槽,但不确定如何解决我的问题。你能提供一个简单的例子来说明你的意思吗? 等等...对不起,我完全误读了。我的错。 您有什么特别的原因要使用自定义指令吗? 您尝试做的类似于 v-show 指令,但 v-if 不同。如果条件为假, v-if 不会做任何事情,但是, v-show 仍然会渲染元素,只需使用 css 对其进行切换。所以双花括号中的表达式仍然会被执行,所以你得到了引用错误。 【参考方案1】:

一旦你使用了 Lodash,_.get() 函数可能是一个更简单的解决方案。它提供了对嵌套对象属性的安全访问。一个简单的例子:

new Vue(
    data: 
        employer: 
            name: 
              first: 'Eric',
              last: '',
            ,
            age: 26
        
    ,

    methods: 
        /**
         * Check if a property exists and returns a boolean
         * 
         * @param String e Path to check
         * @param Object o Object to be accessed
         * 
         * @return Boolean
         */
        notEmpty(o, e) 
            let getResult = _.get(o, e);
            return !(getResult == false || getResult == null || getResult == '' || getResult == undefined);
        
    
).$mount('#app');
<div id="app">
  <p v-if="notEmpty(employer, 'name.first')">employer.name.first</p>
  <p v-else>First name not informed</p>
  
  <p v-if="notEmpty(employer, 'name.last')">employer.name.last</p>
  <p v-else>Last name not informed</p>
  
  <!-- Age will not appear, once is not defined -->
  <p v-if="notEmpty(employer, 'age')">employer.age</p>
  <p v-else>Age not informed</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://unpkg.com/vue@2.5.17/dist/vue.min.js"></script>

查看Lodash _.get() 函数。太牛了。

【讨论】:

【参考方案2】:

您需要在绑定钩子函数中编写指令代码。 (Reference)

绑定

仅在指令第一次绑定到元素时调用一次。在这里您可以进行一次性设置工作。

所以你的代码应该是:

Vue.directive('notEmpty', 
  bind: function (el, binding, vnode) 
    if (_.isEmpty(binding.value)) 
      el.style.display =  'none';
     else 
      el.style.display =  'initial';
    
  
);

【讨论】:

我已经尝试过了 :(,它仍在尝试在调用绑定之前评估 data.employer.name,因此它仍然会引发错误。

以上是关于Vue2:自定义指令,如 v-if的主要内容,如果未能解决你的问题,请参考以下文章

vue中自定义指令

Vue2.0笔记——自定义指令

vuejs中类似于v-if的自定义指令

Vue2.x directive自定义指令

Vue.js---自定义指令

07.自定义指令传参小窍门