文章目录
- ⭐前言
- 💖vue3系列相关文章
- ⭐搭建vue3项目过程
- 💖 初始化项目
- 💖 添加antd和router依赖
- 💖 vite配置项映射目录和代理
- 💖 antd国际化
- 💖 layout布局封装
- 💖 vite读取modules目录文件作为路由
- 💖 main入口配置文件
- ⭐实现效果
- ⭐总结
- ⭐结束
⭐前言
大家好,我是yma16,vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)。
背景
搭建一个模型可视化平台,可以对3d模型进行旋转、缩放、拖拽的基础操作,
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 模型、轻量级智能合约、高度可扩展和自我优化等优势,使其成为一个值得关注的公链平台。
⭐结束
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!