⭐前言
大家好,我是yma16,vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)。
背景
搭建一个模型可视化平台,可以对3d模型进行旋转、缩放、拖拽的基础操作,
💖vue3系列相关文章
vue3 + fastapi 实现选择目录所有文件自定义上传到服务器
前端vue2、vue3去掉url路由“ # ”号——nginx配置
csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板
python_selenuim获取csdn新星赛道选手所在城市用echarts地图显示
让大模型分析csdn文章质量 —— 提取csdn博客评论在文心一言分析评论区内容
前端vue3——html2canvas给网站截图生成宣传海报
vue3+echarts应用——深度遍历html的dom结构并用树图进行可视化
vue3新特性
Vue 3 是 Vue.js 的最新版本,它引入了许多新的特性和改进。以下是一些 Vue 3 的新特性:
- Composition API:Vue 3 引入了一个新的 API,称为 Composition API。Composition API 允许开发者以逻辑组织代码,而不是按照组件的选项进行组织。这使得代码更易于维护和重用。
- 更快的渲染速度:Vue 3 对渲染引擎进行了改进,使得渲染速度更快。它采用了一个新的虚拟 DOM 比较算法,该算法在进行 Diff 计算时更加高效。
- 更小的包体积:Vue 3 的包体积比 Vue 2 更小,这意味着它可以更快地加载和运行。
- 改进的 TypeScript 支持:Vue 3 对 TypeScript 的支持得到了改进。它提供了更好的类型推断和编辑器支持,使开发过程更加流畅和安全。
- 新的响应性系统:Vue 3 引入了一个新的响应性系统,使得在组件中跟踪和更新状态更加简单和高效。
- 新的生命周期钩子:Vue 3 引入了一些新的生命周期钩子函数,使开发者可以更好地控制组件的生命周期。
- 更好的 TypeScript 支持:Vue 3 更好地支持 TypeScript,提供了更好的类型推断和类型检查。
这些都是 Vue 3 的一些主要特性,它们使开发者可以更好地开发和维护 Vue.js 应用程序。
⭐搭建vue3项目过程
在windows环境使用node版本>16
💖 初始化项目
npm创建项目
$ npm create vite@latest vue_threejs_front --template vue
选择vue
选择typescript
💖 添加antd和router依赖
在package.json添加 vue-router和ant-design-vue
"dependencies": { "ant-design-vue": "^3.2.15", "eslint-config-standard-with-typescript": "^24.0.0", "eslint-plugin-import": "^2.26.0", "less": "^4.1.3", "unplugin-vue-components": "^0.22.12", "vue": "^3.2.45", "vue-router": "^4.1.6", "vuex": "^4.0.2" }, "devDependencies": { "@types/node": "^18.11.18", "@vitejs/plugin-vue": "^4.0.0", "typescript": "^4.9.3", "vite": "^4.0.0", "vue-tsc": "^1.0.11" }
💖 vite配置项映射目录和代理
vite配置项
- 映射目录
src -> @
- 初始化加载main.less样式文件
- api本地代理
import { defineConfig,loadEnv } from "vite"; import vue from "@vitejs/plugin-vue"; // @ts-ignore import { resolve } from "path"; // @ts-ignore import Components from "unplugin-vue-components/vite"; // @ts-ignore import { AntDesignVueResolver } from "unplugin-vue-components/resolvers"; // https://vitejs.dev/config/ export default defineConfig(({mode})=>{ // 运行模式 console.log('mode',mode) // 当前路径 console.log('process.cwd()',process.cwd()) // @ts-ignore const env=loadEnv(mode,process.cwd()) console.log('env',env) const proxy={ "^/api/": { target: env.VITE_APP_HOST, changeOrigin: true, ws: true, rewrite: (path) => path.replace(/^\/api/, ""), }, }; return { // 打包相对路径 base: './', server: { port: 3000, open: true, cors: true, proxy: { ...proxy }, }, "css": { preprocessorOptions: { less: { javascriptEnabled: true, patterns: [resolve(__dirname, "./src/style/main.less")], }, }, }, resolve: { alias: { "@": resolve(__dirname, "src"), }, }, plugins: [ vue(), Components({ resolvers: [AntDesignVueResolver()], }), ], } });
💖 antd国际化
App.vue配置国际化
<script setup lang="ts"> import { ref } from "vue"; import zhCN from "ant-design-vue/es/locale/zh_CN"; import dayjs from "dayjs"; import "dayjs/locale/zh-cn"; 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; } </style>
💖 layout布局封装
layout读取routes展示路由
layout/index.vue
<script setup lang="ts"> import { UserOutlined, FundOutlined, MenuUnfoldOutlined, MenuFoldOutlined, PoweroffOutlined, } from "@ant-design/icons-vue"; // @ts-ignore import { reactive, computed,h,onMounted} from "vue"; import { useRouter } from "vue-router"; //router const router = useRouter(); interface stateType { selectedKeys: Array<String>; openKeys:Array<String>; collapsed: Boolean; title: string; menuList:any; } const state: stateType = reactive({ title: "vue3平台", openKeys:[], selectedKeys: [], collapsed: false, menuList:[ ] }); interface contentType { url: string; title: string; kind:string; } const collapeAction=()=>{ state.collapsed = !state.collapsed } const clickMenu=(item:any)=>{ console.log('item',item) router.push({ name:item.name }) } //{ item, key, selectedKeys } const selectMenu = (e: any) => { console.log(e) }; const renderIcon=(icon)=>{ // return h(icon) return '' } onMounted(() => { console.log('router.current.value',router) const {routes}=router.options state.menuList=routes.map(item=>{ console.log('item') return { 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, } }) } }) }); </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.id" @click="clickMenu(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 :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px', }" > <!-- 渲染子路由--> <router-view/> </a-layout-content> </a-layout> </a-layout> </template> <style lang="less"> .layout-container { width: 100%; height: 100%; } #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>
💖 vite读取modules目录文件作为路由
router.ts
// import { useStore } from "vuex"; import * as VueRouter from "vue-router"; // import.meta.glob() 直接引入所有的模块 Vite 独有的功能 const modules = import.meta.glob('./modules/**/*.ts', { eager: true }); const routeModuleList:any=[] // 加入到路由集合中 Object.keys(modules).forEach((key) => { const mod = modules[key].default || {}; const modList = Array.isArray(mod) ? [...mod] : [mod]; console.log('modList',modList) routeModuleList.push(...modList); }); const router: any = VueRouter.createRouter({ // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。 history: VueRouter.createWebHashHistory(), routes: routeModuleList, }); // 路由权限 beforeResolve router.beforeResolve(async (to: any, from: any, next: any) => { return next() }); export default router;
💖 main入口配置文件
main.ts
// @ts-ignore import { createApp } from "vue"; // @ts-ignore import App from "./App.vue"; // @ts-ignore import Antd from "ant-design-vue"; import "ant-design-vue/dist/antd.css"; // @ts-ignore import Router from "./router/index.ts"; const app = createApp(App); app.use(Antd); // router app.use(Router); app.mount("#app");
⭐实现效果
基础路由页面
添加一个图片页面路由
⭐总结
Vite是一个高性能的公链平台,具有以下优势:
- 高性能:Vite采用了异步快速共识算法。具体来说,Vite使用了一种名为HDPoS的共识机制,该机制能够实现每秒高达10,000笔交易的吞吐量。这使得Vite成为一个高效、快速的公链平台。
- 无 gas 模型:Vite引入了自身独有的无 gas 模型,用户无需支付燃气费用即可进行交易和执行智能合约。这大大降低了用户使用区块链应用的成本。
- 轻量级智能合约:Vite采用了基于图灵完备语言的Solidity智能合约,这使得Vite的智能合约编写和部署变得简单和高效。
- 高度可扩展:Vite通过使用DAG(有向无环图)机制,实现了高度可扩展性。DAG的使用可以有效地提高网络吞吐量,并克服了其他公链平台中存在的交易堵塞问题。
- 自我优化:Vite的共识算法允许网络参与者在节点之间进行随机选举,并进行高效的数据通信。这种机制能够自动优化网络性能,确保链上交易的快速确认。
综上所述,Vite具有高性能、无 gas 模型、轻量级智能合约、高度可扩展和自我优化等优势,使其成为一个值得关注的公链平台。
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!