vue3+ts+vite 项目实战笔记

一、创建项目

1、项目初始化

执行npm create vite@latest 命令,根据提示,给项目命名,选择vue3框架、ts 语言

2、下载依赖

npm install

3、运行

npm run dev

二、前置工作

1、eslint 校验代码工具配置

2、prettier 格式化工具配置

3、husky 配置

4、commitLint 配置

5、项目中集成 elment-plus

main.ts 中

import ElementPlus from "element-plus"
//@ts-ignore
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import 'element-plus/dist/index.css'

let app = createApp(App)
app.use(ElementPlus, {
  locale: zhCn
})
app.mount('#app')

5、src 文件夹别名配置

vite.config.ts

resolve: {
  alias: {
    "@": path.resolve("./src")  //相对路径别名配置,使用 @ 代替 src
  }
}

tsconfig.json

"compilerOptions": {
  "baseUrl": "./",  //解析非相对模块的基地址,默认为当前目录
  "paths": {
    "@/*": ["src/*"]
  }
},

6、配置项目环境变量

  • 根目录创建 .env.development 和 .env.production
    .env.development
# 变量必须以 VITE_ 为前缀才能暴露给外部使用
NODE_ENV = "development"
VITE_APP_TITLE = "硅谷甄选运营平台-开发环境"
VITE_APP_BASE_API = "/dev-api"
VITE_SERVE = "http://xxx.com"

.env.production

# 变量必须以 VITE_ 为前缀才能暴露给外部使用
NODE_ENV = "production"
VITE_APP_TITLE = "硅谷甄选运营平台-生产环境"
VITE_APP_BASE_API = "/prod-api"
VITE_SERVE = "http://yyy.com"
  • 使用
console.log(import.meta.env)

7、svg 图标的封装与使用

  • 1:下载 vite-plugin-svg-icons
    npm i vite-plugin-svg-icons -D
  • 2:vite.config.ts中配置,
//引入path
import path from 'path'
// 引入 createSvgIconsPlugin
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
export default defineConfig({
  plugins: [
    vue(),
    createSvgIconsPlugin({
      iconDirs: [path.resolve(process.cwd(), "src/assets/icons")], //svg 图标需要放到 src/assets/icons 目录下
      symbolId: "icon-[dir]-[name]"
    })
  ],
})
  • 3:在入口文件 main.ts 中导入配置项
//导入配置项
import "virtual:svg-icons-register"
  • 4:使用
    以 iconfont 字体图标库为例
    • 图标库中找到对应图标(star),点击下载,在弹框中复制 SVG 代码
    • 在 src/assets/icons 目录下,新建 star.svg 文件,将 上面复制的 SVG 代码复制进去(此时浏览器打开文件可以显示图标)
    • 组件内使用,
<svg>
	<!-- href 也可以使用 xlink:href,值需要固定为 #icon-svg图标名,fill 为颜色-->
	<use href="#icon-star" fill="yellow"></use>
</svg>

8、注册自定义的全局组件

注册全局组件有两种方法:

  • 方法1:每增加一个全局组件,就手动引入,然后进行注册
//main.ts 文件中
//引入全局组件
import SvgIcon from '@/components/SvgIcon/index.vue'
//注册全局组件
app.component("SvgIcon",SvgIcon)

注:如果要注册很多全局组件,这里就需要引入、注册多次,比较麻烦

  • 方法2:components 下新增 index.ts,在里面引入组件,遍历注册组件
// index.ts
//引入 全局组件
import SvgIcon from "./SvgIcon/index.vue"
import Test from "./test.vue"

let allGloabComponent ={
  SvgIcon,
  Test
}
//对外暴露插件对象
export default {
  //install 方法会在页面初始化时候执行,该方法有一个参数,该参数是 main.ts 中创建的 app 对象
  install(app) {
    // console.log("allGloabComponent")
    // 循环注册全局组件
    Object.keys(allGloabComponent).forEach(key => {
      app.component(key, allGloabComponent[key])
    })
  }
}
//main.ts 文件
//引入自定义插件对象,注册整个项目全局组件
import gloablComponent from "@/components"
console.log(gloablComponent)
//安装自定义插件(gloablComponent是带有 install 方法的一个对象,安装gloablComponent以后,初始化时,会执行install方法)
app.use(gloablComponent)

9、集成sass,并重置样式

  • 下载 sass
  • 创建 src/style/index.scss、src/style/reset.scss、src/style/variable.scss
    • index.scss 是全局样式文件,要在 main.ts 中引入import "./style/index.scss"。index.scss 里面会引入其他所有 scss 文件,这个文件中,没有办法使用 $ 变量,所以需要另外创建 scss 文件(variable.scss ,名称随意,但是要跟 vite.config.js 中统一),专门用来存放变量
    • reset.scss 是统一全局样式的文件,可以在 npm 官网搜索 reset.scss 文件,把内容复制过来
    • variable.scss 是存放 scss 变量的文件(需要在 vite.config.ts 中配置)

1)index.scss

// 引入全局样式
@import "./reset.scss"; //后面必须加分号,否则会报错

2)variable.scss

$base-color: green;
$title-color: blue;

3)vite.config.ts

export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        javascriptEnabled: true,
        additionalData: '@import "./src/style/variable.scss";'  //引入存放scss全局变量的文件
      }
    }
  }
})

@import "./src/style/variable.scss";后一定要加分号,否则会报错。

10、mock 接口

安装依赖:https://github.com/vbenjs/vite-plugin-mock

  • 下载 vite-plugin-mock npm install -D vite-plugin-mock@2.9.6 mockjs
  • 在 vite.config.js 中配置文件启用插件(注意:这里 vite-plugin-mock 要用 2.9.6 版本,否则在配置 localEnabled: command === "serve" 时会报错,不清楚什么原因 )
// 引入 mock 方法
import { viteMockServe } from 'vite-plugin-mock'
export default defineConfig(( { command } ) => {
  return {
    plugins: [
      vue(),
      viteMockServe({
     localEnabled: command === "serve"
   })
  }
})
  • 在根目录创建mock文件夹:去创建我们需要mock数据与接口!!!
  • 在mock文件夹内部创建一个user.ts文件
//用户信息数据
function createUserList() {
  return [
    {
      userId: 1,
      avatar:
        'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
      username: 'admin',
      password: '111111',
      desc: '平台管理员',
      roles: ['平台管理员'],
      buttons: ['cuser.detail'],
      routes: ['home'],
      token: 'Admin Token',
    },
    {
      userId: 2,
      avatar:
        'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
      username: 'system',
      password: '111111',
      desc: '系统管理员',
      roles: ['系统管理员'],
      buttons: ['cuser.detail', 'cuser.user'],
      routes: ['home'],
      token: 'System Token',
    },
  ]
}

export default [
  // 用户登录接口
  {
    url: '/api/user/login',//请求地址
    method: 'post',//请求方式
    response: ({ body }) => {
      //获取请求体携带过来的用户名与密码
      const { username, password } = body;
      //调用获取用户信息函数,用于判断是否有此用户
      const checkUser = createUserList().find(
        (item) => item.username === username && item.password === password,
      )
      //没有用户返回失败信息
      if (!checkUser) {
        return { code: 201, data: { message: '账号或者密码不正确' } }
      }
      //如果有返回成功信息
      const { token } = checkUser
      return { code: 200, data: { token } }
    },
  },
  // 获取用户信息
  {
    url: '/api/user/info',
    method: 'get',
    response: (request) => {
      //获取请求头携带token
      const token = request.headers.token;
      //查看用户信息是否包含有次token用户
      const checkUser = createUserList().find((item) => item.token === token)
      //没有返回失败的信息
      if (!checkUser) {
        return { code: 201, data: { message: '获取用户信息失败' } }
      }
      //如果有返回成功信息
      return { code: 200, data: { checkUser } }
    },
  },
]
  • 安装axios npm install axios
  • 在main.ts中测试接口,接口返回 200 表示请求成功
//测试接口
import axios from "axios"
axios({
  url: "/api/user/login",
  method: "post",
  data: {
    username: 'admin',
    password: '111111',
  }
})

11、axios 二次封装

目的:
1、使用请求拦截器,可以在请求拦截器中处理一些业务(开始进度条、请求头携带公共参数等)
2、使用响应拦截器,可以在响应拦截器中处理一些业务(结束进度条,简化服务器返回的数据,处理 http 网络错误)

在创建src/utils/request.ts

// 进行 axios 二次封装:使用请求与响应lan jie q
//引入 axios
import axios from "axios";
// 引入 element-plus 的提示框组件,在请求失败的时候,弹出失败信息
import { ElMessage } from "element-plus";
// 这里通过 axios 创建的 request 实例,可以增加一些配置信息
//第一步:利用 axios 对象的create方法,创建一个axios实例(其中可配置:基础路径、超时时间)
let request = axios.create({
  // 这里的 import.meta.env.VITE_APP_BASE_API 读取到的是 .env.xxx(如.env.development) 文件中的相关配置
  baseURL: import.meta.env.VITE_APP_BASE_API, 
  // 配置超时时间
  timeout: 5000
});
// 第一步:请求拦截器
request.interceptors.request.use((config) => {
  // config 里面包含了 baseURL、method、url、headers、timeout 等
  // console.log(config)
  // 这里要 return 出去,否则请求发不出去
  return config;
})
// 第二步:响应拦截器
request.interceptors.response.use((response:any) => {
  //成功的回调,作用:简化数据
  // response 中包含 请求的config(数据同第17行)、接口响应的 data、状态 status、headers等
  // console.log(response)
  // 将接口响应的数据返回
  return response.data;
}, (error) => {
  // 错误回调,处理错误信息
  // error 是接口请求失败的信息,包含 code 和 config、message、response(接口失败的信息)
  // console.log(error)
  let status = error.response.status, message = "";
  switch (status) {
    case 401: 
      message = "TOKEN过期";
      break; 
    case 403:
      message = "无权访问";
      break;
    case 404:
      message = "请求地址错误";
      break;
    case 500:
      message = "服务器出现问题";
      break;
    default:
      message = "网络出现问题";
      break;
  }
  ElMessage({
    type: "error",
    message
  })
  return Promise.reject(error);
})

export default request;

组件内使用:

import { onMounted } from "vue";
import request from "@/utils/request.ts"
onMounted(() => {
  request({
    url: "/user/login",
    method: "post",
    data: {
      username: 'admin',
      password: '111111'
    }
  }).then((res) => {
    console.log(res)
  })
})

12、API 接口统一管理

创建apis目录,按照模块创建目录,配置接口地址及出入参数据类型,如:
src/apis/user/index.ts:该文件配置接口接口、接口出入参的类型
src/apis/user/type.ts:定义出入参的数据类型

//src/apis/user/index.ts
// 统一管理项目用户相关的接口
import request from "@/utils/request";
// import 语法会将整个模块文件加载进去
// import type 只会从模块中获取类型信息
import type { loginForm, loginResponseData, userResponseData } from "./type";

enum API {
  LOGIN_URL = "/user/login",
  USERINFO_URL = "/user/info"
}

export const reqLogin = (data:loginForm) => request.post<any,loginResponseData>(API.LOGIN_URL, data)
export const reqUserInfo = () => request.post<any,userResponseData>(API.USERINFO_URL)
//type.ts
// 定义登录接口需要携带的参数的 ts 类型
export interface loginForm {
  username: string,
  password: string
}
interface dataType {
  token: string
}
// 定义登录接口返回的数据类型
export interface loginResponseData {
  code: number,
  data: dataType
}

interface checkUser {
  userId: number,
  avatar: string,
  username: string,
  password: string,
  desc: string,
  roles: string[],
  buttons: string[],
  routes: string[],
  token: string

}

interface user {
  checkUser: checkUser
}

// 定义接口返回用户信息相关的数据类型
export interface userResponseData {
  code: number,
  data: user
}

组件中发送请求:

import { onMounted } from "vue";
import { reqLogin } from "./apis/user/index.ts"

onMounted(() => {
  reqLogin({username: "admin", password: "111111"}).then((res) => {
    console.log(res)
  })
})

13、路由配置

  • 创建 src/router/index.ts(路由相关配置)、src/router/routes.ts(路由列表)
  • 创建 src/views 目录,里面按模块创建目录及对应页面组件如:src/views/404/index.vue、src/views/home/index.vue、src/views/login/index.vue
  • 入口文件 src/main.ts 引入路由并进行注册
  • 入口模版组件使用 <router-view></router-view> 显示路由组件
//src/router/index.ts
// 引入创建路由实例的方法,和创建 hash(createWebHashHistory) / history(createWebHistory) 模式的方法
import { createRouter, createWebHashHistory } from "vue-router"

import { constantRoute } from "./routes.ts"
let router = createRouter({
  // 配置路由模式:hash
  history: createWebHashHistory(),
  // 配置路由
  routes: constantRoute,
  //路由切换时,页面滚动到顶部左侧
  scrollBehavior() {
    return {
      top: 0,
      left: 0
    }
  }
});

export default router;
//src/router/routes.ts
//对外暴露配置的路由
  export const constantRoute = [
    {
      path: "/login",
      name: "登录",
      component: () => import ("@/views/login/index.vue")
    },
    {
      path: "/404",
      name: "404",
      component: () => import ("@/views/404/index.vue")
    },
    {
      path: "/",
      name: "home",
      component: () => import ("@/views/home/index.vue")
    },
    {
      // 路由都匹配不上时,匹配这个任意路由,重定向到 404
      path: "/:pathMatch(.*)",
      name: "any",
      redirect: "/404"
    }
  ]
// main.ts
// 引入路由
import router from "./router"
//注册路由
app.use(router)
<!--App.vue-->
<template>
  <router-view></router-view>
</template>
  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3 + TypeScript + Vite 是一种常见的前端项目搭建方式,它结合了Vue框架的最新版本Vue3、TypeScript语言和Vite构建工具。这种项目搭建方式可以提供更好的开发体验和性能优化。 在Vue3中,可以使用`watch`方法来监听数据的变化。通过`import { watch, ref } from "vue"`引入相关的模块,然后在`setup`函数中使用`watch`方法来监听数据的变化。例如,可以创建一个`ref`对象来存储数据,并使用`watch`方法来监听该数据的变化。在`watch`的回调函数中,可以执行一些操作,比如发送异步请求。具体的代码示例如下: ```javascript import { watch, ref } from "vue" const name = ref('') export default defineComponent({ setup(props) { watch(name, () => { // 可添加异步请求 }) } }) ``` 基于Vue3 + Element + Vite的基本后台管理系统是可以成型的。除了这些基本的组件和工具之外,还可以根据需要自行添加其他功能,比如配置ESLint代码规范。此外,还可以进一步学习Vue3的其他高级用法,可以通过阅读其他相关的文章来深入了解。 #### 引用[.reference_title] - *1* [vite+vue3+ts 手把手教你创建一个vue3项目](https://blog.csdn.net/weixin_59916662/article/details/127331094)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [基于vue3 + ts + vite项目初探](https://blog.csdn.net/m0_49569569/article/details/124782445)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值