Vue 2 - 如何在从数据库中获取数据后 select 正确的 <select> 选项

Vue 2 - How to select the correct <select> option after the data is fetched from db

我正在为一个小型博客项目使用 Vue 2。我有一个单独的组件用于 post 的表单,其中一个表单输入是 select(对于 post 的类别)。 select 在从数据库中获取类别后得到填充。该组件还从父组件获取一个 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: {}
        }
    }
}

我遇到的问题是 none 选项默认为 select。看起来像 this. But when I open the select I see both categories from my db like this

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

我试过 <select ... :v-bind:selected="post.category_id == cat.id"> 但同样的事情发生了。

编辑

好的,现在我已经尝试像这样转储 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>

而我select任意选项前的结果是this - only cat.id gets printed, post.category_id does not. However after I select some option I post.category_id appears as well, like this。请注意最后的“1”是如何只出现在第二个屏幕截图中的,在我 select 编辑了其中一个选项后,即 {{ post.category_id }}.

这意味着 post 在类别之后加载,我应该在加载后以某种方式重新初始化 select。我该怎么做?作为参考,这是获取 post.

的父组件
<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>

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

您甚至可以通过禁用 <select> 添加一些额外的可用性糖,直到 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: []
  }
}

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

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
            }
        })
    }
},