首页 > 解决方案 > VueJS在单个文件中选择组件

问题描述

我很绝望。我完全不知道如何将 html “select”-tag 外包给单个 Vue 组件文件。我尝试了很多不同的方法,但不幸的是我还没有让它工作。

用户组件:

<custom-select :id="'continent'" :selected="user.continent" :options="continents" @change.native="changedContinent" class="some css classes" />

export default {
    props: ['user'],
    components: {
        CustomSelect,
    },
    data() {
        return {
            continents: [
                { value: 'africa', text: 'Africa' },
                { value: 'america-north', text: 'America (North)' },
                { value: 'america-south', text: 'America (South)' },
                { value: 'asia', text: 'Asia' },
                { value: 'australia', text: 'Australia' },
                { value: 'europe', text: 'Europe' }
            ]
        };
    },
    methods: {
        updateUser() {
            axios.post('/updateUser', this.user).then(() => {});
        },
        changedContinent() {
            // Do something with the new selected continent like changing background relative to the selected continent
        }
    }
};

自定义选择:

<template>
    <select v-model="selected" class="some css classes">
        <option v-for="option in options" :key="option.value" :value="option.value">{{ option.text }}</option>
    </select>
</template>

<script>
export default { props: ['id', 'selected', 'label', 'options'] };
</script>

每当我更改选定的值时,它应该更新 user.continent 值,但它会引发以下错误:

避免直接改变 prop,因为只要父组件重新渲染,该值就会被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“选择”

但我不知道如何处理。有人可以帮我吗?
先感谢您!

标签: javascriptvue.jsselect

解决方案


正如错误消息所说,“为了避免直接改变道具,请使用数据或计算属性......”

我修改了您的代码以在我的测试环境中创建组件(使用 Vue CLI 的 Vue 2),并将 CustomSelect 绑定到从“selected”道具初始化的新数据属性“selectedContinent”。我还通过自定义事件更新父组件(在您的情况下为用户组件)。这是我的组件。请参阅Vue 自定义事件文档

我的 CustomSelect.vue 组件:

<template>
  <div class="custom-select">
    <select v-model="selectedContinent" class="" v-on:change="changeContinent">
      <option v-for="option in options" :key="option.value" :value="option.value">{{ option.text }}</option>
    </select>
  </div>
</template>

<script>
  export default {
    props: ['id', 'selected', 'label', 'options'],
    data() {
      return {
        selectedContinent: this.selected
      }
    },
    methods: {
      changeContinent() {
        //console.log('changeContinent: ' + this.selectedContinent);
        this.$emit('change-continent-event', this.selectedContinent);
      }
    }
  }
</script>

我的 Parent.vue 组件(您的用户):

<template>
  <div class="parent">
    <custom-select :id="'continent'" :selected="user.continent" :options="continents"
      v-on:change-continent-event="changedContinent" />
  </div>
</template>

<script>
  import CustomSelect from './CustomSelect.vue'

  export default {
    props: ['user'],
    components: {
      CustomSelect,
    },
    data() {
      return {
        continents: [
          { value: 'africa', text: 'Africa' },
          { value: 'america-north', text: 'America (North)' },
          { value: 'america-south', text: 'America (South)' },
          { value: 'asia', text: 'Asia' },
          { value: 'australia', text: 'Australia' },
          { value: 'europe', text: 'Europe' }
        ]
      };
    },
    methods: {
      updateUser() {
        //axios.post('/updateUser', this.user).then(() => { });
      },
      changedContinent(newContinent) {
        // Do something with the new selected continent like changing background relative to the selected continent
        console.log('changedContinent: ' + newContinent);
      }
    }
  }
</script>

推荐阅读