欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue批量注冊組件實現(xiàn)動態(tài)組件技巧

 更新時間:2024年11月14日 10:40:17   作者:三天不學(xué)習(xí)  
Vue 動態(tài)組件的應(yīng)用場景很多,可應(yīng)用于動態(tài)頁簽,動態(tài)路由等場景,其核心原理是批量注冊,在Vue2和Vue3中實現(xiàn)原理相同,只是語法略有差異,本文給大家介紹了Vue批量注冊組件實現(xiàn)動態(tài)組件技巧,需要的朋友可以參考下

介紹

Vue 動態(tài)組件的應(yīng)用場景很多,可應(yīng)用于動態(tài)頁簽,動態(tài)路由等場景,其核心原理是批量注冊。在Vue2和Vue3中實現(xiàn)原理相同,只是語法略有差異。

Vue2 實現(xiàn)

基于 webpack

require.context() 是webpack提供的一個自動導(dǎo)入的API
參數(shù)1:加載的文件目錄
參數(shù)2:是否加載子目錄
參數(shù)3:正則,匹配文件
返回值:導(dǎo)入函數(shù) fn
使用require提供的函數(shù)context加載某一個目錄下所有的.vue后綴的文件,他的返回值是一個對象,對象里面有一個屬keys(), 可以獲取所有的文件路徑,我們可以遍歷importFn.keys(),最后在遍歷中使用

首先先描述下應(yīng)用場景,比如我想在父容器遍歷組件集合,根據(jù)組件類型(字符串)來首先動態(tài)加載組件,如下圖:

在這里插入圖片描述

如果要是按正常一個個注冊的話,也是可以的,就是代碼冗余多,不夠優(yōu)雅,所以需要一個方法來實現(xiàn),這個方法就放到一個JS里去,然后把該index.js直接丟到widget-attr文件夾里.

//index.js
const requireComponent = require.context('./', false, /\w+\.vue$/)
let comps = {}
requireComponent.keys().map(fileName => {
  let comp = requireComponent(fileName).default;
  comps[comp.name] = comp
})
export default comps;

然后在頁面引用,如下圖:

在這里插入圖片描述

好了,到這里簡簡單單就實現(xiàn)了,我現(xiàn)在整個項目需要這樣批量注冊的場景也就兩三個,所以我在需要批量注冊的組件對應(yīng)的文件夾就放置這個一個index.js就能實現(xiàn)了,如果實際場景不想放那么多,可以自行稍微改造下,傳個路徑進(jìn)去,我Vue3版本就是這樣實現(xiàn)的

Vue3 實現(xiàn)

基于 Vite

const components = import.meta.glob("./*.vue");
//注意 :  import.meta.glob 不支持變量,

Vue3 使用 組合式 ,方法里也用到了Vite的語法,首頁也要把核心代碼封裝到 dynamicComponents.js里面

詳細(xì)如下

// utils/dynamicComponents.js
import { defineAsyncComponent } from 'vue';
function loadComponentsFromFolder(folderPath) {
  const components = {};
  let modules = import.meta.glob('@/components/form-designer/widget/*.vue', { eager: false });
  if (folderPath == 'widgetArrt') {
    modules = import.meta.glob('@/components/form-designer/widget/widget-attr/*.vue', { eager: false });
  }
  for (const path in modules) {
    const componentName = path.match(/\/([^/]+)\.vue$/)[1];
    components[componentName] = defineAsyncComponent(modules[path]);
  }
  return components;
}
export default loadComponentsFromFolder;

這個并不完美,理想中應(yīng)該是根據(jù)傳參(需要動態(tài)注冊的組件所在文件夾路徑)來實現(xiàn),但是,如下目前好像并不支持:

// utils/dynamicComponents.js
function loadComponentsFromFolder(folderPath) {
   //省略...
    modules = import.meta.glob(`${folderPath}/*.vue`, { eager: false   });
   //省略...
}
export default loadComponentsFromFolder;

這樣寫會報錯,提示import.meta.glob不支持變量.

[plugin:vite:import-glob] Invalid glob import syntax:
 Expected glob to be a string, but got dynamic template literal
 //大致意思: 只能使用文本,而我們的 path 使用了變量,所以會報錯.

這個有其他解決辦法,待會下面會說到,因為我在該項目批量注冊應(yīng)用場景不多,所以我就直接傳參判斷來寫死了.
.接下來就是引用了,如下圖:

在這里插入圖片描述

至此,就實現(xiàn)批量動態(tài)注冊了,另外注意, 組件集合不要用綁定模式,雖然不報錯,但是會報黃提示影響效率

 // let components =ref({})  //不要寫成響應(yīng)式的了,會有性能風(fēng)險提示
 let components = {} 
 components = loadComponentsFromFolder('widget')

最后

用其他辦法來解決這個問題吧,有點復(fù)雜,有更好辦法的小伙伴可以留言~

使用 fs 模塊讀取文件列表:
在 Node.js 環(huán)境中使用 fs 模塊讀取指定文件夾下的文件列表。
將文件列表傳遞給前端,前端再使用 import() 動態(tài)導(dǎo)入這些文件。
前端動態(tài)導(dǎo)入:

前端根據(jù)接收到的文件列表動態(tài)導(dǎo)入組件。
實現(xiàn)步驟
1. 后端讀取文件列表
首先,在 Vite 項目的 vite.config.js 或者單獨的 Node.js 腳本中,使用 fs 模塊讀取文件列表,并將結(jié)果暴露給前端。

javascript
// vite.config.js 或者單獨的 Node.js 腳本
const fs = require('fs');
const path = require('path');

function getComponentPaths(folderPath) {
  const baseFolderPath = path.resolve(__dirname, 'src/components/form-designer/widget/');
  const fullFolderPath = folderPath ? path.join(baseFolderPath, folderPath) : baseFolderPath;

  const files = fs.readdirSync(fullFolderPath);
  const componentPaths = files
    .filter(file => file.endsWith('.vue'))
    .map(file => path.join(fullFolderPath, file));

  return componentPaths.map(p => p.replace(/\\/g, '/').replace(path.resolve(__dirname, 'src/'), '@/'));
}

module.exports = {
  getComponentPaths,
};
2. 前端動態(tài)導(dǎo)入
在前端,使用 import() 動態(tài)導(dǎo)入這些文件。

javascript
// utils/dynamicComponents.js
import { defineAsyncComponent } from 'vue';

const componentCache = {};

async function loadComponentsFromFolder(folderPath) {
  // 檢查緩存
  if (componentCache[folderPath]) {
    return componentCache[folderPath];
  }

  // 獲取文件路徑列表
  const componentPaths = await fetchComponentPaths(folderPath);

  const components = {};

  // 動態(tài)導(dǎo)入模塊
  await Promise.all(componentPaths.map(async (path) => {
    const componentName = path.match(/\/([^/]+)\.vue$/)[1];
    components[componentName] = defineAsyncComponent(() => import(path));
  }));

  // 緩存結(jié)果
  componentCache[folderPath] = components;

  return components;
}

async function fetchComponentPaths(folderPath) {
  // 這里假設(shè)你有一個 API 端點來獲取文件路徑列表
  const response = await fetch(`/api/get-component-paths?folderPath=${folderPath}`);
  const data = await response.json();
  return data.paths;
}

export default loadComponentsFromFolder;
3. 創(chuàng)建 API 端點
在 Vite 項目中創(chuàng)建一個簡單的 API 端點來返回文件路徑列表。

javascript
// server/index.js
const express = require('express');
const { getComponentPaths } = require('../vite.config');

const app = express();
const port = 3000;

app.get('/api/get-component-paths', (req, res) => {
  const folderPath = req.query.folderPath;
  const paths = getComponentPaths(folderPath);
  res.json({ paths });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});
使用示例
在組件或頁面中使用 loadComponentsFromFolder 函數(shù)時,只需傳遞不同的 folderPath 參數(shù)即可動態(tài)注冊不同路徑下的組件。

javascript
// 在某個 Vue 組件中使用
<script setup>
import { ref, onMounted } from 'vue';
import loadComponentsFromFolder from '@/utils/dynamicComponents';

const folderPath = 'widgetAttr'; // 可以根據(jù)實際需求動態(tài)設(shè)置
const dynamicComponents = ref({});

onMounted(async () => {
  dynamicComponents.value = await loadComponentsFromFolder(folderPath);
});
</script>

<template>
  <div>
    <component v-for="(component, name) in dynamicComponents" :is="component" :key="name"></component>
  </div>
</template>
注意事項
文件路徑處理:

確保文件路徑在前后端一致,特別是在 Windows 系統(tǒng)中,路徑分隔符需要轉(zhuǎn)換。
API 端點:

確保 API 端點能夠正確返回文件路徑列表。
性能優(yōu)化:

如果組件數(shù)量較多,可以考慮使用懶加載和緩存機(jī)制來優(yōu)化性能。
通過這種方式,你可以根據(jù)路徑參數(shù)動態(tài)注冊不同文件夾下的組件,而不需要使用 if-else 判斷。

以上就是Vue批量注冊組件實現(xiàn)動態(tài)組件技巧的詳細(xì)內(nèi)容,更多關(guān)于Vue動態(tài)組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VueRouter路由模式全面解析

    VueRouter路由模式全面解析

    這篇文章主要介紹了VueRouter路由模式的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue項目中使用tinymce編輯器的步驟詳解

    vue項目中使用tinymce編輯器的步驟詳解

    本文分步驟給大家介紹了vue項目中使用tinymce編輯器的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09
  • 在vue項目中使用Swiper插件詳解

    在vue項目中使用Swiper插件詳解

    這篇文章主要介紹了在vue項目中使用Swiper插件詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 使用element-ui實現(xiàn)行合并過程

    使用element-ui實現(xiàn)行合并過程

    這篇文章主要介紹了使用element-ui實現(xiàn)行合并過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vue Router路由動態(tài)緩存組件使用詳解

    Vue Router路由動態(tài)緩存組件使用詳解

    這篇文章主要介紹了Vue Router路由動態(tài)緩存組件使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Vue手寫橫向輪播圖的實例

    Vue手寫橫向輪播圖的實例

    這篇文章主要介紹了Vue手寫橫向輪播圖的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue實現(xiàn)跑馬燈簡單效果

    Vue實現(xiàn)跑馬燈簡單效果

    這篇文章主要為大家詳細(xì)介紹了Vues實現(xiàn)跑馬燈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • vue select選擇框數(shù)據(jù)變化監(jiān)聽方法

    vue select選擇框數(shù)據(jù)變化監(jiān)聽方法

    今天小編就為大家分享一篇vue select選擇框數(shù)據(jù)變化監(jiān)聽方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • vue props 一次傳多個值實例

    vue props 一次傳多個值實例

    這篇文章主要介紹了vue props 一次傳多個值實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 前端Vue頁面中展示本地圖片簡單代碼示例

    前端Vue頁面中展示本地圖片簡單代碼示例

    今天遇到一個在vue文件中引入本地圖片的問題,于是有了這篇文章,本文主要給大家介紹了關(guān)于前端Vue頁面中展示本地圖片的相關(guān)資料,需要的朋友可以參考下
    2023-12-12

最新評論