除了使用 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>
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>
在普通 js 中,您可以创建一个代理并使其在更改时执行代码。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
计算属性是为此而设计的: 有关计算属性的 Vue 文档
你能分享一些代码吗?