Vue中子组件添加新数据时动态获取父组件中的数据,无需使用watcher

问题描述 投票:0回答:3

除了使用 watcher 之外,Vue 中还有什么方法可以在更新时显示数据吗?就像 React 中的 useEffect 会在数据更改时呈现一样,我们是否可以在不使用 Watcher 的情况下执行类似的操作?因为观察者正在占用专用资源来持续监视状态。

我想在用户在其他页面输入相同的用户名后立即在左侧显示用户名。

Vue 中 Watcher 的替代品

这是代码

    <template>
    <div>
        <q-layout view="hHh lpR lFf">
            <!-- Header -->
            <q-header elevated :class="$q.dark.isActive ? 'bg-secondary' : 'bg-black'">
                <q-toolbar>
                    <q-btn flat @click="drawer = !drawer" round dense icon="menu"></q-btn>
                    <q-toolbar-title>Data Templates</q-toolbar-title>
                </q-toolbar>
            </q-header>

            <!-- Page Content -->
            <q-page-container>
                <router-view></router-view>
                <CreateTemplate v-if="showCreateTemplate" />
                <EditTemplate v-if="showEditTemplate" :id="template._id" />
                <DeleteTemplate v-if="showEditTemplate" :id="template._id" />
                <SpecificTemplate v-if="showEditTemplate" :id="template._id" />
            </q-page-container>

            <!-- Sidebar -->
            <q-drawer v-model="drawer" show-if-above class="drawer">
                <q-scroll-area class="fit">
                    <div class="sidebar">
                        <div class="sidebar-content">
                            <q-btn class="data-button" color="primary" label="Create New Template" dense
                                @click="navigateTo()" />
                            <div class="template-list">
                                <q-item v-for="(templateItem) in template" :key="templateItem._id">
                                    <q-item-section>
                                        <div class="template-item">
                                            <div @click="gotoSpecificTemplate(templateItem._id)">{{ templateItem.name ?
                                                templateItem.name : "No Name" }}</div>
                                            <div class="template-buttons">
                                                <q-btn color="red" dense
                                                    @click="navigateDeleteTo(templateItem._id)">
                                                    <font-awesome-icon icon="trash" class="template-icon" />
                                                </q-btn>
                                                <q-btn color="primary" dense
                                                    @click="navigateEditTo(templateItem._id)">
                                                    <font-awesome-icon icon="pen" class="template-icon" />
                                                </q-btn>
                                            </div>
                                        </div>
                                    </q-item-section>
                                </q-item>
                            </div>
                        </div>
                    </div>
                </q-scroll-area>
            </q-drawer>
        </q-layout>
    </div>
</template>
<script>
import CreateTemplate from '../components/MainLayout.vue';
import EditTemplate from '../components/EditLayout.vue';
import DeleteTemplate from '../components/DeleteLayout.vue';
import SpecificTemplate from '../components/SpecificLayout.vue';

import { defineComponent, ref, onMounted, watch } from 'vue';
import {
    QLayout,
    QDrawer,
    QScrollArea,
    QToolbarTitle,
    QItem,
    QBtn,
} from 'quasar';
import axios from 'axios';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { library } from '@fortawesome/fontawesome-svg-core';
import { faTrash, faPen } from '@fortawesome/free-solid-svg-icons';
import { useRouter } from 'vue-router';

library.add(faTrash, faPen);

export default defineComponent({
    name: 'AppLayout',
    components: {
        QLayout,
        QDrawer,
        QScrollArea,
        QToolbarTitle,
        QItem,
        QBtn,
        CreateTemplate,
        EditTemplate,
        FontAwesomeIcon,
        DeleteTemplate,
        SpecificTemplate

    },
    setup() {
        const drawer = ref(false);
        const buttonData = ref([]);
        const text = ref('');
        const template = ref([]);
        const showCreateTemplate = ref(false);
        const showEditTemplate = ref(false);
        const showDeleteTemplate = ref(false);
        const showSpecificTemplate = ref(false);
        const router = useRouter();

        const fetchAllTemplates = async () => {
            try {
                const templateResponse = await axios.get('https://my-api.com/templates');
                const templates = templateResponse.data;
                template.value = templates;
            } catch (error) {
                console.error('Error fetching templates: ', error);
            }
        };

        onMounted(() => {
            fetchAllTemplates();
        });

        watch(template, () => {
            fetchAllTemplates();
        });

        const navigateTo = () => {
            router.push({ name: 'create-template' });
            showCreateTemplate.value = false;
            showEditTemplate.value = false;
        }

        const navigateEditTo = (templateId) => {
            router.push({ name: 'update-template', params: { id: templateId } });
            showEditTemplate.value = false;
        };

        const navigateDeleteTo = (templateId) => {
            router.push({name: 'delete-template', params: {id: templateId}});
            showDeleteTemplate.value = false;

        }
        const gotoSpecificTemplate = (templateId) => {
            try {
                router.push({ name: 'specific-template', params: { id: templateId } });
            } catch (error) {
                console.error('There is some error: ', error);
            }
        };

        return {
            drawer,
            buttonData,
            text,
            template,
            showCreateTemplate,
            showEditTemplate,
            showDeleteTemplate,
            showSpecificTemplate,
            navigateTo,
            navigateEditTo,
            gotoSpecificTemplate,
            navigateDeleteTo
        };
    },
});
</script>
vue.js vuejs2 vuejs3 vue-component vuetify.js
3个回答
1
投票

computed
可以追踪
ref
变化。
这是例子。

输入

aaaa
输入字段。

const { createApp, ref, computed } = Vue

createApp({
  setup() {
    const value = ref('')
    const userList = [{ user: 'aaaa' }, { user: 'bbbb' }]
    
    const user = computed(() => userList.find((el) => el.user === value.value))
    
    return {
      value,
      user,
    }
  }
}).mount('#app')
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">
  <input v-model="value" />
  {{ user }}
</div>


0
投票

在普通 js 中,您可以创建一个代理并使其在更改时执行代码。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy


0
投票

计算属性是为此而设计的: 有关计算属性的 Vue 文档

你能分享一些代码吗?

© www.soinside.com 2019 - 2024. All rights reserved.