【问题标题】:Update vuejs model value using jquery-chosen plugin使用 jquery-chosen 插件更新 vuejs 模型值
【发布时间】:2015-09-27 17:21:28
【问题描述】:

尝试将jquery-chosen与vue一起使用,问题是这个插件隐藏了我应用v-model的实际选择,所以当我选择一个值时,vue不会将它识别为选择更改事件并且模型值是没有更新。

当我选择某些东西时,选择的值实际上正在改变,我用 console.log 检查了它以查看选定的值。

http://jsfiddle.net/qfy6s9Lj/3/

我可以做vm.$data.city = $('.cs-select').val()that 似乎工作, 但是还有其他选择吗?如果 select 的值发生了变化,为什么 vue 看不到这个?

【问题讨论】:

    标签: jquery-chosen vue.js


    【解决方案1】:

    我愿意接受其他建议,但暂时我是这样做的:

    html

    <div id='search-results'>
        {{city}}
        <select class="cs-select" v-model='city'>
            <option value="Toronto">Toronto</option>
            <option value="Orleans">Orleans</option>
        </select>
    </div>
    

    js

    window.vm = new Vue({
      el: '#search-results',
      data: {
        city: 'Toronto',
      }
    })
    
    $('.cs-select').chosen({
        inherit_select_classes: true,
        width: '30%'
    }).change( function() {
        vm.$data.city = $('.cs-select').val()
    })
    

    【讨论】:

      【解决方案2】:

      回答: http://jsfiddle.net/qfy6s9Lj/5/

      <div id='search-results'>
          Vue model value <br>
          {{city}}
          <hr>
          Select value:
          <select class="cs-select" v-chosen>
             <option value="Toronto">Toronto</option>
             <option value="Orleans">Orleans</option>
          </select>
      </div>
      
      Vue.directive('chosen', {
          bind: function () {
              var vm = this.vm;
              this.el.options = vm.cities;
              this.el.value = vm.city;       
      
              $(this.el).chosen({
                  inherit_select_classes: true,
                  width: '30%',
                  disable_search_threshold: 999})
              .change( function() {
                   vm.city = this.el.value;
               }.bind(this)
            );
          }
      });
      
      var vm = new Vue({
        data: {
            city: 'Toronto',
            cities: ['Toronto', 'Orleans']
        }
      }).$mount("#search-results");
      

      更新:更好的解决方案(感谢 simplesmiler): http://jsfiddle.net/simplesmiler/qfy6s9Lj/8/

      【讨论】:

      • 这似乎不适用于具有多个(多选)属性的选择标签。
      【解决方案3】:

      @swift 的答案非常接近,但正如@bertrand 指出的那样,它不适用于多选。我已经找到了适用于这两种情况的方法:http://jsfiddle.net/seanwash/sz8s99xx/

      我本来只想发表评论,但我没有足够的代表这样做。

      Vue.directive('chosen', {
          twoWay: true, // note the two-way binding
          bind: function () {
              $(this.el)
                  .chosen({
                      inherit_select_classes: true,
                      width: '30%',
                      disable_search_threshold: 999
                  })
                  .change(function(ev) {
                      // two-way set
                      // Construct array of selected options
                      var i, len, option, ref;
                      var values = [];
                      ref = this.el.selectedOptions;
                      for (i = 0, len = ref.length; i < len; i++) {
                          option = ref[i];
                          values.push(option.value)
                      }
                      
                      this.set(values);
                      
                  }.bind(this));
          },
          update: function(nv, ov) {
              // note that we have to notify chosen about update
              $(this.el).trigger("chosen:updated");
          }
      });
      
      var vm = new Vue({
        data: {
            city: 'Toronto',
            cities: [{text: 'Toronto', value: 'Toronto'}, 
                     {text: 'Orleans', value: 'Orleans'}]
        }
      }).$mount("#search-results");

      【讨论】:

      【解决方案4】:

      我为 vue2 做了更新。

      Vue.directive('chosen', {
          selected: null,
          inserted: function (el, binding) {
              selected = binding.value;
              $(el).chosen().change(function(event, change) {
                  if(change.hasOwnProperty('selected')) {
                      selected.push(change.selected);
                  } else {
                      selected.splice(selected.indexOf(change.deselected), 1);
                  }
              });
          },
          componentUpdated: function(el, binding) {
              selected = binding.value;           
              $(el).trigger("chosen:updated");
          }
      });
      
      var vm = new Vue({
         el: '#app',
         data: {
            selected: [],
            cities: [{id: 1, value: "Toronto"}, {id: 2, value: "Orleans"}, {id: 3, value: "Bern"}]
         }
      });
      

      见:https://jsfiddle.net/kaktuspalme/zenksm2b/

      【讨论】:

      • 太棒了!谢谢你的小提琴!
      • 这似乎不适用于非multiple 选择元素。另外,selected: null 是什么?这似乎是多余的?还有你写selected = binding.value的地方,你不是设置了全局变量吗?
      【解决方案5】:

      更新:请注意,这在 v-for 循环中不起作用。 here 提供了一个相关的问题。

      脱离@kaktuspalme 的解决方案,在我朋友 Joe Fleming 的帮助下,我想出了一个适用于 Vue 2 并允许单选和多选的解决方案:

      Vue.directive('chosen', {
          inserted: function(el, binding, vnode) {
              jQuery(el).chosen().change(function(event, change) {
                  if (Array.isArray(binding.value)) {
                      var selected = binding.value;
                      if (change.hasOwnProperty('selected')) {
                          selected.push(change.selected);
                      } else {
                          selected.splice(selected.indexOf(change.deselected), 1);
                      }
                  } else {
                      var keys = binding.expression.split('.');
                      var pointer = vnode.context;
                      while (keys.length > 1)
                          pointer = pointer[keys.shift()];
                      pointer[keys[0]] = change.selected;
                  }
              });
          },
          componentUpdated: function(el, binding) {
              jQuery(el).trigger("chosen:updated");
          }
      });
      

      像这样使用它:

      <select v-model="mymodel" v-chosen="mymodel">...</select>
      

      它适用于multiple="multiple",甚至适用于嵌套状态,例如:

      <select v-model="nested.mymodel" v-chosen="nested.mymodel">...</select>
      

      在这里查看小提琴:https://jsfiddle.net/tylercollier/bvvvgyp0/5/

      【讨论】:

        【解决方案6】:

        取自@kaktuspalme 答案的代码。它现在适用于非多重元素,并且仅适用于非多重元素。

         Vue.directive('chosensingle', {
        
        inserted: function (el, binding) {
            var selected = binding.value;
        
            $(el).chosen().change(function(event, change) {
        
                if(change.hasOwnProperty('selected')) {
                    selected.value = change.selected;                
                } else {
                    selected.value  ='';
                }
            });
        },
        componentUpdated: function(el, binding) {
        
            $(el).trigger("chosen:updated");
        }
        });
        

        考虑@Tyler Collier 的评论

        但请注意,您在 v-model 中使用的属性应定义为数组,例如申请人Id:[]否则不起作用

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-06
          • 2019-08-29
          • 1970-01-01
          • 2018-04-27
          • 2013-03-10
          相关资源
          最近更新 更多