将 ref 与道具一起使用
Using ref with props
我有一个 组件 A 和一个嵌套的 组件 B。 组件A加载一个字符串列表,组件B有一个SELECT
元素,当组件A时填充 加载完成。此时应该选择SELECT
的第一个选项。 After this moment, when other options are selected, Component B should emit update
event with selection data, so that Component A 'knows' 选择了什么选项。由于 A 应该控制 B,这个选项通过 props.[=15= 传回给 B ]
在我下面的实现中,只有选择的初始值被组件 B 接收,当列表被加载时,它被成功填充,但是 selectedOption 值没有被控制 属性 .所以,它不起作用。
实现这个的正确方法是什么?
组件 A:
<template>
<component-b :list="list" :selected="selected" @update="onUpdate">
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup: () => {
const list = ref<string[]>([]);
const selected = ref('');
load().then(data => { // some load function returning a promise
selected.value = data[0]; // data is never empty
list.value = data;
});
const onUpdate = (data: string) => selected.value = data;
return { list, selected, onUpdate };
}
})
</script>
组件 B:
<template>
<select v-model="selectedOption" @change="onChange">
<option v-for="item of props.list" />{{item}</option>
</select>
</template>
<script lang="ts">
import { defineComponent, ref, PropType } from 'vue';
export default defineComponent({
emits: ['update'],
props: {
selected: {
type: String
},
list: {
type: Object as PropType<String[]>
}
}
setup: (props, { emit }) => {
const selectedOption = ref(props.selected); // this doesn't work when loading is finished and props are updated
const onChange = () => emit('update', selectedOption.value);
return { selectedOption, onChange, props }
}
});
</script>
谢谢。
在组件 B 中,您不需要同时添加 v-model 和 @change。
<select :value="selected" @change="onChange">
<option v-for="item in list">{{ item }}</option>
</select>
然后在 onChange 中从 select 获取值并发出:
const onChange = (event) => emit('update', event.target.value);
在ComponentB.vue
中,selectedOption
的ref
只是初始化为props.selected
的值,但它本身是 非反应性 (即 ref
不会自动跟踪 props.selected
):
const selectedOption = ref(props.selected); // not reactive to props.selected
您可以使用 watchEffect
解决此问题,将任何新值复制到 selectedOption
(每当 props.selected
更改时自动发生):
watchEffect(() => selectedOption.value = props.selected);
旁注: setup()
不需要显式 return props
因为它们已经可以通过名称用于模板.您的模板可以更改为:
<!-- <option v-for="item of props.list">{{ item }}</option> -->
reference props directly by name
<option v-for="item of list">{{ item }}</option>
我有一个 组件 A 和一个嵌套的 组件 B。 组件A加载一个字符串列表,组件B有一个SELECT
元素,当组件A时填充 加载完成。此时应该选择SELECT
的第一个选项。 After this moment, when other options are selected, Component B should emit update
event with selection data, so that Component A 'knows' 选择了什么选项。由于 A 应该控制 B,这个选项通过 props.[=15= 传回给 B ]
在我下面的实现中,只有选择的初始值被组件 B 接收,当列表被加载时,它被成功填充,但是 selectedOption 值没有被控制 属性 .所以,它不起作用。
实现这个的正确方法是什么?
组件 A:
<template>
<component-b :list="list" :selected="selected" @update="onUpdate">
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup: () => {
const list = ref<string[]>([]);
const selected = ref('');
load().then(data => { // some load function returning a promise
selected.value = data[0]; // data is never empty
list.value = data;
});
const onUpdate = (data: string) => selected.value = data;
return { list, selected, onUpdate };
}
})
</script>
组件 B:
<template>
<select v-model="selectedOption" @change="onChange">
<option v-for="item of props.list" />{{item}</option>
</select>
</template>
<script lang="ts">
import { defineComponent, ref, PropType } from 'vue';
export default defineComponent({
emits: ['update'],
props: {
selected: {
type: String
},
list: {
type: Object as PropType<String[]>
}
}
setup: (props, { emit }) => {
const selectedOption = ref(props.selected); // this doesn't work when loading is finished and props are updated
const onChange = () => emit('update', selectedOption.value);
return { selectedOption, onChange, props }
}
});
</script>
谢谢。
在组件 B 中,您不需要同时添加 v-model 和 @change。
<select :value="selected" @change="onChange">
<option v-for="item in list">{{ item }}</option>
</select>
然后在 onChange 中从 select 获取值并发出:
const onChange = (event) => emit('update', event.target.value);
在ComponentB.vue
中,selectedOption
的ref
只是初始化为props.selected
的值,但它本身是 非反应性 (即 ref
不会自动跟踪 props.selected
):
const selectedOption = ref(props.selected); // not reactive to props.selected
您可以使用 watchEffect
解决此问题,将任何新值复制到 selectedOption
(每当 props.selected
更改时自动发生):
watchEffect(() => selectedOption.value = props.selected);
旁注: setup()
不需要显式 return props
因为它们已经可以通过名称用于模板.您的模板可以更改为:
<!-- <option v-for="item of props.list">{{ item }}</option> -->
reference props directly by name
<option v-for="item of list">{{ item }}</option>