Maison > Questions et réponses > le corps du texte
P粉0042876652023-08-25 18:25:26
Un moyen plus simple consiste à utiliser v-if ou v-for.
Au lieu de gérer le composant directement, gérons l'état du composant et laissons la magie de la réactivité de Vue opérer
Ceci est un exemple, ajoutez dynamiquement un composant (Toast), exploitez simplement l'état du composant
Fichier Toast.vue : Le v-for ici est réactif, chaque fois qu'une nouvelle erreur est ajoutée à l'objet erreurs, elle sera rendue
<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 : chaque fois qu'un événement de clic se produit, nous transmettons une erreur à l'objet erreurs
<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>
Exemple complet : https://stackblitz.com/edit/vitejs-vite-mcjgkl
P粉5981402942023-08-25 00:33:13
createVNode(component, props)
和render(vnode, container)
Créer : Utilisez createVNode()
创建一个带有props的组件定义的VNode
(例如,从*.vue
导入的SFC),可以将其传递给render()
pour effectuer le rendu sur l'élément conteneur donné.
Destroy : Appelez le render(null, container)
会销毁附加到容器的VNode
。当父组件卸载时(通过unmounted
hook du cycle de vie) Cette méthode doit être appelée pour le nettoyage.
// 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 } }
Remarque : Cette méthode repose sur des méthodes internes (createVNode
和render
) qui peuvent être refactorisées ou supprimées dans les versions futures.
createApp(component, props)
和app.mount(container)
Créer : Créez un createApp()
createApp()
创建一个应用实例。该实例具有mount()
="noreferrer">Exemples d'application . Cette instance a une méthode mount()
Destruction : Les instances d'application ont la méthode unmount()
方法来销毁应用和组件实例。当父组件卸载时(通过unmounted
unmount()
unmount
).
// 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 } }Remarque : Cette méthode crée une instance d'application pour chaque composant. Si plusieurs composants doivent être instanciés dans le document en même temps, cela peut entraîner une surcharge considérable.
<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>