前端vite+vue3——自动化配置路由布局

简介: 前端vite+vue3——自动化配置路由布局

⭐前言

大家好,我是yma16,本文分享关于 前端vite+vue3——自动化配置路由布局。

背景

在inscode写了一个前端vite+vue3+js的项目,路由分配有点乱,

现在给这个项目做个优化,路由配置。

没有配置路由之前的前端界面。

改造之后

vite

Vite是一种基于公有链技术的快速、安全和可扩展的开源区块链项目。它旨在通过使用异步交易模型和基于状态的共识算法来提高区块链的性能和可扩展性。

Vite的发展可以追溯到2018年,当时Vite团队发布了Vite

TestNet,开发者和用户可以通过该测试网络体验Vite的功能和性能。随后,Vite于2019年底发布了Vite

MainNet,正式上线并开放给广大用户使用。

在Vite的发展过程中,团队不断进行技术改进和优化,以提高其性能和可扩展性。Vite采用了异步交易模型,即交易可以并行处理,提高了交易的速度和吞吐量。另外,Vite使用基于状态的共识算法,即通过状态机来决定交易的顺序和执行结果,这可以减少节点之间的通信和同步开销,提高网络的效率。

除了性能和可扩展性的优化,Vite还提供了一些特色功能,如原生支持智能合约和去中心化交易所(DEX)。Vite的智能合约是基于Solidity编写的,与以太坊的智能合约兼容,使开发者可以轻松迁移到Vite平台。而Vite的DEX允许用户直接在区块链上进行点对点的交易,无需信任任何第三方中介,提高了交易的安全性和可信度。

vue-router

vue-router是Vue.js官方的路由插件,用于实现前端路由。它可以实现单页应用中的页面跳转、嵌套路由、路由参数传递、路由守卫等功能。通过vue-router,可以根据不同的路由地址,动态地渲染不同的组件,实现页面的切换和更新。同时,vue-router还提供了一些API和导航守卫,可以在路由跳转前后做一些额外的操作,如权限验证、页面统计等。Vue.js官方推荐使用vue-router来管理前端路由。

💖vue3系列文章

vue3 + fastapi 实现选择目录所有文件自定义上传到服务器

前端vue2、vue3去掉url路由“ # ”号——nginx配置

csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板

认识vite_vue3 初始化项目到打包

python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示

让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容

前端vue3——html2canvas给网站截图生成宣传海报

vue3+echarts可视化——记录我的2023编程之旅

自动化配置路由

vue3前端自动化配置路由离不开vue-router的使用,主要时使用router进行加载vue文件

💖引入vite版本自定义目录映射

package.json

{
  "name": "vuejs-with-vite",
  "author": "yma16",
  "version": "0.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview --port 4173"
  },
  "dependencies": {
    "ant-design-vue": "^3.2.17",
    "axios": "^1.2.2",
    "echarts": "^5.4.2",
    "guess": "^1.0.2",
    "html2canvas": "^1.4.1",
    "vue": "^3.2.37",
    "vue-router": "^4.2.5",
    "vuex": "^4.1.0"
  },
  "devDependencies": {
    "@types/node": "^18.19.6",
    "@vitejs/plugin-vue": "^4.0.0",
    "less": "^4.2.0",
    "prettier": "^3.2.2",
    "vite": "^4.0.0"
  },
  "license": "MIT"
}

vite.config.js配置@映射到src目录

import { defineConfig } from 'vite'
import { resolve } from "path";
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
  // 打包相对路径
  base: './',
  server: {
    host: true,
  },
  resolve: {
    alias: {
      "@": resolve(__dirname, "src"),
    },
  },
  plugins: [vue()]
})

💖自动化读取文件下的路由

vite读取modules目录下的配置加入路由中

import * as VueRouter from "vue-router";
// import.meta.glob() 直接引入所有的模块 Vite 独有的功能
const modules = import.meta.glob('./modules/*.js', { eager: true });
const routeModuleList=[]
console.log('modules',modules)
// 加入到路由集合中
Object.keys(modules).forEach((key) => {
    
    const mod = modules[key].default || {};
    const modList = Array.isArray(mod) ? [...mod] : [mod];
    console.log('modList',modList)
    routeModuleList.push(...modList);
});
console.log('routeModuleList',routeModuleList)
const router = VueRouter.createRouter({
    // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
    history: VueRouter.createWebHashHistory(),
    routes: routeModuleList,
});
// 路由权限  beforeResolve
router.beforeResolve(async (to, from, next) => {
    next()
});
export default router;

路由文件modules/layout.js

// 基础路由
// @ts-ignore
import LAYOUT from '@/layout/index.vue'
export default {
    path: '/',
    name: 'Layout',
    component: LAYOUT,
    redirect: '/SearchGrade',
    meta: {
        orderNo: 1,
        icon: 'ion:grid-outline',
        title: 'vue3 平台',
    },
    children: [
        {
            path: 'SearchGrade',
            name: 'SearchGrade',
            component: () => import('@/components/SearchGrade.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: 'csdn查分',
            },
        },
        {
            path: 'GameChart',
            name: 'GameChart',
            component: () => import('@/components/GameChart.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: 'vue3赛道可视化',
            },
        },
        {
            path: 'Draw',
            name: 'Draw',
            component: () => import('@/components/draw/Draw.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: '抽奖',
            },
        },
        {
            path: 'Drag',
            name: 'Drag',
            component: () => import('@/components/drag/Drag.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: '拼图',
            },
        },
        {
            path: 'Commit',
            name: 'Commit',
            component: () => import('@/components/commit/Commit.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: '大模型分析评论',
            },
        },
        {
            path: 'visual',
            name: 'visual',
            component: () => import('@/components/visual/index.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: '2023编码可视化',
            },
        },
        {
            path: 'visualHtml',
            name: 'visualHtml',
            component: () => import('@/components/visualHtml/index.vue'),
            meta: {
                icon: 'ion:grid-outline',
                title: '可视化html',
            },
        }
    ],
};

目录结构如下

路由配置

💖main入口加载路由

createApp加载定义的router

import { createApp } from 'vue'
import App from './App.vue'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
import './assets/main.css'
import Router from "./router/index.js";
createApp(App)
.use(Antd)
.use(Router)
.mount('#app')

配置文件

💖入口app.vue配置

app.vue的配置

<script setup>
  import { ref } from "vue";
  import zhCN from "ant-design-vue/es/locale/zh_CN";
  import dayjs from "dayjs";
  import "dayjs/locale/zh-cn";
  /** 下载图片 */
const downloadBase64 = (content, fileName) => {
  const base64ToBlob = function (code) {
    let parts = code.split(';base64,');
    let contentType = parts[0].split(':')[1];
    let raw = window.atob(parts[1]);
    let rawLength = raw.length;
    let uInt8Array = new Uint8Array(rawLength);
    for (let i = 0; i < rawLength; ++i) {
      uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {
      type: contentType
    });
  };
  let aLink = document.createElement('a');
  let blob = base64ToBlob(content);
  aLink.download = fileName + '.png';
  aLink.href = URL.createObjectURL(blob);
  aLink.click();
};
// 截图
const shotAction = () => {
  html2canvas(document.getElementById('render-id'), {
    useCORS: true,
    proxy: 'inscode.csdn.net',
    allowTaint: true,
    scale: 2,
  }).then(function (canvas) {
    console.log('canvas', canvas)
    const base64 = canvas.toDataURL().replace(/^data:image\/(png|jpg);base64,/, '');
    const base64img = `data:image/png;base64,${base64}`;
    downloadBase64(base64img, state.current);
    // document.body.appendChild(canvas);
  });
}
  dayjs.locale("zh-cn");
  const locale = ref(zhCN);
</script>
<template>
  <!--  国际化配置-->
  <a-config-provider :locale="locale">
    <div id="app">
      <router-view/>
    </div>
  </a-config-provider>
</template>
<style scoped>
  #app{
    width: 100vw;
    height: 100vh;
    background-size: 100%;
    background: linear-gradient(rgba(38, 38, 38, 0.5), rgba(40,140,234, 0.6)), url("/static/img/previewFix.jpg") no-repeat center;
  }
</style>

💖layout基础布局配置

layout的vue页面配置

<script setup>
import {
    MenuUnfoldOutlined,
    MenuFoldOutlined,
} from "@ant-design/icons-vue";
import { reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
//router
const router = useRouter();
const state = reactive({
    title: "vue3平台",
    openKeys: [],
    selectedKeys: [],
    collapsed: false,
    menuList: []
});
const collapeAction = () => {
    state.collapsed = !state.collapsed
}
const clickMenu = (menu, item) => {
    console.log('item', item)
    state.openKeys = [menu.key]
    state.selectedKeys = [menu.key]
    router.push({
        name: item.name
    })
}
//{ item, key, selectedKeys }
const selectMenu = (e) => {
    console.log(e)
};
const renderIcon = (icon) => {
    // return h(icon)
    return ''
}
onMounted(() => {
    console.log('router.current.value', router)
    const { routes } = router.options
    state.menuList = routes.reduce((pre, item) => {
        const isHiddenInLayout = item.meta.isHiddenInLayout
        if (!isHiddenInLayout) {
            const menuItem = {
                title: item.meta.title,
                path: item.path,
                key: item.name,
                name: item.name,
                icon: item.meta.icon,
                children: item.children.map(children => {
                    return {
                        title: children.meta.title,
                        path: children.path,
                        key: children.name,
                        name: children.name,
                    }
                })
            }
            pre.push(menuItem)
        }
        return pre
    }, [])
});
</script>
<template>
    <a-layout class="layout-container">
        <a-layout-sider v-model:collapsed="state.collapsed" :trigger="null" collapsible>
            <div class="logo" />
            <a-menu v-model:openKeys="state.openKeys" v-model:selectedKeys="state.selectedKeys" theme="dark" mode="inline"
                @select="selectMenu">
                <a-sub-menu v-for="menu in state.menuList" :key="menu.key">
                    <template #icon> {{ renderIcon(menu.icon) }}</template>
                    <template #title> <span>{{ menu.title }}</span></template>
                    <a-menu-item v-for="menuChild in menu.children" :key="menuChild.key" @click="clickMenu(menu, menuChild)">
                        {{ menuChild.title }}
                    </a-menu-item>
                </a-sub-menu>
            </a-menu>
        </a-layout-sider>
        <a-layout>
            <a-layout-header style="background: #ffffff; padding-left: 20px">
                <div style="display: flex">
                    <div style="width: 50%">
                        <menu-unfold-outlined v-if="state.collapsed" class="trigger" @click="collapeAction" />
                        <menu-fold-outlined v-else class="trigger" @click="collapeAction" />
                        {{ state.title }}
                    </div>
                </div>
            </a-layout-header>
            <a-layout-content class="content-box">
                <!--                    渲染子路由-->
                <router-view />
            </a-layout-content>
        </a-layout>
    </a-layout>
</template>
<style lang="less">
.layout-container {
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.content-box {
    overflow: auto;
    max-height: calc(100vh - 64px);
    padding: 24px;
    background: #fff;
}
#components-layout-demo-custom-trigger .trigger {
    font-size: 18px;
    line-height: 64px;
    padding: 0 24px;
    cursor: pointer;
    transition: color 0.3s;
}
#components-layout-demo-custom-trigger .trigger:hover {
    color: #1890ff;
}
#components-layout-demo-custom-trigger .logo {
    height: 32px;
    background: rgba(255, 255, 255, 0.3);
    margin: 16px;
}
.site-layout .site-layout-background {
    background: #fff;
}
.main-container {
    width: 100%;
    height: 100%;
}
</style>

💖效果

修改之后的页面配置

csdn赛道可视化


拖拽拼图

2023编码可视化

抽奖页面

inscode代码

⭐总结

自动化配置路由思路分解

  1. router文件的自动读取形成数据驱动
  2. layout布局页面读取路由,渲染子路由
    vue-router使用

首先引入Vue和Vue Router,并通过Vue.use(VueRouter)来告诉Vue使用VueRouter插件。

然后创建一个VueRouter实例,并通过routes属性配置路由规则。

最后,在创建Vue实例时将router实例传入,并在根组件的模板中添加一个router-view组件来渲染路由组件

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!


目录
相关文章
|
7天前
|
编解码 前端开发 开发者
【Flutter前端技术开发专栏】Flutter中的响应式设计与自适应布局
【4月更文挑战第30天】Flutter框架助力移动应用实现响应式设计与自适应布局,通过层次化布局系统和`Widget`树管理,结合`BoxConstraints`定义尺寸范围,实现自适应。利用`MediaQuery`获取设备信息,调整布局以适应不同屏幕。`FractionallySizedBox`按比例设定尺寸,`LayoutBuilder`动态计算布局。借助这些工具,开发者能创建跨屏幕尺寸、方向兼容的应用,提升用户体验。
【Flutter前端技术开发专栏】Flutter中的响应式设计与自适应布局
|
11天前
|
前端开发 数据可视化 JavaScript
前端vite+vue3——可视化页面性能耗时指标(fmp、fp)
前端vite+vue3——可视化页面性能耗时指标(fmp、fp)
35 6
|
7天前
|
开发框架 前端开发 数据安全/隐私保护
【Flutter 前端技术开发专栏】Flutter 中的布局与样式设计
【4月更文挑战第30天】本文探讨了Flutter的布局和样式设计,关键点包括:1) 布局基础如Column、Row和Stack用于创建复杂结构;2) Container、Center和Expanded等常用组件的作用;3) Theme和Decoration实现全局样式和组件装饰;4) 实战应用如登录界面和列表页面的构建;5) 响应式布局利用MediaQuery和弹性组件适应不同屏幕;6) 性能优化,避免过度复杂设计。了解并掌握这些,有助于开发者创建高效美观的Flutter应用。
【Flutter 前端技术开发专栏】Flutter 中的布局与样式设计
|
1天前
|
编解码 前端开发 UED
前端布局方式及其优缺点
前端布局方式及其优缺点
|
3天前
|
Web App开发 JSON 数据格式
一键自动化博客发布工具,chrome和firfox详细配置
blog-auto-publishing-tools博客自动发布工具现在已经可以同时支持chrome和firefox了.
一键自动化博客发布工具,chrome和firfox详细配置
|
7天前
|
弹性计算 运维 Shell
|
7天前
|
缓存 前端开发 JavaScript
【JavaScript 技术专栏】JavaScript 前端路由实现原理
【4月更文挑战第30天】本文探讨了JavaScript前端路由在SPA中的重要性,阐述了其基本原理和实现方式,包括Hash路由和History路由。前端路由通过监听URL变化、匹配规则来动态切换内容,提升用户体验和交互性。同时,文章也提到了面临的SEO和页面缓存挑战,并通过电商应用案例分析实际应用。理解并掌握前端路由能助开发者打造更流畅的单页应用。
|
7天前
|
前端开发 测试技术 持续交付
【Flutter 前端技术开发专栏】Flutter 中的 UI 测试与自动化测试
【4月更文挑战第30天】本文探讨了 Flutter 应用中UI测试和自动化测试的重要性,包括保障质量、提高效率和增强开发信心。Flutter提供`flutter_test`库进行Widget测试,以及`flutter_driver`进行集成测试。UI测试涵盖界面布局、交互和状态变化的验证,最佳实践建议尽早引入测试、保持用例简洁,并结合手动测试。未来,随着Flutter技术发展,UI测试和自动化测试将更加完善,助力开发高质量应用。
【Flutter 前端技术开发专栏】Flutter 中的 UI 测试与自动化测试
|
7天前
|
弹性计算 运维 Shell
自动化安装并配置自定义服务
【4月更文挑战第30天】
7 0
|
9天前
|
前端开发
前端三栏布局(包括圣杯,双飞翼)
前端三栏布局(包括圣杯,双飞翼)

热门文章

最新文章