代码之家  ›  专栏  ›  技术社区  ›  vimuth

Vue js与jquery get的问题

  •  0
  • vimuth  · 技术社区  · 6 年前

    嗨,我正在尝试通过ajax和vue包装组件获取数据。这是我的密码。

      <html>
        <head>
            <title>title</title>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <style>
                html, body {
                    font: 13px/18px sans-serif;
                }
                select {
                    min-width: 300px;
                }
            </style>
        </head>
        <body>
            <div id="el"></div>
    
            <!-- using string template here to work around HTML <option> placement restriction -->
            <script type="text/x-template" id="demo-template">
                <div>
                <p>Selected: {{ input.selected }}</p>
                <select2 :options="options" v-model="input.selected">
                <option disabled value="0">Select one</option>
                </select2>
                </div>
            </script>
    
            <script type="text/x-template" id="select2-template">
                <select>
                <slot></slot>
                </select>
            </script>
            <script src="http://themestarz.net/html/craigs/assets/js/jquery-3.3.1.min.js"></script>
            <script src="https://unpkg.com/vue@2.5.17/dist/vue.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
            <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
            <script>
                Vue.component('select2', {
                    props: ['options', 'value'],
                    template: '#select2-template',
                    mounted: function () {
                        var vm = this;
                        $(this.$el)
                                // init select2
                                .select2({data: this.options})
                                .val(this.value)
                                .trigger('change')
                                // emit event on change.
                                .on('change', function () {
                                    vm.$emit('input', this.value)
                                });
                    },
                    watch: {
                        value: function (value) {
                            // update value
                            $(this.$el)
                                    .val(value)
                                    .trigger('change')
    
    
    
                        },
                        options: function (options) {
                            // update options
                            $(this.$el).empty().select2({data: options})
                        }
                    },
                    destroyed: function () {
                        $(this.$el).off().select2('destroy')
                    }
                })
    
                var vm = new Vue({
                    el: '#el',
                    template: '#demo-template',
                    data: {
                        input: {
                            selected: "all"
                        },
                        options: []
                    },
                    created: function () {
                        this.mymethod();
                    },
                    methods: {
                        mymethod: function () {
                            var vm = this;
    
    
                            $.get("https://api.coindesk.com/v1/bpi/currentprice.json", function (data) {
                                vm.options = [
                                    {id: 'all', text: 'All'},
                                    {id: 1, text: 'Hello'},
                                    {id: 2, text: 'World'},
                                    {id: 3, text: 'Bye'}
                                ];
    
                                vm.input.selected = 2;
                            });
                        }
                    }
                });
            </script>
        </body>
    </html>
    

    在项目加载到下拉列表后,我需要像这样更改所选项目

    vm.input.selected = 2;
    

    但不幸的是,在ajax请求之后,这并没有发生。如果我在ajax之前添加了数组,它会按照预期的那样发生,但是我需要ajax请求中的数据。我还降低了代码的复杂性,以提高可视性。 jsfiddle 这是个问题。我认为问题在于vue组件。

    1 回复  |  直到 6 年前
        1
  •  1
  •   ChrisG    6 年前

    我做了一些测试,看起来你基本上改变了select2的值 之前 它的选项,以及自选项 2 不存在,改变失败了。

    正如我在评论中提到的,改变 options value 在组件的 watch 修复了这一问题,可能是因为这样在设置新值之前就更改了选项。

    工作示例:

    Vue.component('select2', {
      props: ['options', 'value'],
      template: '#select2-template',
      mounted: function() {
        var vm = this;
        $(this.$el)
          // init select2
          .select2({
            data: this.options
          })
          .val(this.value)
          .trigger('change')
          // emit event on change.
          .on('change', function() {
            vm.$emit('input', this.value)
          });
      },
      watch: {
        options: function(options) {
          // update options
          $(this.$el).empty().select2({
            data: options
          })
        },
        value: function(value) {
          // update value
          $(this.$el)
            .val(value)
            .trigger('change')
        }
      },
      destroyed: function() {
        $(this.$el).off().select2('destroy')
      }
    })
    
    var vm = new Vue({
      el: '#el',
      template: '#demo-template',
      data: {
        input: {
          selected: "all"
        },
        options: []
      },
      created: function() {
        this.mymethod();
      },
      methods: {
        mymethod: function() {
          var vm = this;
          $.get("https://api.coindesk.com/v1/bpi/currentprice.json", function(data) {
            vm.options = [{
                id: 'all',
                text: 'All'
              },
              {
                id: 1,
                text: 'Hello'
              },
              {
                id: 2,
                text: 'World'
              },
              {
                id: 3,
                text: 'Bye'
              }
            ];
            vm.input.selected = 2;
            //      setTimeout(() =>  { vm.input.selected = 2; }, 0);
          });
        }
      }
    });
    html,
    body {
      font: 13px/18px sans-serif;
    }
    
    select {
      min-width: 300px;
    }
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script type="text/javascript" src="https://unpkg.com/vue@2.5.17/dist/vue.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
    <div id="el"></div>
    
    <!-- using string template here to work around HTML <option> placement restriction -->
    <script type="text/x-template" id="demo-template">
      <div>
        <p>Selected: {{ input.selected }}</p>
        <select2 :options="options" v-model="input.selected">
          <option disabled value="0">Select one</option>
        </select2>
      </div>
    </script>
    
    <script type="text/x-template" id="select2-template">
      <select>
        <slot></slot>
      </select>
    </script>