Vue Directive 没有更新它的值 - Jquery Chosen

Posted

技术标签:

【中文标题】Vue Directive 没有更新它的值 - Jquery Chosen【英文标题】:Vue Directive not updating it's value - Jquery Chosen 【发布时间】:2018-04-27 06:47:35 【问题描述】:

我正在使用 Jquery Chosen 和 Vue。这是我的 Vue 指令:

Vue.component("chosen-select", 
    props: 
        value: [String, Array],
        multiple: Boolean
    ,
    template: `<select :multiple="multiple"><slot></slot></select>`,
    mounted() 
        $(this.$el)
            .val(this.value)
            .chosen( width: '100%' )
            .on("change", e => this.$emit('input', $(this.$el).val()))
    ,
    watch: 
        value(val) 
            $(this.$el).val(val).trigger('chosen:updated');
        
    ,
    destroyed() 
        $(this.$el).chosen('destroy');
    
);

并像这样使用它:

<chosen-select v-model="basicDetailsModel.stateID" v-validate="'required'" data-vv-as="state" :state="errors.has('stateID') ? 'invalid' : 'valid'" name="stateID">
                        <option :value="null">Please select an option</option>
                        <option v-for="(state, index) in states" :key="index" :value="state.sid">state.nm</option>
                    </chosen-select>

如果为状态分配了静态值,它可以按预期正常工作,但是如果我动态获取状态值,则选择的值不会更新为最新值。它保持初始值。

我该如何解决这个问题?

编辑:这个有效。你认为这是正确的方法吗?

Vue.component("chosen-select", 
    data() 
        return  observer: null 
    ,
    props: 
        value: [String, Array],
        multiple: Boolean
    ,
    template: `<select :multiple="multiple"><slot></slot></select>`,
    mounted() 
        // Create the observer (and what to do on changes...)
        this.observer = new MutationObserver(function (mutations) 
            $(this.$el).trigger("chosen:updated");
        .bind(this));

        // Setup the observer
        this.observer.observe(
            $(this.$el)[0],
             childList: true 
        );
        $(this.$el)
            .val(this.value)
            .chosen( width: '100%' )
            .on("change", e => this.$emit('input', $(this.$el).val()))
    ,
    watch: 
        value(val) 
            $(this.$el).val(val);
        
    ,
    destroyed() 
        $(this.$el).chosen('destroy');
    
);

【问题讨论】:

【参考方案1】:

解决此问题的最简单方法是在您有使用v-if 进行渲染的选项之前不渲染选择。

<chosen-select v-if="states && states.length > 0" v-model="basicDetailsModel.stateID" v-validate="'required'" data-vv-as="state" :state="errors.has('stateID') ? 'invalid' : 'valid'" name="stateID">

您还可以尝试在组件更新时发出 chosen:updated 事件。

updated()
  $(this.$el).trigger("chosen:updated")
,

它适用于多选,但神秘地不适用于单选。

【讨论】:

我最初尝试更新工作,但可能效率低下,因为每次更新都会被调用,即使 v-model 的属性发生更改(发生选择更改)。我从***.com/questions/38148297/… 中找到了一些灵​​感,并相应地更改了我的代码。请参阅我有问题的编辑。告诉我情况如何。【参考方案2】:

我不确定您是如何动态获取状态的,但是如果您使用 jQuery 来获取它们,那么我认为这是您的问题。如果非 Vue 的东西(比如 jQuery)改变了任何东西,Vue 不会得到通知。 即使不是这样,this 也值得一读,看看为什么 jQuery 和 Vue 不能相处。 您可以添加动态获取它们的方式吗? 另外,可以考虑使用像 Vuetify 这样的 Vue 框架,它有一个非常好的选择控件并且完全在 Vue 中。

【讨论】:

以上是关于Vue Directive 没有更新它的值 - Jquery Chosen的主要内容,如果未能解决你的问题,请参考以下文章

Vue 自定义指令 directive

Directive 自定义指令

vue自定义指令directive

angularjs脏检查

参考书籍《Vue.js快跑:构建触手可及的高性能Web应用》第1章 Vue.js基础--模板(Template)数据(Data)和指令(Directive)

Vue.directive为啥要在实例初始化之前