【问题标题】:Vue 2 - How to select the correct <select> option after the data is fetched from dbVue 2 - 从数据库中获取数据后如何选择正确的 <select> 选项
【发布时间】:2017-01-19 23:16:30
【问题描述】:

我将 Vue 2 用于一个小型博客项目。我有一个用于帖子表单的单独组件,其中一个表单输入是一个选择(用于帖子的类别)。从数据库中获取类别后,选择会被填充。该组件还从父组件获取post 对象,该对象也是从数据库中获取的(参见props: ['post'])。

代码如下:

// HTML
...
<select class="form-control" v-model="post.category_id">
    <option 
        v-for="cat in categories" 
        v-bind:value="cat.id">
        {{ cat.name }}
    </option>
</select>
...

// JS
module.exports = {
    props: ['post', 'url'],
    name: 'postForm',
    created: function() {
        this.syncCats()
    },
    methods: {
        syncCats: function() {
            this.$http.get("/api/categories")
            .then(function(res) {
                this.categories = res.data 
            })
        }
    },
    data: function() {
        return {
            categories: {}
        }
    }
}

我遇到的问题是默认情况下没有选择任何选项。它看起来像this。但是当我打开选择时,我会从我的数据库中看到这两个类别,例如this

我想默认选择正确的 (post.category_id == cat.id) 值。我该怎么做?

我试过&lt;select ... :v-bind:selected="post.category_id == cat.id"&gt;,但同样发生了。

编辑

好的,现在我尝试像这样倾倒post.category_idcat.id

<div class="form-group">
  <label>Category</label>
  <select class="form-control" v-model="post.category_id">
    <option 
        v-for="cat in categories" 
        :value="cat.id"
        :selected="cat.id == post.category_id">
        {{ cat.name }} {{ cat.id }} {{ post.category_id }}
    </option>
  </select>
</div>

在我选择任何选项之前的结果是 this - 只有 cat.id 会被打印,post.category_id 不会。但是,在我选择某个选项后,我也会出现 post.category_id,例如 this。请注意,在我选择了其中一个选项({{ post.category_id }})之后,末尾的“1”仅出现在第二张屏幕截图中。

这意味着帖子是在类别之后加载的,我应该在加载后以某种方式重新初始化选择。我该怎么做?作为参考,这是获取帖子的父组件。

<template>
    <span id="home">
        <postForm :post="post" :url="url"></postForm>
    </span>
</template>
<script>
var postForm = require('../forms/post.vue')

module.exports = {
    name: 'postEdit',
    created: function() {
        this.$http.get('api/posts/slug/' + this.$route.params.slug)
        .then(function(response) {
            if(response.status == 200) {
                this.post = response.data
                this.url = "/api/posts/slug/" + response.data.slug
            }
        })
    },
    data: function() {
        return {
            post: {},
            url: ""
        }
    },
    components: {
        postForm
    }
}
</script>

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    您需要在适当的&lt;option&gt; 上设置selected 属性并遵守Vue 的one-way data flow 范例。

    您甚至可以通过禁用&lt;select&gt; 来添加一些额外的可用性糖,直到postcategories 都被加载...

    <select class="form-control" 
            :disabled="!(post.category_id && categories.length)"
            @input="setCategoryId($event.target.value)">
      <option v-for="cat in categories"
              :value="cat.id"
              :selected="cat.id == post.category_id">
        {{cat.name}}
      </option>
    </select>
    

    methods: {
      setCategoryId(categoryId) {
        this.$emit('input', parseInt(categoryId))
      }
    }
    

    那么,在包含上述的Vue实例/组件中,简单的使用

    <post-form :post="post" :url="url"
               v-model="post.category_id"></post-form> 
    

    更多信息请参见Components - Form Input Components using Custom Events

    JSFiddle 演示~https://jsfiddle.net/1oqjojjx/267/


    仅供参考,我还将 categories 初始化为一个数组,而不是一个对象...

    data () {
      return {
        categories: []
      }
    }
    

    【讨论】:

    • 是的,初始化数组很有意义。然而这并没有解决我的问题。我现在尝试在所有选择名称中同时转储cat.idpost.category_id,结果只有cat.id 被打印出来,直到我选择其中一个选项,然后post.category_id 也被打印出来。所以我很确定我必须在获取帖子后以某种方式重新启动选择。我该怎么做?
    • @devk 啊,我认为这与one-way data flow 的 Vue.js 主体有关。您可能不应该尝试修改post 上的category_id。尝试使用我的答案并省略v-model。我会做一些更新来说明
    • 感谢您的支持并帮助我:)。我会在晚上回家时尝试更新的答案。
    【解决方案2】:

    您应该能够执行以下操作:

    methods: {
        syncCats: function() {
            this.$http.get("/api/categories")
            .then(function(res) {
                this.categories = res.data 
                if(!this.post.category_id) { 
                   this.post.category_id = this.categories[0].id
                }
            })
        }
    },
    

    【讨论】:

    • 我不认为这会起作用,因为当组件首次呈现时不会有categories[0]。另外,v-init 的文档在哪里?哪里都看不到
    • 但我不想覆盖post.category_id。它已经有一个值(这是一个编辑表单)。
    • 如果post.category_id 已经有一个值,默认情况下应该选择它,如果您在创建和编辑情况下都使用它,那么您可以在未定义时为this.post.category_id 分配一个值,否则按原样使用它。我会在回答中更新这个。您是否可以为此创建一个小提琴。
    • 它确实已经有了一个值。我已经用更多信息更新了这个问题。问题是类别被提取,然后选择初始化,然后帖子被提取,这显然不会再次重新初始化选择。我发布了 2 个显示非常奇怪行为的屏幕截图 - post.category_id 仅在我选择其中一个选项后显示。
    • 这违反了组件之间的one-way data flow范式
    猜你喜欢
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    相关资源
    最近更新 更多