Vue3 和 Vue-Select:使用可标记道具时如何向父级发送子数据?

Vue3 and Vue-Select: How to emit child data to parent when using taggable prop?

我在 Vue3 中使用 Vue-Select 库。我的 objective 是让用户从选项列表中选择标签,如果选项列表中不存在标签,也可以创建新标签。

这在子组件中工作正常,但我在 passing/emitting 父组件的数据方面遇到了问题。 我需要父组件中的数据,因为我我打算把它打包以便稍后进行表单处理。

如何才能成功的从子组件中获取到标签并进入父组件的formData.tags 属性?

代码and sandbox link:

components/PostEditorTags.vue:

<template>
  <v-select
    :create-option="(tag) => ({ label: tag, value: tag })"
    v-model="selected"
    :options="options"
    multiple
    taggable
    @input="$emit('input', selected)"
    placeholder="add a tag"
  ></v-select>
  <br />
  child component data:
  <pre>{{ selected }}</pre>
</template>

<script setup>
import { ref } from 'vue';
import vSelect from 'vue-select';
import 'vue-select/dist/vue-select.css';

defineEmits(['input']);

const options = [
  { value: 'one', label: 'One' },
  { value: 'two', label: 'Two' },
  { value: 'three', label: 'Three' },
  { value: 'four', label: 'Four' },
  { value: 'five', label: 'Five' },
  { value: 'six', label: 'Six' },
  { value: 'seven', label: 'Seven' },
  { value: 'eight', label: 'Eight' },
  { value: 'nine', label: 'Nine' },
  { value: 'ten', label: 'Ten' },
];

let selected = ref([]);
</script>

components/Parent.vue:

<template>
  <h1>Post Tags</h1>
  <PostEditorTags @input="setTagsArr" />
  <br />
  <br />
  parent component data:
  <pre>{{ formData.tags }}</pre>
</template>

<script setup>
import PostEditorTags from './PostEditorTags.vue';

const formData = {
  // title: '',
  // content: '',
  tags: null,
};

function setTagsArr(x) {
  formData.tags = x;
}
</script>

尝试使用 watcher 而不是 event

components/PostEditorTags.vue:

<template>
  <v-select
    :create-option="(tag) => ({ label: tag, value: tag })"
    v-model="selected"
    :options="options"
    multiple
    taggable
    placeholder="add a tag"
  ></v-select>
  <br />
  child component data:
  <pre>{{ selected }}</pre>
</template>

<script setup>
import { ref, defineEmits, watch } from 'vue';
import vSelect from 'vue-select';
import 'vue-select/dist/vue-select.css';

const options = [{ value: 'one', label: 'One' }, { value: 'two', label: 'Two' }, { value: 'three', label: 'Three' }, { value: 'four', label: 'Four' }, { value: 'five', label: 'Five' }, { value: 'six', label: 'Six' }, { value: 'seven', label: 'Seven' }, { value: 'eight', label: 'Eight' }, { value: 'nine', label: 'Nine' }, { value: 'ten', label: 'Ten' },];

let selected = ref([]);

watch(
  () => selected.value,
  (newValue, oldValue) => {
    act(newValue);
  }
);

const emit = defineEmits(['input'])
const act = (val) => emit('input', val);
</script>

使您的数据在 components/Parent.vue:

中具有反应性
<template>
  <h1>Post Tags</h1>
  <PostEditorTags @input="setTagsArr" />
  <br />
  <br />
  parent component data:
  <pre>{{ formData.tags }}</pre>
</template>

<script setup>
import { reactive } from 'vue'
import PostEditorTags from './PostEditorTags.vue';

const formData = reactive({
  // title: '',
  // content: '',
  tags: null,
});

function setTagsArr(x) {
  formData.tags = x;
}
</script>

your demo