💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] >[success] # 动态组件和异步组件 本章讲解 **动态组件** 与 **异步组件** 的使用方法 >[success] ## 动态组件 **动态组件** : **根据数据的变化,结合 component 这和标签,来随时动态切换组件的显示** 。 **需求** :有两个组件,一个 **input框** ,一个 **hello world** 文字,想实现效果: **input框 显示时, hello world 文字就隐藏, hello world 文字显示时, input框 就隐藏** 。 如果用 **简单写法** 就是像下面这样写: **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态组件和异步组件</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { currentItem: 'input-item' } }, methods: { handleClick(){ if(this.currentItem === 'input-item'){ this.currentItem = 'common-item' } else { this.currentItem = 'input-item' } } }, template: ` <input-item v-show="currentItem === 'input-item'" /> <common-item v-show="currentItem === 'common-item'" /> <button @click="handleClick">切换</button> ` }) // 子组件 app.component('input-item', { template: `<input />` }) // 子组件 app.component('common-item', { template: `<div>hello world</div>` }) const vm = app.mount('#root') </script> </html> ~~~ 上面的代码看似简单,但是代码量大,下面再看一下用 **动态组件** 实现的相同效果, **动态组件实际上就是一个 component 标签,通过is属性来决定这个显示的是哪个组件** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态组件和异步组件</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { currentItem: 'input-item' } }, methods: { handleClick(){ if(this.currentItem === 'input-item'){ this.currentItem = 'common-item' } else { this.currentItem = 'input-item' } } }, template: ` <component :is="currentItem" /> <button @click="handleClick">切换</button> ` }) // 子组件 app.component('input-item', { template: `<input />` }) // 子组件 app.component('common-item', { template: `<div>hello world</div>` }) const vm = app.mount('#root') </script> </html> ~~~ 这样就会有一个问题,在 **输入框输入内容后,** 点击 **切换按钮2次** ,又 **回到显示输入框的状态下,发现输入框内输入的内容消失了** , 这时候就需要用到**keep-alive标签** 来解决这个问题, **keep-alive** 的意思就是 **当这个动态组件第一次渲染时,它会把它里面的一些状态,后面变更的一些情况,都记录下来,当你回头再用这个组件时,会从缓存里,把之前的数据拿过来填充上** ,代码如下: ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>动态组件和异步组件</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ data(){ return { currentItem: 'input-item' } }, methods: { handleClick(){ if(this.currentItem === 'input-item'){ this.currentItem = 'common-item' } else { this.currentItem = 'input-item' } } }, template: ` <keep-alive> <component :is="currentItem" /> </keep-alive> <button @click="handleClick">切换</button> ` }) // 子组件 app.component('input-item', { template: `<input />` }) // 子组件 app.component('common-item', { template: `<div>hello world</div>` }) const vm = app.mount('#root') </script> </html> ~~~ **动态组件** 与 **keep-alive** 有时候会一起使用,这点注意一下即可。 >[success] ## 异步组件 1. **同步组件** 首先展示一下 **同步组件**, **同步组件** 就是你 **调用这个组件时,这个代码就会立即执行** ,这就叫做 **同步组件**。 **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>同步组件</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ template: ` <div> <common-item /> </div> ` }) // 子组件 app.component('common-item', { template: `<div>hello world</div>` }) const vm = app.mount('#root') </script> </html> ~~~ 2. **异步组件** **异步组件** : **动态加载** 一些组件,这样的好处是,我们可以把一些大型的项目,加一些小的 **js文件**,在需要用到这些小 **js文件** 的时候,通过 **异步组件** 来引入这些 **js文件** 来使用这些 **js文件** 。 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>同步组件</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // 父组件 const app = Vue.createApp({ template: ` <div> <common-item /> <async-common-item /> </div> ` }) // 子组件 app.component('common-item', { template: `<div>hello world</div>` }) // 异步子组件 app.component('async-common-item', Vue.defineAsyncComponent(() => { return new Promise((reslve, reject) => { setInterval(() => { reslve({ template: `<div>这是异步组件</div>` }) }, 4000) }) })) const vm = app.mount('#root') </script> </html> ~~~