前言:vue3+ts+vite大家已经都开始用了,最近也在学习,基本上是零基础开始ts的学习,很多语法知识是边写边查,没有系统的学习ts。此处展示从零开始,搭建的一个框架,方便拿来即用!

1. 初始化一个vite项目

npm create vite@latest

其中框架选择vue,语言选择typeScript

2. 启动项目

npm install

npm run dev

项目启动成功以后如下所示:

3. 修改目录

为了方便日常工作中的框架使用,在此处对刚初始化好的框架进行改造,在原有框架的基础上,添加store,router,layout,utils,views等文件夹,其中的作用将在后面进行说明。如图所示:

4. 配置router

首先安装vue-router的依赖

npm install vue-router

在router文件夹下创建index.ts文件,配置如下:

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';

const routes: Array = [

// 项目打开后进入的默认地址

{

path: '/',

redirect: '/login'

},

{

path: '/login',

component: () => import('../views/login/login.vue')

},

{

path: '/home',

component: () => import('../views/home/home.vue')

}

]

const router = createRouter({

history: createWebHashHistory(), // 本项目采用了哈希模式

routes

})

export default router

路由文件配置以后,需要在main.ts文件中进行引用,如下所示:

import { createApp } from 'vue'

import './style.css'

import App from './App.vue'

const app = createApp(App)

// 路由设置

import router from './router/index'

app.use(router)

app.mount('#app')

修改app.vue文件,根据实际情况进行修改,本项目中不需要初始化的helloWord组件,所以修改如下所示:

在views文件夹中创建login.vue文件,并重新启动项目,如图所示,跳转到登陆页面后表示路由配置成功: vue文件中使用路由的方法如下:

import { useRouter, useRoute} from 'vue-router'

const router = useRouter()

const route = useRoute()

// 路由跳转

router.push('/xxx')

**补充:**路由hash模式与history模式的区别

hash模式 示例:http://localhost:5173/#/login 原理:利用window监听的onhashchange事件,不会包含在http请求中,对后端完全没有影响。history模式 示例:http://localhost:5173/login 原理:地址发生改变后,会按照改变后的地址向服务端发送请求,需要后端配合处理,做地址映射。

5.配置vuex(pinia)

pinia 是一个拥有组合式API的状态管理库。 pinia官网: https://pinia.vuejs.org/zh/introduction.html 首先安装pinia的依赖

npm install pinia

在store文件夹中创建index.ts,具体内容如下:

import type {App} from 'vue'

import { createPinia } from "pinia";

const store = createPinia()

export function setupStore(app:App) {

app.use(store)

}

export {store}

然后在store文件夹中创建modules文件夹,并创建user.ts 文件,用来保存用户的基本信息。

import { defineStore } from 'pinia'

import { store } from '../index'

interface userInfoType {

username: string,

age: number,

gender: string

}

export const useUserStore = defineStore('user', () => {

// 此处使用的是组合式API的方式,更多情况可查看官网

let userInfo: userInfoType = {

username: '小明',

age: 18,

gender: '男'

}

return {

userInfo

}

},

)

// 最后到处定义的useUserStore

export function useUserStoreHook() {

return useUserStore(store)

}

store的基本信息配置好以后,需要在main.ts问价中挂载到app组件上,如下:

import { setupStore } from './store'

// 挂载store

setupStore(app);

存储在vuex中的数据使用方式如下:

// login.vue 文件

效果如下:

6. element-plus 的基本使用

首先安装依赖

npm install element-plus

官网: https://element-plus.org/zh-CN/guide/design.html 本项目中使用的是方法是在main.ts文件中完整导入!main.ts文件如下:

// element-plus

import ElementPlus from 'element-plus'

import 'element-plus/dist/index.css'

// 导入所有的icon图标

import * as ElementPlusIconsVue from '@element-plus/icons-vue'

app.use(ElementPlus)

for (const [key, component] of Object.entries(ElementPlusIconsVue)) {

app.component(key, component)

}

在vue文件中基本使用方法:

import { ElMessage } from 'element-plus'

ElMessage('你好')

7. axios封装

对于前后分离的项目来说,绑定后端提供的接口进行数据增删改查是业务中较为重要的部分,此处对axios的使用进行封装,方便向服务断发送请求。 依旧是安装axios的依赖:

npm install axios

axios的接口封装文件如下:

import axios from 'axios';

import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'

import {getCookie,setCookie} from '../../utils/cookie'

const service: AxiosInstance = axios.create({

baseURL: import.meta.env.VITE_APP_API_BASEURL,

timeout: 15000,

headers: {

'Content-Type': 'application/json'

},

});

interface requestConfig extends AxiosRequestConfig {

headers?: any

}

// axios实例拦截请求

service.interceptors.request.use(

(config: requestConfig) => {

const token = getCookie('token');

if (token) {

config.headers.token = token

}

return config;

},

(error: AxiosError) => {

return Promise.reject(error);

},

);

// axios实例拦截响应

service.interceptors.response.use(

(response: AxiosResponse) => {

if (response.status === 200) {

return response;

}

return response;

},

// 请求失败

(error: any) => {

const { response } = error;

if (response) {

// 请求已发出,但是不在2xx的范围

return Promise.reject(response.data);

}

},

);

/***

* post 方法封装

*/

export function postMethod(url:string,params?:any):Promise {

return new Promise((resolve, reject) => {

service.post(url,params).then((res:any) => {

if(res.data.code === 200 && res.headers['token']) {

setCookie('token',res.headers['token'],21600)

}

resolve(res.data)

}).catch((err) => {

reject(err)

})

})

}

/***

* get 方法封装

*/

export function getMethod(url:string,params?:any):Promise {

return new Promise((resolve, reject) => {

service.get(url,params).then((res:any) => {

if(res.data.code === 200 && res.headers['token']) {

setCookie('token',res.headers['token'],21600)

}

resolve(res.data)

}).catch((err) => {

reject(err)

})

})

}

/**

* 文件上传 方法封装

* 上传文件传参方式注意为form-data格式

*/

export function uploadFile(url:string,uploadForm:any):Promise{

const fd = new FormData()

fd.append('fileName', uploadForm.projectId)

fd.append('file', uploadForm.file)

return new Promise((resolve, reject) => {

service.post(url,fd,{

headers: {

'Content-Type': 'multipart/form-data'

}

}).then((res:any) => {

if(res.data.code === 200 && res.headers['token']) {

setCookie('token',res.headers['token'],21600)

}

resolve(res.data)

}).catch((err) => {

reject(err)

})

})

}

8. cookie封装

用户登录的时候,提交表单信息,需要对接口返回的token进行存储,此处使用了cookie进行存储,可以利用js-cookie库进行cookie存储,也可自己封装方法,此处是封装cookie的方法进行cookie的存储,获取,以及清除,如下所示:

// cookie.ts

/**

* cookie 浏览器缓存

*/

const domain = ''

// 时间单位为秒

export function setCookie(c_name: string, value: any, expire?: any) {

var date: any = new Date()

date.setSeconds(date.getSeconds() + expire)

document.cookie = c_name + '=' + escape(value) + '; expires=' + date.toGMTString() + '; domain=' + domain + ';path=/'

}

export function getCookie(c_name: string) {

let c_start: number

let c_end: number

if (document.cookie.length > 0) {

c_start = document.cookie.indexOf(c_name + '=')

if (c_start != -1) {

c_start = c_start + c_name.length + 1

c_end = document.cookie.indexOf(';', c_start)

if (c_end == -1) c_end = document.cookie.length

return unescape(document.cookie.substring(c_start, c_end))

}

}

return ''

}

export function delCookie(c_name:string) {

setCookie(c_name, '', -1)

}

9. localStorage 使用

在获取localStorage存储信息时,发现存在一个问题,在vue文件中的setup的语法糖中,直接使用JSON的序列化方法会标红,可以正常使用,但是存在类型问题。将其进行封装后,发现这个问题不在出现,在vue文件中使用时,直接引入即可。如下所示:

// localStorage.ts

/**

* window.localStorage 浏览器永久缓存

*/

export const localStorage = {

// 设置永久缓存

set(key: string, val: any) {

window.localStorage.setItem(key, JSON.stringify(val));

},

// 获取永久缓存

get(key: string) {

const json: any = window.localStorage.getItem(key);

return JSON.parse(json);

},

// 移除永久缓存

remove(key: string) {

window.localStorage.removeItem(key);

},

// 移除全部永久缓存

clear() {

window.localStorage.clear();

}

};

10. 框架地址

gitee地址: https://gitee.com/free_project/vue3_ts_frame.git 目前只有一个空架子,针对表单的使用等还未进行展示;因为对ts不熟,好多类型都设置了any。若有问题还请指出!

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: