【问题标题】:Vue computed setter get not triggered for array in v-modelv-model中的数组未触发Vue计算的setter
【发布时间】:2018-02-06 16:02:03
【问题描述】:

我有一个值的字符串管道,我想对其进行修改。弦管的值范围为 0-5,所以我做了以下操作:

new Vue({
  el: '#app',
  data: {
    valuesString: ""
  },
  computed: {
    values: {
      get() {
      	var values = this.valuesString ? this.valuesString.split("-") : [];
        if(values.length < 5)
        	values.push(null);
        return values;
      },
      set(values) {
        this.valuesString = values.filter(value => value).join("-")
      }
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
  <div v-for="(value, i) in values" :key="i">
    <select v-model="values[i]" style="width: 200px">
      <option></option>
      <option>1</option>
      <option>2</option>
      <option>3</option>
      <option>4</option>
      <option>5</option>
    </select>
  </div>
  <br>
  <span>valuesString: {{ valuesString }}</span>
  <br>
  <span>values: {{ values }}</span>
</div>

现在的问题是,我计算的 values 属性的设置器没有被调用。

我的用例是一个类似于类别过滤器的过滤器。我从我的路由器获得valuesString 作为参数。用户应该能够选择 1-5 个类别进行过滤。每次过滤器更改时,路由器参数都应该更改,并且应该出现一个新的空选择,直到设置了 5 个类别。

【问题讨论】:

  • 如果我理解正确,您希望用户最多可以选择五个类别并将这些选择的类别构建成一个字符串?
  • 没错,因为字符串是我的路由的参数,所以在站点刷新或路由更改后,我的选择应该已经设置(或更改)

标签: javascript vuejs2 vue-router computed-properties computed-observable


【解决方案1】:

也许我的问题不清楚。 Bert's comment is right

我通过解决方法解决了我的问题,但我不太满意。也许任何人都可以帮助我优化它。为此,我尝试使用计算设置器。

new Vue({
  el: '#app',
  data: {
    values: [],
    valuesString: "",
    allValues: [...Array(5).keys()]
  },
  watch: {
    values (val) {
      if(val.toString() != this.filteredValues.toString()  && val.toString() != this.filteredValues.concat([null]).toString())
        this.$set(this, 'values', this.filteredValues);
      else if (this.valuesString != this.filteredValues.join('-'))
        this.$set(this, 'valuesString', this.filteredValues.join('-'));
    },
    valuesString (valuesString) {
      this.$set(this, 'values', valuesString.split('-'));
    }
  },
  computed: {
    filteredValues () {
      return this.values.filter(v => v);
    },
    modelArray () {
      let size = this.filteredValues.length;
      if(size < 5)
        size++;
      return new Array(size);
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
  <div v-for="(value, i) in modelArray" :key="i">
    <select v-model="values[i]" style="width: 200px">
      <option></option>
      <option v-for="(v, j) in allValues" :key="j" v-if="v == values[i] || filteredValues.indexOf(v.toString()) === -1">{{ v }}</option>
    </select>
  </div>
  <br>
  <span>valuesString: <input v-model="valuesString" /></span>
  <br>
  <span>values: {{ values }}</span>
  <br>
  <span>filteredValues: {{ filteredValues }}</span>
</div>

【讨论】:

    【解决方案2】:

    我不完全确定我理解你在寻找什么,但我认为这会解决问题:

    • 解析管道字符串并将其放入数组中
      • 查看未使用管道的计算属性
    • 遍历数组并将值放入选择框中
      • 循环应该发生在 .结果绑定到 valuesString
    • 应将所选值推送到结果数组并清除选择框。
      • 参见 pushValues 方法。

    Jfiddle example

    <div id="app">
     <div>
       <select v-model="valuesString" @change="pushValues" style="width: 200px">
        <option v-for="p in unpiped">{{p}}</option>
        </select>
      </div>
    <br>
      <span>valuesString: {{ valuesString }}</span>
    <br>
      <span>unpiped: {{ unpiped }}</span>
     <br>
       <span>results: {{ results }}</span>
    </div>
    

    JS:

    new Vue({
    el: '#app',
     data: {
      valuesString: "",
      piped: "1|2|3|4|5",
      results: []
     },
     computed: {
      unpiped(){
        var v = this.piped.split("|");
        return v;
     },
    },
     methods: {
       pushValues: function(){
        this.results.push(this.valuesString)
        this.valuesString = ""
     }
    }
    });
    

    【讨论】:

      猜你喜欢
      • 2019-12-14
      • 1970-01-01
      • 2017-04-16
      • 2019-02-14
      • 2023-02-03
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      相关资源
      最近更新 更多