子組件改變父組件ref變數的方法 - daniel-qa/Vue GitHub Wiki

子組件改變父組件ref變數的方法

你需要使用一個 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 變數。

這樣,你就可以在子組件的搜尋框中輸入內容,並且父組件也能夠接收到這個變化。

⚠️ **GitHub.com Fallback** ⚠️