【问题标题】:Bootstrap vue select sending old valueBootstrap vue 选择发送旧值
【发布时间】:2019-04-05 23:58:15
【问题描述】:

我得到了这个基于 vue bootstrap 的选择代码:

<b-form-select v-model="selectedgroup" class="mb-3"  @change="searchSubGroup()">
    <option :value="null">Select a group</option>
    <option v-for="group in groupItem" :value="group.id">
        {{group.nome}}
    </option>
</b-form-select>  

当@change 事件调用searchSubGroup() 方法时,@change 事件传递一个旧值selectedgroup。示例:如果我首先单击 value = 1 的选项,该方法将调用 selectedgroup 作为null,然后如果我再次单击另一个 value = 2 的选项,该方法将调用 selectedgroup 作为 1。

searchSubGroup(){ 
  this.axios.get("http://chart.solutions/public/api/produto/subgroup/search/" + this.selectedgroup + "/").then(response => {
        if (response.data.erro) {
            //console.log("subgroup doesnt exist")
        }else{
            this.subGroupItem = response.data;
        }
    })
} 

【问题讨论】:

  • 你能分享searchSubGroup()的代码吗?
  • 主题已更新,谢谢
  • 嗯,我认为有必要使用更多的变量和方法,我知道您需要为该组件提供一个数组,但是您从该 get 请求中收到了什么?您尝试迭代的数组上的值是什么? selectedgroup 是什么?
  • selectedgroup 只是一个数据,我这样开始: selectedgroup: null。与文档中的方法相同。似乎@change 在更改 v-model 之前获得了价值
  • 从@change 调用中移除 () ;p @change="searchSubGroup"

标签: javascript vue.js vuejs2 vue-component bootstrap-vue


【解决方案1】:

您应该调用不带括号的searchSubGroup 方法。这将自动将新选择的值传递给您的方法..

<b-form-select v-model="selectedgroup" class="mb-3"  @change="searchSubGroup">
    <option :value="null">Select a group</option>
    <option v-for="group in groupItem" :value="group.id">
        {{group.nome}}
    </option>
</b-form-select>

然后在您的方法中,您应该执行以下操作..

searchSubGroup(value){ 
  this.axios.get("http://chart.solutions/public/api/produto/subgroup/search/" + value + "/").then(response => {
        if (response.data.erro) {
            //console.log("subgroup doesnt exist")
        }else{
            this.subGroupItem = response.data;
        }
    })
} 

【讨论】:

  • 这实际上是相同的答案,只是您没有解释它为什么起作用。当您删除括号并捕获 VALUE 时,您将跳过这个问题,即 v-model 的 @change 调用是在 AFTER 之后进行的,因此在调用该方法时“this.selectedgroup”为 NULL。
  • @Marina 我不得不恭敬地不同意。他的问题是他正在使用储值。而不是通过等待nextTick 或其他策略来等待事件发生后更新该值,他可以只使用事件本身发出的值。
  • @HusamIbrahim 正是。因为他正在使用存储的值(正在第二次更改调用中更新),所以问题正在发生。如果您查看文档:bootstrap-vue.js.org/docs/components/form-select 在事件下,您可以看到更改甚至是在用户输入时触发的,这意味着当点击交互发生时组件正在触发它自己的更改事件。当他改变函数以接受一个值时,他正在规避这个问题,就像使用一个被监视的道具一样——但重要的是要了解为什么。无论哪种方式,好的答案,它都有效。
  • @Marina 我同意。给猫剥皮的方法有很多。我只是认为这是最直接和惯用的方式。干杯:)
【解决方案2】:

您需要像这样从@change 调用中删除 ():

@change="searchSubGroup"

如果您保留 () 设置,则在构建组件时调用该函数,并且“选定组”仍未定义,因此使用 null 调用

v-model 基于@change 工作,因此事件会被触发两次。在更新 v-model 数据的 change 方法之前调用 selectedGroup 方法。这就是为什么价值是“旧的”。

尽管其他答案仍然是避免问题的正确方法,但它并不能准确解释为什么会发生这种情况。

这是另一种解决方案:

  1. 从 b-form-select 中删除您的 @change 调用
  2. 添加一个“监视”属性

    watch: { selectedgroup(value) { this.searchSubGroup(); //OR you could remove the method and just call axios here }) }

【讨论】:

  • 为什么它会更新为新值? searchSubGroup 是否只被调用一次或每次触发事件时也被调用?
  • @IvanS95 它在加载时被调用一次,然后是随后的触发器。唯一一次将 ( ) 添加到 prop 内的方法调用是当你要传递一个值 @change="method(item)" 时,否则它会在渲染时被调用。此外,这将取决于 OP 的 API 是如何工作的。也许它允许空调用?
  • 我刚刚注意到别的东西,v-model 实际上也调用了@change。所以我要编辑我的答案,给我一分钟
【解决方案3】:

您可以使用@input 代替@change 事件,因为@input="searchSubGroup" 返回当前选定的项目

new Vue({
  el: '#app',

  data() {
    return {
      selected: null,
      options: [{
          value: null,
          text: 'Please select some item'
        },
        {
          value: 'a',
          text: 'This is option a'
        },
        {
          value: 'b',
          text: 'Default Selected Option b'
        },
        {
          value: 'c',
          text: 'This is option c'
        },
        {
          value: 'd',
          text: 'This one is disabled',
          disabled: true
        },
        {
          value: 'e',
          text: 'This is option e'
        },
        {
          value: 'e',
          text: 'This is option f'
        }
      ]
    }
  },
  methods: {
    choose() {
      console.log(this.selected)
    }
  }

});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" href="style.css">
  <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
  <link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />

  <!-- Add this after vue.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
  <script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
  <script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

</head>

<body>

  <div id="app">

    <b-form-select v-model="selected" :options="options" class="mb-3" @input="choose">
    </b-form-select>
    <div>Selected: <strong>{{ selected }}</strong></div>
  </div>

  <script src="script.js"></script>
</body>

</html>

【讨论】:

    猜你喜欢
    • 2019-03-14
    • 2020-07-29
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 2020-09-26
    • 2021-04-23
    • 2019-11-01
    • 2019-04-05
    相关资源
    最近更新 更多