Empaquetado de componentes avanzados de Vue: componentes dinámicos y componentes asíncronos

Prefacio

Desea utilizar datos para impulsar la representación del componente; en este momento, elija utilizar componentes dinámicos e implementación

Ideas

Componente dinámico

El componente tiene: atributo is, que controla qué componente se renderizará, es decir, cuando el valor de is es el valor registrado, el componente se renderizará para lograr la renderización dinámica del componente.

<component :is="component"></component>
<script>
import child from '@/componets/child'
export default {
    
    
	componets:{
    
    
		child
	},
	data(){
    
    
		component: 'child'
	}
}
</script>

importar hijo de '@ / componets / child'

Pero el niño debe agregarse manualmente.
En este momento, habrá un problema: se cargarán componentes innecesarios. Cuando un componente es demasiado grande, no es necesario cargarlo, porque afectará nuestro rendimiento.
Esto es no es lo suficientemente elegante, entonces tenemos ¿No hay forma de cargar diferentes componentes de nietos en? Sí, vamos a utilizar componentes asincrónicos.

Componente asincrónico

En aplicaciones grandes, es posible que necesitemos dividir la aplicación en bloques de código más pequeños y cargar un módulo desde el servidor solo cuando sea necesario. Para simplificar, Vue le permite definir su componente como una función de fábrica, que analizará la definición de su componente de forma asincrónica. Vue activará la función de fábrica solo cuando el componente necesite ser renderizado y almacenará en caché el resultado para una futura renderización.

Código

Código de componente dinámico

Escribamos primero los componentes dinámicos, los
subcomponentes

<template>
	<div class="m-detail">
		<component :is="item.component" v-for="(item, index) in detailArr" :key="index" :data="item.data"
		v-bind="$attrs" v-on="$listeners">
		</component>
	</div>
</template>

<script>
import importComponent from '@/utils/importComponent'
export default {
    
    
	title: 'store',
	props: {
    
    
		detailData: {
    
    
			type: Array,
			default() {
    
    
				return []
			}
		}
	},
	data() {
    
    
		return {
    
    }
	},
	computed: {
    
    
		detailArr() {
    
    
			const arr = []
			for (var i = 0; i < this.detailData.length; i++) {
    
    
				(i => {
    
    
					const item = this.detailData[i]
					var _type = this.detailData[i].type
					const detailMap = {
    
    
						BlockList: {
    
    
							products:item.products
						},
						FloatList: {
    
    
							products:item.products
						}
					}
					const obj = {
    
    
						component: importComponent(`components/Store/${
      
      _type}.vue`),
						data: {
    
    
							...detailMap[_type]
						}
					}
					arr.push(obj)
				})(i)
			}
			return arr
		}
	}
}
</script>

<style lang="less" scoped>
.m-detail {
    
    
	min-height: 400px;
}
</style>

Código de componente asincrónico

importComponent es cargar componentes de forma asincrónica: solo
importar

export default (path, callback) => {
    
    
	return resolve => require([`@/${
      
      path}`], Module => {
    
    
		callback && callback(Module)
		resolve(Module)
	})
}

Componente solar

En este momento, solo necesitamos crear nietos en '@ / components / Store /';

<template>
	<view class="bank-card">
		<view class="item text-center">
			<text class="text-gray cuIcon-roundleftfill-copy roundleftfil" @click="hanldSwiper('left')"></text>
			<text class="text-gray cuIcon-roundrightfill roundrightfill" @click="hanldSwiper('right')"></text>
			<view class="item-title font-weight">图片</view>
			<swiper class="swiper" :current="current">
				<swiper-item v-for="(item,index) in data.products" :key="index">
					 <view class="swiper-item uni-bg-red" :style="`background-image: url(${item.productPic});`"></view>
				</swiper-item>
			</swiper>
			<view>
				<text class="spot">123</text>
				<text class="spot">123</text>
				<text class="spot">123</text>
			</view>
			<view class="bg-grey flex justify-between footer">
				<view class="text-center">个人邀请</view>
				<text class="line"></text>
				<view @click="posterShare()">海报分享</view>
			</view>
		</view>
	</view>
</template>

<script>
export default{
    
    
	name: 'BankCard',
	props: {
    
    
		data: {
    
    
			type: Object
		}
	},
	data(){
    
    
		return{
    
    
			current:0
		}
	},
	methods: {
    
    
		hanldSwiper(item){
    
    
			if(item == 'left' && this.current > 0){
    
    
				this.current -= 1
				return
			}
			if(item == 'right' && this.current < this.data.products.length-1){
    
    
				this.current += 1
				return
			}
		},
		posterShare(){
    
    
			this.$emit('toShare','val')
		}
	}
}
</script>

<style lang="less">
.bank-card{
    
    
	.nav{
    
    
		margin: 30upx 0;
		.title{
    
    
			font-weight: 700;
			font-size: 32upx;
		}
	}
	.item{
    
    
		width: 100%;
		height: 500upx;
		border: 1px solid #CCCCCC;
		display: inline-block;
		margin-right: 30upx;
		border-radius: 30upx;
		padding: 30upx 0;
		position: relative;
		overflow: hidden;
		.item-title{
    
    
			margin-bottom: 30upx;
			color:#000000
		}
		.roundleftfil{
    
    
			position: absolute;
			left:80upx;
			top:180upx;
			font-size: 50upx;
		}
		.roundrightfill{
    
    
			position: absolute;
			right:80upx;
			top:180upx;
			font-size: 50upx;
		}
		.footer{
    
    
			width: 100%;
			height: 60upx;
			line-height: 60upx;
			position: absolute;
			bottom: 0;
			>view {
    
    
				width: 49%;
			}
		}
	}
	.spot{
    
    
		margin:0 10upx;
		vertical-align: center;
	}
}
.swiper{
    
    
	width: 340upx;
	height: 240upx;
	margin:auto;
	border-radius: 30upx;
	overflow: hidden;
	.swiper-item{
    
    
		width: 100%;
		height: 100%;
		background-size: cover;
		background-repeat: round;
	}
}
</style>

Debido a que el valor de paso del componente de nietos, si usa esto. & Emit para exponer al padre, es muy problemático para el padre exponer al abuelo a través de este. &
Emit , por lo que usamos $ attrs / $ listeners (valor de paso del componente ) conseguir

Componente ancestro

En este punto podemos usar storeData para renderizar componentes dinámicamente

<Store :detailData="storeData" @toShare='toShare'></Store>

this.storeData = [
			{
    
    
				type: 'BlockList',
				products:[
					{
    
    
						newId:'13',			productPic:'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=229065980,2895464780&fm=26&gp=0.jpg'
					},
					{
    
    
						newId:'14',
						productPic:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2350817201,1137116540&fm=26&gp=0.jpg'
					},
					{
    
    
						newId:'15',					productPic:'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F031156f5aeb21a8a801207fa1bc9eac.jpg&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1618385640&t=bc51aaaa2dc72dd8e565807935529732'
					}
					
				]
			}
		]

Supongo que te gusta

Origin blog.csdn.net/weixin_43236062/article/details/114887062
Recomendado
Clasificación