Rumah > Soal Jawab > teks badan
P粉0042876652023-08-25 18:25:26
Cara yang lebih mudah ialah menggunakan v-if atau v-for.
Daripada mengendalikan komponen secara langsung, mari kita kendalikan keadaan komponen dan biarkan sihir responsif Vue berfungsi
Ini adalah contoh, tambah komponen secara dinamik (Toast), cuma kendalikan keadaan komponen
Toast.vue file: V-for di sini adalah reaktif, apabila ralat baharu ditambahkan pada objek ralat, ia akan dipaparkan
<script setup lang="ts">
import { watch } from 'vue';
import { ref, onUpdated } from 'vue';
import { Toast } from 'bootstrap';
const props = defineProps({
errors: { type: Array, default: () => [] },
});
onUpdated(() => {
const hiddenToasts = props.errors.filter((obj) => {
return obj.show != true;
});
hiddenToasts.forEach(function (error) {
var errorToast = document.getElementById(error.id);
var toast = new Toast(errorToast);
toast.show();
error.show = true;
errorToast.addEventListener('hidden.bs.toast', function () {
const indexOfObject = props.errors.findIndex((item) => {
return item.id === error.id;
});
if (indexOfObject !== -1) {
props.errors.splice(indexOfObject, 1);
}
});
});
});
</script>
<script lang="ts">
const TOASTS_MAX = 5;
export function push(array: Array, data): Array {
if (array.length == TOASTS_MAX) {
array.shift();
array.push(data);
} else {
array.push(data);
}
}
</script>
<template>
<div
ref="container"
class="position-fixed bottom-0 end-0 p-3"
style="z-index: 11"
>
<div
v-for="item in errors"
v-bind:id="item.id"
class="toast fade opacity-75 bg-danger"
role="alert"
aria-live="assertive"
aria-atomic="true"
data-bs-delay="15000"
>
<div class="toast-header bg-danger">
<strong class="me-auto text-white">Error</strong>
<button
type="button"
class="btn-close"
data-bs-dismiss="toast"
aria-label="Close"
></button>
</div>
<div class="toast-body text-white error-body">{{ item.msg }}</div>
</div>
</div>
</template>
ErrorTrigger.vue: Setiap kali peristiwa klik berlaku, kami menolak ralat ke objek ralat
<script setup lang="ts"> import { ref, reactive } from 'vue'; import toast from './Toast.vue'; import { push } from './Toast.vue'; const count = ref(0); const state = reactive({ errors: [] }); function pushError(id: int) { push(state.errors, { id: id, msg: 'Error message ' + id }); } </script> <template> <toast :errors="state.errors"></toast> <button type="button" @click="pushError('toast' + count++)"> Error trigger: {{ count }} </button> </template>
Contoh penuh: https://stackblitz.com/edit/vitejs-vite-mcjgkl
P粉5981402942023-08-25 00:33:13
createVNode(component, props)
和render(vnode, container)
Buat: Gunakan createVNode()
创建一个带有props的组件定义的VNode
(例如,从*.vue
导入的SFC),可以将其传递给render()
untuk membuat pada elemen bekas yang diberikan.
Hancurkan: Panggil cangkuk render(null, container)
会销毁附加到容器的VNode
。当父组件卸载时(通过unmounted
kitaran hayat) Kaedah ini harus dipanggil untuk pembersihan.
// renderComponent.js import { createVNode, render } from 'vue' export default function renderComponent({ el, component, props, appContext }) { let vnode = createVNode(component, props) vnode.appContext = { ...appContext } render(vnode, el) return () => { // destroy vnode render(null, el) vnode = undefined } }
Nota: Kaedah ini bergantung pada kaedah dalaman (createVNode
和render
) yang mungkin difaktorkan semula atau dikeluarkan dalam keluaran akan datang.
createApp(component, props)
和app.mount(container)
Buat: Buat createApp()
createApp()
创建一个应用实例。该实例具有mount()
="noreferrer">Contoh aplikasi . Contoh ini mempunyai kaedah mount()
Pemusnahan: Aplikasi aplikasi mempunyai unmount()
方法来销毁应用和组件实例。当父组件卸载时(通过unmounted
unmounted
).
// renderComponent.js import { createApp } from 'vue' export default function renderComponent({ el, component, props, appContext }) { let app = createApp(component, props) Object.assign(app._context, appContext) // 必须使用Object.assign在_context上 app.mount(el) return () => { // 销毁app/component app?.unmount() app = undefined } }Nota: Kaedah ini mencipta contoh aplikasi untuk setiap komponen Jika berbilang komponen perlu digunakan dalam dokumen pada masa yang sama, ia boleh menyebabkan overhed yang besar.
<script setup> import { ref, onUnmounted, getCurrentInstance } from 'vue' import renderComponent from './renderComponent' const { appContext } = getCurrentInstance() const container = ref() let counter = 1 let destroyComp = null onUnmounted(() => destroyComp?.()) const insert = async () => { destroyComp?.() destroyComp = renderComponent({ el: container.value, component: (await import('@/components/HelloWorld.vue')).default props: { key: counter, msg: 'Message ' + counter++, }, appContext, }) } </script> <template> <button @click="insert">插入组件</button> <div ref="container"></div> </template>