如何更改自定义 Vue 指令的 binding.value

Posted

技术标签:

【中文标题】如何更改自定义 Vue 指令的 binding.value【英文标题】:How to change custom Vue directive's binding.value 【发布时间】:2019-11-19 12:22:00 【问题描述】:

我正在使用 v-for 循环并使用 Vue.directive 作为引导工具提示,它将绑定值设置为我从方法返回的字符串。有了新数据后,如何更改此绑定值?即使我的方法返回了新数据,它也不会更新。

我尝试创建一个数据变量并在我的方法中设置它并在我的指令中使用该变量,但它仍然没有改变。

Vue.directive('tooltip',
        function(el, binding) 
            $(el).tooltip(
                title: binding.value,
                placement: binding.arg,
                trigger: 'hover'
            );
        );


<li v-for="(display_name, index) in displayNameList" class="nav-item">
    <a v-tooltip:bottom="tabTooltipSet(index)"  display_name </a>
</li>

我希望 binding.value 更改为函数在调用时返回的任何内容,它最初会这样做。但是在设置了该值并且我的 displayNameList 可以完全更改之后,它不会相应地更新。因此,如果我的第一个选项卡设置为 DOG,然后我更改列表并将其设置为 CAT,则工具提示应该是 CAT 而不是 DOG。

【问题讨论】:

来自文档:bind:仅在指令第一次绑定到元素时调用一次。在这里您可以进行一次性设置工作 您是否将控制台日志记录放在该函数中?数据更改时根本没有调用它还是以错误的值再次调用它?就我个人而言,我对 $(el).tooltip 持怀疑态度,不确定如果您在同一元素上再次调用它会如何。 @Bergur 就是这样,我需要多次执行此操作(当数据更改时)我可能完全滥用了该指令,但我不确定此时我需要什么。 @skirtle 再次使用正确的值调用它,但即使在数据更改后传入了正确的值,绑定值也不会改变。关于变通的任何想法? @Turtle_Code 我不太明白,你说值是正确的,然后你说它不是。如果 binding.value 的值在该函数中是正确的,那么这里就不存在 Vue 问题。更有可能是$(el).tooltip 的问题。在添加新工具提示之前,请尝试使用 $(el).tooltip('dispose') 删除旧工具提示。 【参考方案1】:

Vue 指令似乎工作正常。问题是在同一个元素上调用tooltip() 两次不会更新工具提示。在我的示例中,我刚刚销毁了之前的工具提示并添加了一个新的。这样做的方法可能不那么严厉,但它似乎是实现预期结果的最简单方法。

Vue.directive('tooltip', function(el, binding) 
  if (binding.value === binding.oldValue) 
    return
  

  $(el).tooltip('dispose')

  $(el).tooltip(
    title: binding.value,
    placement: binding.arg,
    trigger: 'hover'
  );
);

new Vue(
  el: '#app',
  
  data () 
    return 
      displayNameList: ['Red', 'Green', 'Blue'],
      tooltipNumber: 0
    
  ,
  
  methods: 
    onClick () 
      this.tooltipNumber++
    ,

    tabTooltipSet (index) 
      return this.displayNameList[index] + ' tooltip ' + this.tooltipNumber
    
  
)
.nav-item 
  background: #ccc;
  border: 1px solid #000;
  list-style: none;
  margin: 10px auto;
  width: 100px;


.nav-item a 
  display: block;
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>

<div id="app">
  <ul>
    <li v-for="(display_name, index) in displayNameList" class="nav-item">
      <a v-tooltip:bottom="tabTooltipSet(index)"> display_name </a>
    </li>
  </ul>
  <button @click="onClick">Update tooltips</button>
</div>

我已经检查了值是否已更改,以避免不必要地创建/销毁工具提示。更强大的版本需要检查放置是否也发生了变化。您还应该使用指令的 unbind 钩子正确处理销毁工具提示,因为如果没有它,似乎可能会有泄漏。

【讨论】:

以上是关于如何更改自定义 Vue 指令的 binding.value的主要内容,如果未能解决你的问题,请参考以下文章

vue3.0 如何自定义指令

vue3.0 如何自定义指令

vue3.0 如何自定义指令

Vue自定义指令

Vue自定义指令组件过滤器如何创建

vue3.2 setup 之局部自定义指令