0


【前端Vue3 + TS项目开发一般流程】

🚀 作者 :“码上有前”
🚀 文章简介 :前端开发
🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬
在这里插入图片描述

前端Vue3 + ts 项目开发一般流程

往期精彩内容

【前端高频面试题–HTML篇】
【前端高频面试题–CSS上篇】
【前端高频面试题–CSS下篇】
【前端高频面试题–JS上篇】
【前端高频面试题–JS下篇】
【前端高频面试题–ES6篇】
【前端高频面试题–ES7-ES11】
【前端–异步编程】
【前端高频面试题–TypeScript篇】

【前端高频面试题–git篇】
【前端高频面试题–微信小程序篇】

【前端高频面试题–Vue基础篇】
【前端高频面试题–虚拟DOM篇】
【前端高频面试题–Vue3.0篇】
【前端高频面试题–Vuex上篇】
【前端高频面试题–Vuex下篇】
【前端高频面试题–Vue生命周期篇】
【前端高频面试题–Vue组件通信篇】
【前端高频面试题–Vue路由篇】

【前端-Vue3创建一个新项目】
【前端大屏自适应缩放】
【前端Vue3 + TS项目开发一般流程】

项目初始化&安装插件&配置文件

// 常见的插件及其配置// eslint: 代码及语法检查
// prettier : 代码格式化// stelylint: 样式语法检查// commitlint: 代码提交添加提交内容概括// husky: 代码提交前进行语法检查// 给src目录去别名,用@符代替// 在vue.config.js文件中添加如下代码const path =require('path');

module.exports ={// ...resolve:{alias:{'@': path.resolve(__dirname,'src/'),// 设置别名为 src 目录// 这里可以继续添加其他别名},},};// 或使用ts的方法在tsconfig.json中配置{"compilerOptions":{"baseUrl":".","paths":{"@/*":["src/*"]// 设置别名为 src 目录// 这里可以继续添加其他别名}}}

在main.ts中配置文件

import{ createApp }from'vue'import App from'@/App.vue'//引入模板的全局的样式import'@/styles/index.scss'//引入element-plus插件与样式import ElementPlus from'element-plus'import'element-plus/dist/index.css'//svg插件需要配置代码import'virtual:svg-icons-register'//引入自定义插件对象:注册整个项目全局组件import gloalComponent from'@/components'//配置element-plus国际化//@ts-expect-errorimport zhCn from'element-plus/dist/locale/zh-cn.mjs'//暗黑模式需要的样式import'element-plus/theme-chalk/dark/css-vars.css'//引入路由import router from'./router'//引入仓库import pinia from'./store'//获取应用实例对象const app =createApp(App)//安装element-plus插件
app.use(ElementPlus,{locale: zhCn,//element-plus国际化配置})//安装自定义插件
app.use(gloalComponent)//安装仓库
app.use(pinia)//注册模板路由
app.use(router)//引入路由鉴权文件import'./permisstion'//引入自定义指令文件import{ isHasButton }from'@/directive/has'isHasButton(app)//将应用挂载到挂载点上
app.mount('#app')

引入全局组件

//引入项目中全部的全局组件import SvgIcon from'./SvgIcon/index.vue'import Pagination from'./Pagination/index.vue'import Category from'./Category/index.vue'//引入element-plus提供全部图标组件import*as ElementPlusIconsVue from'@element-plus/icons-vue'//全局对象constallGloablComponent: any ={ SvgIcon, Pagination, Category }//对外暴露插件对象exportdefault{//务必叫做install方法install(app: any){//注册项目全部的全局组件
    Object.keys(allGloablComponent).forEach((key)=>{//注册为全局组件
      app.component(key, allGloablComponent[key])})//将element-plus提供图标注册为全局组件for(const[key, component]of Object.entries(ElementPlusIconsVue)){
      app.component(key, component)}},}

封装axios&配置响应器与拦截器

//进行axios二次封装:使用请求与响应拦截器import axios from'axios'import{ ElMessage }from'element-plus'//引入用户相关的仓库import useUserStore from'@/store/modules/user'//第一步:利用axios对象的create方法,去创建axios实例(其他的配置:基础路径、超时的时间)const request = axios.create({//基础路径baseURL:import.meta.env.VITE_APP_BASE_API,//基础路径上会携带/apitimeout:5000,//超时的时间的设置})//第二步:request实例添加请求与响应拦截器
request.interceptors.request.use((config)=>{//获取用户相关的小仓库:获取仓库内部token,登录成功以后携带给服务器const userStore =useUserStore()if(userStore.token){
    config.headers.token = userStore.token
  }//config配置对象,headers属性请求头,经常给服务器端携带公共参数//返回配置对象return config
})//第三步:响应拦截器
request.interceptors.response.use((response)=>{//成功回调//简化数据return response.data
  },(error)=>{//失败回调:处理http网络错误的//定义一个变量:存储网络错误信息let message =''//http状态码const status = error.response.status
    switch(status){case401:
        message ='TOKEN过期'breakcase403:
        message ='无权访问'breakcase404:
        message ='请求地址错误'breakcase500:
        message ='服务器出现问题'breakdefault:
        message ='网络出现问题'break}//提示错误信息ElMessage({type:'error',
      message,})return Promise.reject(error)},)//对外暴露exportdefault request

创建路由器

//通过vue-router插件实现模板路由配置// vue-router对外暴露createRouter,createWebHashHistory的方法import{ createRouter, createWebHashHistory }from'vue-router'import{ constantRoute }from'./routes'//创建路由器const router =createRouter({//路由模式hashhistory:createWebHashHistory(),routes: constantRoute,//滚动行为scrollBehavior(){return{left:0,top:0,}},})exportdefault router

定义路由

// 包括常量路由 异步路由 以及任意路由// 示例exportconst asnycRoute =[{path:'/acl',component:()=>import('@/layout/index.vue'),name:'Acl',meta:{title:'权限管理',icon:'Lock',},redirect:'/acl/user',children:[{path:'/acl/user',component:()=>import('@/views/acl/user/index.vue'),name:'User',meta:{title:'用户管理',icon:'User',},},{path:'/acl/role',component:()=>import('@/views/acl/role/index.vue'),name:'Role',meta:{title:'角色管理',icon:'UserFilled',},},{path:'/acl/permission',component:()=>import('@/views/acl/permission/index.vue'),name:'Permission',meta:{title:'菜单管理',icon:'Monitor',},},],},{path:'/product',component:()=>import('@/layout/index.vue'),name:'Product',meta:{title:'商品管理',icon:'Goods',},redirect:'/product/trademark',children:[{path:'/product/trademark',component:()=>import('@/views/product/trademark/index.vue'),name:'Trademark',meta:{title:'品牌管理',icon:'ShoppingCartFull',},},{path:'/product/attr',component:()=>import('@/views/product/attr/index.vue'),name:'Attr',meta:{title:'属性管理',icon:'ChromeFilled',},},{path:'/product/spu',component:()=>import('@/views/product/spu/index.vue'),name:'Spu',meta:{title:'SPU管理',icon:'Calendar',},},{path:'/product/sku',component:()=>import('@/views/product/sku/index.vue'),name:'Sku',meta:{title:'SKU管理',icon:'Orange',},},],},]// 一般的一个路由对象包含{path:'路由地址'component:()=>import('')name:meta:{title:'路由显示的名称'icon:'图标'},redirect:''//是否重定向 重定向路由地址children:[]}

路由鉴权

//路由鉴权:鉴权,项目当中路由能不能被的权限的设置(某一个路由什么条件下可以访问、什么条件下不可以访问)import router from'@/router'import setting from'./setting'//@ts-ignoreimport nprogress from'nprogress'//引入进度条样式import'nprogress/nprogress.css'
nprogress.configure({showSpinner:false})//获取用户相关的小仓库内部token数据,去判断用户是否登录成功import useUserStore from'./store/modules/user'import pinia from'./store'const userStore =useUserStore(pinia)//全局守卫:项目当中任意路由切换都会触发的钩子//全局前置守卫
router.beforeEach(async(to: any,from: any,next: any)=>{
  document.title =`${setting.title} - ${to.meta.title}`//to:你将要访问那个路由//from:你从来个路由而来//next:路由的放行函数
  nprogress.start()//获取token,去判断用户登录、还是未登录const token = userStore.token
  //获取用户名字const username = userStore.username
  //用户登录判断if(token){//登录成功,访问login,不能访问,指向首页if(to.path =='/login'){next({path:'/'})}else{//登录成功访问其余六个路由(登录排除)//有用户信息if(username){//放行next()}else{//如果没有用户信息,在守卫这里发请求获取到了用户信息再放行try{//获取用户信息await userStore.userInfo()//放行//万一:刷新的时候是异步路由,有可能获取到用户信息、异步路由还没有加载完毕,出现空白的效果next({...to })}catch(error){//token过期:获取不到用户信息了//用户手动修改本地存储token//退出登录->用户相关的数据清空await userStore.userLogout()next({path:'/login',query:{redirect: to.path }})}}}}else{//用户未登录判断if(to.path =='/login'){next()}else{next({path:'/login',query:{redirect: to.path }})}}})//全局后置守卫
router.afterEach((to: any,from: any)=>{
  nprogress.done()})//第一个问题:任意路由切换实现进度条业务 ---nprogress//第二个问题:路由鉴权(路由组件访问权限的设置)//全部路由组件:登录|404|任意路由|首页|数据大屏|权限管理(三个子路由)|商品管理(四个子路由)//用户未登录:可以访问login,其余六个路由不能访问(指向login)//用户登录成功:不可以访问login[指向首页],其余的路由可以访问

创建仓库

//仓库大仓库import{ createPinia }from'pinia'//创建大仓库const pinia =createPinia()//对外暴露:入口文件需要安装仓库exportdefault pinia

将一些全局性对变量/函数放入仓库中

//小仓库:layout组件相关配置仓库import{ defineStore }from'pinia'const useLayOutSettingStore =defineStore('SettingStore',{state:()=>{return{fold:false,//用户控制菜单折叠还是收起控制refsh:false,//仓库这个属性用于控制刷新效果}},})exportdefault useLayOutSettingStore

定义布局

// 定义布局 并在一个main布局中接受路由组件// 比如在整个分为左侧菜单menu 顶部导航栏tabbar 主体部分main,并在main中添加<router-view></router-view>来接收路由组件// 同时还有一个问题:布局中的定位和布局问题,自适应问题(样式等)<template><!-- 路由组件出口的位置 --><router-view v-slot="{ Component }"><transition name="fade"><!-- 渲染layout一级路由组件的子路由 --><component :is="Component" v-if="flag"/></transition></router-view></template><script setup lang="ts">import{ watch, ref, nextTick }from'vue'import useLayOutSettingStore from'@/store/modules/setting'let layOutSettingStore =useLayOutSettingStore()//控制当前组件是否销毁重建let flag =ref(true)//监听仓库内部数据是否发生变化,如果发生变化,说明用户点击过刷新按钮watch(()=> layOutSettingStore.refsh,()=>{//点击刷新按钮:路由组件销毁
    flag.value =falsenextTick(()=>{
      flag.value =true})},)</script><script lang="ts">exportdefault{name:'Main',}</script><style scoped>.fade-enter-from {opacity:0;transform:scale(0);}.fade-enter-active {transition: all 0.3s;}.fade-enter-to {opacity:1;transform:scale(1);}</style>

数据大屏

// 在数据大屏中,需要注意自适应的问题,同时还有echarts等UI组件,引入和导入,初始化,设置配置项等问题<template><div class="box2"><div class="title"><p>年龄比例</p><img src="../../images/dataScreen-title.png" alt=""/></div><!-- 图形图标的容器 --><div class="charts" ref="charts"></div></div></template><script setup lang="ts">import{ ref, onMounted }from'vue'//引入echartsimport*as echarts from'echarts'let charts =ref()//组件挂载完毕初始化图形图标onMounted(()=>{let mychart = echarts.init(charts.value)//设置配置项let option ={tooltip:{trigger:'item',},legend:{right:30,top:40,orient:'vertical',//图例组件方向的设置textStyle:{color:'white',fontSize:14,},},series:[{name:'Access From',type:'pie',radius:['40%','70%'],avoidLabelOverlap:false,itemStyle:{borderRadius:10,borderColor:'#fff',borderWidth:2,},label:{show:true,position:'inside',color:'white',},labelLine:{show:false,},data:[{value:1048,name:'军事'},{value:735,name:'新闻'},{value:580,name:'直播'},{value:484,name:'娱乐'},{value:300,name:'财经'},],},],//调整图形图标的位置grid:{left:0,top:0,right:0,bottom:0,},}
  mychart.setOption(option)})</script><style scoped lang="scss">.box2 {width:100%;height:100%;background:url(../../images/dataScreen-main-cb.png) no-repeat;
  background-size:100%100%;.title {
    margin-left: 20px;

    p {color: white;
      font-size: 20px;}}.charts {height: 260px;}}</style>

业务

// 剩下的就是业务上的问题了,调用接口,渲染界面
标签: 前端

本文转载自: https://blog.csdn.net/qq_45832651/article/details/132248718
版权归原作者 码上有前 所有, 如有侵权,请联系我们删除。

“【前端Vue3 + TS项目开发一般流程】”的评论:

还没有评论