Vue3的动态组件和异步组价
Posted 飞鹰3995
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3的动态组件和异步组价相关的知识,希望对你有一定的参考价值。
今天小编在网上闲逛的时候,发现前端这几年的发展离不开组件的概念,之前小编接触到的组件,基本都是这样的
const app= Vue.createApp({ template: ` <input-item /> <common-item /> ` }) app.component(\'input-item\',{ template: `<div> <input /> </div>` }) app.component(\'common-item\',{ template: `<div> Hello World </div>` }) const vm = app.mount("#root")
这个时候页面显示的一个文本框,一行文字 ,这个时候,如果我们想通过一个按钮,来切换两个元素的现实和隐藏关系,就可以把代码修改成这样
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\' } // 也可以通过三目运算符来实现。还可以借鉴绑定class或者style绑定 // this.currentItem = this.currentItem === \'input-item\'?\'common-item\':\'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: `<div> <input /> </div>` }) app.component(\'common-item\',{ template: `<div> Hello World </div>` }) const vm = app.mount("#root")
有了动态组件之后,同样的需求,我们的代码就可以写成这样
// 动态组件:根据数据的变化,结合component这个标签,来随时动态切换组件的实现 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: `<div> <input /> </div>` }) app.component(\'common-item\',{ template: `<div> Hello World </div>` }) const vm = app.mount("#root")
在小编的第一块代码中,都是引入自定义标签的组件之后,就可以直接展示效果,这种成为同步组件 ,当然还有异步组件,主要是为了解决首屏加载速度的问题,借助Vue3中的defineAsyncComponent,就像这样
const AsyncCommonItem = Vue.defineAsyncComponent(() => { return new Promise((resolve,reject) => { setTimeout(() => { resolve({ template:\'<div>this is an async component</div>\' }) },4000) }) }) 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\',AsyncCommonItem) const vm = app.mount("#root")
当然,今天小编还为大家准备了一些其他常用的知识点,就当是饭后甜点吧
一、ref:获取DOM节点用的语法,慎用这种方法,后期维护的时候会很麻烦
const app= Vue.createApp({ data(){ return { count: 1 } }, mounted(){ // 只有早这个生命周期或者之后,将元素挂载上,才存在DOM的概念 console.log(this.$refs.countele) // <div>1</div> this.$refs.commele.sayHello() }, template: ` <div @click="count += 1"> <div ref="countele">{{ count }}</div> <common-item ref=\'commele\' /> </div> ` }) app.component(\'common-item\',{ methods:{ sayHello(){ alert(\'hello\') } }, template: `<div> Hello World </div>` }) const vm = app.mount("#root")
二、privide inject:用于组件与子组件的子组件传递数据的方式
我们在通过组件向子组件的子组件传递数据的时候,可以这样
const app= Vue.createApp({ data(){ return { count: 1 } }, template: ` <div> <child :count="count"/> </div> ` }) app.component(\'child\',{ props:[\'count\'], template: `<div> <child-child :count="count" /> </div>` }) app.component(\'child-child\',{ props:[\'count\'], template: `<div> {{ count }} </div>` }) const vm = app.mount("#root")
显然,这样很麻烦,通过privide inject,我们可以这么写
const app= Vue.createApp({ data(){ return { count: 1 } }, // provide:{ // 不能直接调用data中的数据,需要的时候,需要写成函数的方式 // count:1 // }, // 这种是一次性的,可以通过Vue3的getter方式响应式,通过传统props一层层传递是可以 provide(){ return { count: this.count } }, template: ` <div> <child /> <button @click="count += 1">增加</button> </div> ` }) app.component(\'child\',{ template: `<div> <child-child /> </div>` }) app.component(\'child-child\',{ inject:[\'count\'], template: `<div> {{ count }} </div>` }) const vm = app.mount("#root")
大家还可以扫描二维码,关注我的微信公众号,蜗牛全栈
Vue组价的基本使用
组件是可复用的 Vue 实例,我们只需要调用就可以了。
创建组件
方法一:通过extend创建组件(不推荐)
<div id="app"> <h2>全局组件</h2> <my-cpn></my-cpn> <h2>局部组件</h2> <cpnc></cpnc> </div> // 1.创建组件构造器对象 const cpnc = Vue.extend({ template:` <div> <h2>标题</h2> <p>内容1</p> <p>内容2</p> </div>` }) // 2.注册组件(全局组件,可以在多个vue实例中使用) Vue.component(‘my-cpn‘, cpnc) const app = new Vue({ el:"#app", components:{//局部组件创建 cpnc:cpnc } })
方法二:template(推荐),这里有三种写法
<div id="app"> <cpn1></cpn1> </div> // 1.注册全局组件语法糖 Vue.component(‘cpn1‘, { template:` <div> <h2>全局组件语法糖</h2> <p>全局组件语法糖</p> </div>` })
上面的组件模板都是写在组件里面的,这样写阅读起来不方便,组件模板的分离写法如下:
<!-- 写法一:script标签注意类型是text/x-template --> <script type="text/x-template" id="cpn1"> <div> <h2>组件模板的分离写法</h2> <p>script标签注意类型是text/x-template</p> </div> </script>
<!-- 写法二:template标签 (推荐)--> <template id="cpn2"> <div> <h2>组件模板的分离写法</h2> <p>template标签</p> </div> </template>
JS
const app = new Vue({ el: "#app", components: { //局部组件创建 cpn1:{ template:‘#cpn1‘ }, cpn2: { template: ‘#cpn2‘ } } })
组件的动态数据
刚刚创建的组件数据都是静态的,开发中很多数据都是动态数据,我们可以组件中的data解决问题:
<div id="app"> <cpn1></cpn1> </div> const app = new Vue({ el: "#app", components: { //局部组件创建 cpn1:{ template:‘<div>{{msg}}</div>‘, data(){ return { msg:"组件的数据存放必须要是一个函数" } } } } })
注:组件的data必须是一个函数,而且这个函数返回一个对象保存数据
大家有想过,组件为啥data是一个函数?这里做一个实验,组件cpn1不使用函数,cpn2使用函数:
<div id="app"> <h2>data不使用函数</h2> <cpn1></cpn1> <cpn1></cpn1> <h2>data使用函数</h2> <cpn2></cpn2> <cpn2></cpn2> <hr> </div>
<template id="cpn1"> <div> <button @click="count--">-</button> 当前计数:{{count}} <button @click="count++">+</button> </div> </template>
<template id="cpn2"> <div> <button @click="count--">-</button> 当前计数:{{count}} <button @click="count++">+</button> </div> </template>
cpn1返回的公共对象,相当于没有函数的作用域(模拟不使用函数)
const obj = { count:0 }; const app = new Vue({ el: "#app", components: { //局部组件创建 cpn1: { template: ‘#cpn1‘, data() { return obj;//不使用函数 } }, cpn2: { template: ‘#cpn2‘, data() { return { count: 0//使用函数 } } } } })
运行结果如下,如果不使用函数它会同加同减,相互作用,这是因为返回的对象地址都是一样的。但使用函数就不会出现这种情况(因为有作用域),它会创建新的地址
组件是一个封闭的空间,什么意思?即组件的方法不是写着Vue实例里,直接写在组件:
<div id="app2"> <mycpn3></mycpn3> </div> <template id="cpn3"> <div> 当前计数:{{count}} <button @click="add">+</button> </div> </template>
JS
//全局注册组件 Vue.component(‘mycpn3‘,{ template:"#cpn3", data(){ return { count:0 } }, methods:{ add(){ this.count++; } } }); //实例Vue const app2 = new Vue({ el:"#app2" });
注册组件必须在实例实例Vue前面,不然报错
以上是关于Vue3的动态组件和异步组价的主要内容,如果未能解决你的问题,请参考以下文章
683 vue3的动态组件,keep-alive,缓存组件的生命周期,异步组件和Suspense,$refs,$parent和$root,生命周期,组件的v-model