【问题标题】:Vue2: Custom Directive Like v-ifVue2:自定义指令,如 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 对其进行切换。所以双花括号中的表达式仍然会被执行,所以你得到了引用错误。

标签: vue.js vuejs2 vue-component


【解决方案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,因此它仍然会引发错误。
    猜你喜欢
    • 2019-05-22
    • 2017-08-17
    • 2021-04-23
    • 1970-01-01
    • 2015-02-15
    • 2018-12-20
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多