子組件改變父組件ref變數的方法 - daniel-qa/Vue GitHub Wiki
你需要使用一個 ref 變數來管理搜尋框的值,並將這個 ref 變數的值傳遞給父組件。
注意: 由於使用了 defineEmits,你需要確保你的 Vue 版本在 3.2 或以上。
<template>
<div v-if="activeIndex !== null" class="list2 parent">
<el-input v-model="searchQuery"
placeholder="搜尋子項目..."
size="medium"
clearable
class="child"
style="width: 90%; top: 5%;"></el-input>
<div class="list child" style="height: 85%; top: 12%; width: 90%;">
<div v-for="(subItem, subIndex) in filteredSubItems"
:key="subIndex"
:class="{'active': activeIndex2 === subIndex}"
class="list-item"
@click="setActive2(subIndex)">
{{ subItem.name }} {{ subItem.tchCnt }} 人
<el-button size="small"
@click.stop="addToColumn3(subItem)"
type="success">
加入
</el-button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, defineProps, inject, watch } from "vue";
import { ElMessage } from "element-plus";
// 从父组件注入的接收名单和更新方法
const column3Items = inject("column3Items", ref([])); // 接收名單
// 父組件傳入的 props
const props = defineProps({
activeIndex: {
type: Number,
required: true
},
activeIndex2: {
type: Number,
required: true
},
searchQuery: {
type: String,
required: true
},
subItems: {
type: Array,
required: true
},
});
// 本组件的搜尋框 query
const searchQuery = ref(props.searchQuery);
// 监听 searchQuery 的变化,并通知父组件
watch(searchQuery, (newVal) => {
// 使用 $emit 通知父组件 searchQuery 更改
// 这里需要 emit 一个事件,父组件监听该事件并更新 props.searchQuery
// 由于是 setup script,无法直接使用 $emit,需要通过 defineEmits 获取 emit 函数
const emit = defineEmits(['update:searchQuery']);
emit('update:searchQuery', newVal);
});
// 选中学校
const setActive2 = (index) => {
activeIndex2 = index;
};
// 过滤子级菜单项(学校)
const filteredSubItems = computed(() => {
if (props.activeIndex === null) return [];
const currentSubItems = props.subItems[props.activeIndex] || [];
return currentSubItems.filter((item) =>
item.name.toLowerCase().includes(searchQuery.value.toLowerCase())
);
});
// 添加到第三列 (响应式触发更新)
const addToColumn3 = (item) => {
const newValue = JSON.stringify(item);
const isExist = column3Items.value.some((column3) => JSON.stringify(column3) === newValue);
if (!isExist) {
column3Items.value.push(item);
ElMessage.success(`已加入接收名單`);
} else {
ElMessage.warning(`已存在接收名單中`);
}
};
</script>
- 父組件需要做的修改
<template>
<ChildComponent :searchQuery="searchQuery" @update:searchQuery="updateSearchQuery" ... />
</template>
<script setup>
import { ref } from 'vue';
// ... other imports
const searchQuery = ref(''); // 初始化 searchQuery
const updateSearchQuery = (newVal) => {
searchQuery.value = newVal;
};
// ... other code
</script>
- 子組件:
引入 watch。
使用 ref 建立 searchQuery 變數,並用 props.searchQuery 初始化。
v-model 綁定到 searchQuery,而非 props.searchQuery。
使用 watch 監聽 searchQuery 的變化,並使用 defineEmits 取得 emit 函數,觸發 update:searchQuery 事件,將新的 searchQuery 值傳遞給父組件。
- 父組件:
在子組件標籤上監聽 update:searchQuery 事件,並將事件處理函數 updateSearchQuery 傳遞給它。
updateSearchQuery 函數接收子組件傳遞的新 searchQuery 值,並更新父組件的 searchQuery ref 變數。
這樣,你就可以在子組件的搜尋框中輸入內容,並且父組件也能夠接收到這個變化。