【问题标题】:Custom vue directive to render only if present自定义 vue 指令仅在存在时呈现
【发布时间】:2018-07-12 00:28:07
【问题描述】:

通常,我只想在 div (或其他元素)有内容时才渲染它。这意味着重复对标签中内容的引用,以及在 v-if 中,像这样......

<div v-if="store.sometimesIWillBeEmpty">{{store.sometimesIWillBeEmpty}}</div>

使用自定义指令,我想创建一个指令 v-fill,它的行为与上面的代码一样,但语法更简单...

<div v-fill="store.sometimesIWillBeEmpty"></div>

更新 当消息不为空时,以下工作。当消息为空时,我应该设置或清除什么以不呈现任何内容?

var store = {message: "hello cobber"}
Vue.directive('fill', 
  function (el, binding, vnode) {
    if(binding.value)
      el.innerHTML = binding.value
    else
      el = null
  }
);

new Vue({
  el: '#fill-example',
  data: {
    store: store
  }
})

我就在一条线上。 Here's my fiddle.有人有什么想法吗?

【问题讨论】:

  • 不要eval(binding.expression);使用binding.value
  • 好吧,我比我想象的更接近。奇迹般有效。你想把它作为一些筹码的答案吗?
  • 更新:不完全工作。我已经更新了代码和问题。 else 部分给我带来了问题。
  • 为什么不在el.innerHTML = null之后呢?
  • 不错的尝试,但没有。关键是如果没有内容,尝试让包含元素消失。如果我执行 el.outerHTML = "",我可以摆脱我的元素,但如果消息再次出现,它就不会回来。

标签: vue.js


【解决方案1】:

可以制作一个简单的组件来做你想做的事。指令需要更多操作才能移除元素并将其放回正确的位置。

const vm = new Vue({
  el: '#fill-example',
  data: {
    empty: '',
    notEmpty: 'I have content'
  },
  components: {
    renderMaybe: {
      props: ['value'],
      template: `<div v-if="value" class="boxy">{{value}}</div>`
    }
  },
  directives: {
    fill: {
      bind(el, binding) {
        Vue.nextTick(() => {
          el.vFillMarkerNode = document.createComment('');
          el.parentNode.insertBefore(el.vFillMarkerNode, el.nextSibling);
          if (binding.value) {
            el.textContent = binding.value;
          } else {
            el.parentNode.removeChild(el);
          }
        });
      },
      update(el, binding) {
        if (binding.value) {
          el.vFillMarkerNode.parentNode.insertBefore(el, el.vFillMarkerNode);
          el.textContent = binding.value;
        } else {
          if (el.parentNode) {
            el.parentNode.removeChild(el);
          }
        }
      }
    }
  }
});

setTimeout(() => {
  vm.empty = "Now I have content, too.";
}, 1500);
.boxy {
  border: thin solid black;
  padding: 1em;
}
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="fill-example">
  Components:
  <render-maybe :value="empty"></render-maybe>
  <render-maybe :value="notEmpty"></render-maybe>
  Directives:
  <div class="boxy" v-fill="empty"></div>
  <div class="boxy" v-fill="notEmpty"></div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    相关资源
    最近更新 更多