最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3如何處理重復(fù)渲染代碼的問題

 更新時(shí)間:2024年01月18日 10:25:50   作者:前端成長(zhǎng)指南  
這篇文章主要來和大家一起探討一下在Vue3項(xiàng)目中如何處理重復(fù)渲染代碼的問題,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

普通的場(chǎng)景

最近在做 Vue3 項(xiàng)目的時(shí)候,在思考一個(gè)小問題,其實(shí)是每個(gè)人都做過的一個(gè)場(chǎng)景,很簡(jiǎn)單,看下方代碼

<template>
<div v-for="item in data" :key="item.age">
	<span>{[ item.name }}</span>
	<span>今年已經(jīng) </span>
	<span>{[ item.age }}</span>
	<span>歲啦</span>
</div>
</template>
<script setup lang="ts">
const data = new Array(20).fill(0).map((_, index) => ({
name:`sunshine-${index}`,
age: index
}));
</script>

其實(shí)就是一個(gè)普通的不能再普通的循環(huán)遍歷渲染的案例,咱們往下接著看,如果這樣的遍歷在同一個(gè)組件里出現(xiàn)了很多次,比如下方代碼

<template>
<div>
	<div v-for="item in data" :key="item.age">
		<span>{{ item.name }}</span>
		<span>今年已經(jīng) </span>
		<span>{{ item.age }}</span>
		<span>歲啦</span>
	</div>
	<!-- 多處使用 -->
	<div v-for="item in data" :key="item.age">
		<span>{[ item.name }}</span>
		<span>今年已經(jīng) </span>
		<span>{{ item.age }}</span>
		<span>歲啦</span>
	</div>
	<!-- 多處使用 -->
	<div v-for="item in data" :key="item.age">
		<span>{[ item.name }}</span>
		<span>今年已經(jīng) </span>
		<span>{[ item.age }}</span>
		<span>歲啦</span>
	</div>
	<!-- 多處使用 -->
	<div v-for="item in data" :key="item.age">
		<span>{ item.name }}</span>
		<span>今年已經(jīng) </span>
		<span>{[ item.age }}</span>
		<span>歲啦</span>
	</div>
</div>
</temple>

這個(gè)時(shí)候我們應(yīng)該咋辦呢?誒!很多人很快就能想出來了,那就是把循環(huán)的項(xiàng)抽取出來成一個(gè)組件,這樣就能減少很多代碼量了,比如我抽取成 Item.vue 這個(gè)組件

<!-- Item.vue -->
<template>
<div>
	<span>{{ name }}</span>
	<span>今年已經(jīng) </span>
	<span>{ age }}</span>
	<span>歲啦</span>
</div>
</template>
<script lang="ts" setup>defineProps({
name: {
type: String,
default:'',
},
age: {
type:Number
default:0,
};
})
</script>

然后直接可以引用并使用它,這樣大大減少了代碼量,并且統(tǒng)一管理,提高代碼可維護(hù)性?。。?/p>

<template>
<div>
<Item v-for="item in data" :key="item.age" :age="item.age" :name="item.name" /></div>
</template>
<script setup lang="ts">
import Item from './Item.vue';
const data = new Array(20).fill(0).map((_, index) => ({
name:`sunshine-${index}`,
age: index
</script>

不難受嗎?

但是我事后越想越難受,就一個(gè)這么丁點(diǎn)代碼量的我都得抽取成組件,那我不敢想象以后我的項(xiàng)目組件數(shù)會(huì)多到什么地步,而且組件粒度太細(xì),確實(shí)也增加了后面開發(fā)者的負(fù)擔(dān)~

那么有沒有辦法,可以不抽取成組件呢?我可以在當(dāng)前組件里去提取嗎,而不需要去重新定義一個(gè)組件呢?例如下面的效果

<template>
<div>
	<!-- 在本組件中定義一個(gè)復(fù)用模板 -->
	<DefineTemplate v-slot="[ age, name }">
		<div>
		<span>{{ name }}</span>
		<span>今年已經(jīng) </span>
		<span>{{ age }}</span>
		<span>歲啦</span>
		</div>
	</DefineTemplate>
	<!-- 可多次使用復(fù)用模板 -->
	<ReuseTemplate v-for="item in data" :key="item.age" :age-"item.age" :name-"item.name">
	<ReuseTemplate v-for="item in data" :key="item,age" :age="item,age" :name-"item, name">
	<ReuseTemplate v-for="item in data" :key="item.age" :age="item.age" :name="item.name">
</div>
</template>

<script setup lang="ts">
import { useTemplate } from '@/hooks/useTemplate';
const data = new Array(20).fill(0).map((_, index) => ({
name:`sunshine-$[index}`,
age: index,
});
const [DefineTemplate, ReuseTemplate] = useTemplate();
</script>

useTemplate 代碼實(shí)現(xiàn)

想到這,馬上行動(dòng)起來,需要封裝一個(gè) useTemplate來實(shí)現(xiàn)這個(gè)功能

import { defineComponent, shallowRef } from 'vue';
import { camelCase } from 'lodash';
import type { Slot } from 'vue';
//將橫線命名轉(zhuǎn)大小駝峰
function keysToCamelKebabCase(obj: Record<string,any>)[
	const newObj: typeof obj = ;for (const key in obj) newObj[camelCase(key)] = obj[key];
	return newObj;
}
export const useTemplate = () => {
	const render = shallowRef<Slot undefined>();
	const define = defineComponent({
	setup(_,[ slots }) {
		return () => {
			//將復(fù)用模板的渲染函數(shù)內(nèi)容保存起來
			render.value = slotsdefault;
			}
		}
	})
	const reuse = defineComponent({
		setup(_, [ attrs, slots }) {
			return () => {
				// 還沒定義復(fù)用模板,則拋出錯(cuò)誤
				if (!render.value){
					throw new Error( 你還沒定義復(fù)用模板呢!);
				}
				// 執(zhí)行渲染函數(shù),傳入 attrs、slots
				const vnode = render.value([ ...keysToCamelKebabCase(attrs), $slots: slots });
				return vnode.length === 1 ? vnode[0] : vnode;
			}
		},
	});
	return [define reuse];
}

用的不爽

盡管做到這個(gè)地步,我還是覺得用的不爽,因?yàn)闆]有類型提示

我們想要的是比較爽的使用,那肯定得把類型的提示給支持上?。。?!于是給 useTemplate 加上泛型?。〖由现缶陀蓄愋吞崾纠瞺~~~

加上泛型后的 useTemplate 代碼如下:

import { defineComponent, shallowRef } from 'vue';
import { camelCase } from 'lodash';
import type { DefineComponent, Slot } from 'vue';

// 將橫線命名轉(zhuǎn)換為駝峰命名
function keysToCamelKebabCase(obj: Record<string, any>) {
  const newObj: typeof obj = {};
  for (const key in obj) newObj[camelCase(key)] = obj[key];
  return newObj;
}

// 定義 DefineTemplateComponent 類型,該類型表示定義模板的組件
export type DefineTemplateComponent<
  Bindings extends object,
  Slots extends Record<string, Slot | undefined>,
> = DefineComponent<object> & {
  new (): { $slots: { default(_: Bindings & { $slots: Slots }): any } };
};

// 定義 ReuseTemplateComponent 類型,該類型表示復(fù)用模板的組件
export type ReuseTemplateComponent<
  Bindings extends object,
  Slots extends Record<string, Slot | undefined>,
> = DefineComponent<Bindings> & {
  new (): { $slots: Slots };
};

// 定義 ReusableTemplatePair 類型,表示一個(gè)定義模板和復(fù)用模板的組件對(duì)
export type ReusableTemplatePair<
  Bindings extends object,
  Slots extends Record<string, Slot | undefined>,
> = [DefineTemplateComponent<Bindings, Slots>, ReuseTemplateComponent<Bindings, Slots>];

// useTemplate 函數(shù),返回一個(gè)定義模板和復(fù)用模板的組件對(duì)
export const useTemplate = <
  Bindings extends object,
  Slots extends Record<string, Slot | undefined> = Record<string, Slot | undefined>,
>(): ReusableTemplatePair<Bindings, Slots> => {
  const render = shallowRef<Slot | undefined>();

  // 定義 DefineTemplateComponent 組件
  const define = defineComponent({
    setup(_, { slots }) {
      return () => {
        // 將復(fù)用模板的渲染函數(shù)內(nèi)容保存起來
        render.value = slots.default;
      };
    },
  }) as DefineTemplateComponent<Bindings, Slots>;

  // 定義 ReuseTemplateComponent 組件
  const reuse = defineComponent({
    setup(_, { attrs, slots }) {
      return () => {
        // 還沒定義復(fù)用模板,則拋出錯(cuò)誤
        if (!render.value) {
          throw new Error('你還沒定義復(fù)用模板呢!');
        }
        // 執(zhí)行渲染函數(shù),傳入 attrs、slots
        const vnode = render.value({ ...keysToCamelKebabCase(attrs), $slots: slots });
        return vnode.length === 1 ? vnode[0] : vnode;
      };
    },
  }) as ReuseTemplateComponent<Bindings, Slots>;

  return [define, reuse];
};

以上就是Vue3如何處理重復(fù)渲染代碼的問題的詳細(xì)內(nèi)容,更多關(guān)于Vue3重復(fù)渲染的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue如何動(dòng)態(tài)配置ip與端口

    vue如何動(dòng)態(tài)配置ip與端口

    這篇文章主要介紹了vue如何動(dòng)態(tài)配置ip與端口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue2.0+webpack環(huán)境的構(gòu)造過程

    vue2.0+webpack環(huán)境的構(gòu)造過程

    本文分步驟給大家介紹了vue2.0+webpack環(huán)境的構(gòu)造過程的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • 詳解vue項(xiàng)目中如何引入全局sass/less變量、function、mixin

    詳解vue項(xiàng)目中如何引入全局sass/less變量、function、mixin

    這篇文章主要介紹了詳解vue項(xiàng)目中如何引入全局sass/less變量、function、mixin,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • Vue導(dǎo)出頁面為PDF格式的實(shí)現(xiàn)思路

    Vue導(dǎo)出頁面為PDF格式的實(shí)現(xiàn)思路

    這篇文章主要介紹了Vue導(dǎo)出頁面為PDF格式的實(shí)現(xiàn)思路,其實(shí)思路也很簡(jiǎn)單,就是將頁面轉(zhuǎn)換成圖片格式.然后通過圖片的base64碼.生成PDF..感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-07-07
  • 如何啟動(dòng)node.js文件的3個(gè)方法

    如何啟動(dòng)node.js文件的3個(gè)方法

    這篇文章主要給大家介紹了關(guān)于如何啟動(dòng)node.js文件的3個(gè)方法,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 詳解Vue3如何加載動(dòng)態(tài)菜單

    詳解Vue3如何加載動(dòng)態(tài)菜單

    這篇文章主要為大家詳細(xì)介紹了Vue3是如何實(shí)現(xiàn)加載動(dòng)態(tài)菜單功能的,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Vue有一定幫助,需要的可以參考一下
    2022-07-07
  • Vue事件總線怎么用

    Vue事件總線怎么用

    這篇文章主要介紹了Vue事件總線的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • vue移動(dòng)端設(shè)置全屏背景的項(xiàng)目實(shí)踐

    vue移動(dòng)端設(shè)置全屏背景的項(xiàng)目實(shí)踐

    本vue移動(dòng)端項(xiàng)目設(shè)置全屏背景,關(guān)鍵是要找對(duì)文件,然后添加background屬性即可,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Vue項(xiàng)目刷新后h5樣式失效的原因及解決方案

    Vue項(xiàng)目刷新后h5樣式失效的原因及解決方案

    今天遇到一個(gè)bug,有一個(gè)Element的message組件,用它做的一個(gè)進(jìn)度條,它是寫在一個(gè)頁面上,并且是用js控制dom元素的,web端一切正常,但是,H5頁面刷新的時(shí)候它樣式加載不出來了,所以本文主要介紹了Vue項(xiàng)目刷新后h5樣式失效的原因及解決方案,需要的朋友可以參考下
    2024-10-10
  • vue input輸入框模糊查詢的示例代碼

    vue input輸入框模糊查詢的示例代碼

    本篇文章主要介紹了vue input輸入框模糊查詢的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05

最新評(píng)論

弋阳县| 运城市| 九台市| 那坡县| 凌源市| 湄潭县| 玛沁县| 湖南省| 沁源县| 宜兴市| 南康市| 东兰县| 桑植县| 剑阁县| 静宁县| 页游| 通海县| 北票市| 吴旗县| 新源县| 诏安县| 福建省| 连州市| 洛川县| 乳源| 承德市| 晋城| 武威市| 青川县| 文登市| 新乡县| 辽阳县| 五原县| 舟山市| 曲阳县| 临湘市| 平谷区| 万安县| 会宁县| 大同县| 江北区|