Vuejs: Callback after render

2020-07-09 07:34发布

I have a Bootstrap popover that I want to attach to an element that has a conditional render; therefore, I must trigger $().popover() after the element has been attached to the DOM.

Is there a way to trigger a callback after a v-if statement inserts the elements into the DOM?

3条回答
SAY GOODBYE
2楼-- · 2020-07-09 08:12

The right way to do this, is making it a directive, so you can hook into the life cycle of a DOM element.

Using nextTick is not the right way to do it for a few reasons, it can break if the DOM reacts and re render a part of your view. You are not destroying tooltips after initialisation. This can break because nextTick is async, and something in between render and nextTick can change your DOM state.

https://vuejs.org/v2/guide/custom-directive.html

/* Enable Bootstrap popover using Vue directive */
Vue.directive('popover', {
    bind: bsPopover,
    update: bsPopover,
    unbind (el, binding) {
        $(el).popover('destroy');
    }
});
function bsPopover(el, binding) { 
    let trigger;
    if (binding.modifiers.focus || binding.modifiers.hover || binding.modifiers.click) {
        const t = [];
        if (binding.modifiers.focus) t.push('focus');
        if (binding.modifiers.hover) t.push('hover');
        if (binding.modifiers.click) t.push('click');
        trigger = t.join(' ');
    }
    
    $(el).popover('destroy'); //update
    $(el).popover({
        title: typeof binding.value==='object'? binding.value.title : undefined,
        content: typeof binding.value==='object'? binding.value.content : binding.value,
        placement: binding.arg,
        trigger: trigger,
        html: binding.modifiers.html
    });
}


//DEMO
new Vue({
  el: '#app',
  data: {
    foo: "Hover me",
    bar: "There",
    baz: {content: "<b>Hi</b><br><i>There</i>", title: "Test"},
  }
});
<link href="https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/bootstrap@3.3.7/dist/js/bootstrap.js"></script>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>


<div id="app">
  <h4>Bootstrap popover with Vue.js Directive</h4>
  <br>
  <input v-model="foo" v-popover.hover="foo"/>
  <button v-popover.click="bar">Click me</button>
  <button v-popover.html="baz">Html</button>
  <br>
  <button v-popover:top="foo">Top</button>
  <button v-popover:left="foo">Left</button>
  <button v-popover:right="foo">Right</button>
  <button v-popover:bottom="foo">Bottom</button>
  <button v-popover:auto="foo">Auto</button>
</div>

查看更多
Evening l夕情丶
3楼-- · 2020-07-09 08:19

Vue.nextTick() defers the execution of the callback to be executed after the next update of the DOM, see: VueJS API reference

查看更多
疯言疯语
4楼-- · 2020-07-09 08:31

Use this in vuejs 2:

updated: function() {
    $('[data-toggle="tooltip"]').tooltip();
},

take a look here

查看更多
登录 后发表回答