名称 | 描述 |
---|---|
component | 渲染一个“元组件”为动态组件。 |
keep-alive | 主要用于保留组件状态或避免重新渲染。 |
slot | <slot> 元素作为组件模板之中的内容分发插槽。<slot> 元素自身将被替换。 |
transition | <transition> 元素作为单个元素/组件的过渡效果。 |
1. component
- 渲染一个“元组件”为动态组件。依
is
的值,来决定哪个组件被渲染。is
的值是一个字符串,它既可以是 HTML 标签名称也可以是组件名称。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>v-slot</title> </head> <body> <div id="root"> </div> <script src="https://unpkg.com/vue@next"></script> <script> const app = Vue.createApp({ data(){ return {currentItem: 'input-item'}; }, methods: { handleClick(){ if(this.currentItem === 'input-item'){ this.currentItem = 'div-item'; }else{ this.currentItem = 'input-item'; } } }, template: ` <component :is='currentItem' /> <button @click=handleClick>交换</button> ` }); app.component('input-item', { template: `<input />` }); app.component('div-item', { template: `<div>666</div>` }); const vm = app.mount('#root'); </script> </body> </html>
- 异步组件
- 创建一个只有在需要时才会加载的异步组件,需要用到 defineAsyncComponent API。
- 对于基本用法,
defineAsyncComponent
可以接受一个返回Promise
的工厂函数。Promise 的resolve
回调应该在服务端返回组件定义后被调用。你也可以调用reject(reason)
来表示加载失败。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>v-slot</title> </head> <body> <div id="root"> </div> <script src="https://unpkg.com/vue@next"></script> <script> const app = Vue.createApp({ template: ` <common-item /> <async-common-item /> ` }); app.component('common-item', { template: `<div>hello world</div>` }); app.component('async-common-item', Vue.defineAsyncComponent(() => { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ template: `<div>这是一个异步组件</div>` }) }, 4000) }) })); const vm = app.mount('#root'); </script> </body> </html>
2. keep-alive
- 主要用于保留组件状态或避免重新渲染。
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>v-slot</title> </head> <body> <div id="root"> </div> <script src="https://unpkg.com/vue@next"></script> <script> const app = Vue.createApp({ data(){ return {currentItem: 'input-item'}; }, methods: { handleClick(){ if(this.currentItem === 'input-item'){ this.currentItem = 'div-item'; }else{ this.currentItem = 'input-item'; } } }, template: ` <component :is='currentItem' /> <keep-alive> <component :is='currentItem' /> </keep-alive> <button @click=handleClick>交换</button> ` }); app.component('input-item', { template: `<input />` }); app.component('div-item', { template: `<div>666</div>` }); const vm = app.mount('#root'); </script> </body> </html>
3. slot
<slot>
元素作为组件模板之中的内容分发插槽。<slot>
元素自身将被替换。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>v-slot</title> </head> <body> <div id="root"> </div> <script src="https://unpkg.com/vue@next"></script> <script> const app = Vue.createApp({ data(){ return { message: '值传递' } }, template: ` <comp1>字符串</comp1> <comp1><ul><li>HtML代码</li></ul></comp1> <comp1>{{message}}</comp1> ` }); app.component('comp1', { template: ` <div><slot></slot></div> ` }); const vm = app.mount('#root'); </script> </body> </html>
4. transition
<transition>
元素作为单个元素/组件的过渡效果。<transition>
只会把过渡效果应用到其包裹的内容上,而不会额外渲染 DOM 元素,也不会出现在可被检查的组件层级中。在进入/离开的过渡中,会有 6 个 class 切换。
v-enter-from
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
v-enter-to
:定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时v-enter-from
被移除),在过渡/动画完成之后移除。
v-leave-from
:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
v-leave-to
:离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时v-leave-from
被删除),在过渡/动画完成之后移除。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>使用 Vue 实现 CSS 过渡与动画效果</title> <style> /* 过渡 */ /* 入场 */ .v-enter-from { opacity: 0; } .v-enter-active { transition: opacity 3s ease-out; } .v-enter-to { opacity: 1; } /* 出场 */ .v-leave-from { opacity: 1; } .v-leave-active { transition: opacity 3s ease-out; } .v-leave-to { opacity: 0; } </style> </head> <body> <div id="root"> </div> <script src="https://unpkg.com/vue@next"></script> <script> // 单元素,单组件的入场出场动画 const app = Vue.createApp({ data() { return { show: false }; }, methods: { handleClick() { this.show = !this.show; } }, template: ` <transition> <div v-if='show'>666666</div> </transition> <button @click=handleClick>切换</button> ` }); const vm = app.mount('#root'); </script> </body> </html>