话不多说,先创建vue-ts模版,
npm create vite@latest my-vite-vue-ts -- --template vue-ts
?
?
安装其他依赖:
npm i vue-router sass sass-loader pinia element-plus axios @element-plus/icons-vue fast-glob vite-plugin-svg-icons
npm install --save @types/nprogress
?修改 main.ts
import { createApp } from 'vue'
import App from './App.vue'
//引入 pinia store
import { createPinia } from 'pinia'
//引入 element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import Router from '@/router'
import '@/router/beforeEach'
//引入 vite-plugin-svg-icons
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon/index.vue'// svg component
import * as Icons from '@element-plus/icons-vue'
const pinia = createPinia()
const app =createApp(App)
// 注册svgIcon为全局组件
app.component('svg-icon', SvgIcon)
// 注册全局组件
Object.keys(Icons).forEach(key => {
app.component(key, Icons[key as keyof typeof Icons])
// console.log(key);
})
app.use(pinia)
app.use(ElementPlus)
app.use(Router)
app.mount('#app')
修改 vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import { resolve } from "path";
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [resolve(process.cwd(), "src/icons/svg")],
// 指定symbolId格式
symbolId: "icon-[dir]-[name]",
/**
* custom dom id
* @default: __svg__icons__dom__
*/
customDomId: "__svg__icons__dom__",
}),
],
resolve: {
// 配置别名
alias: {
"@": resolve(__dirname, "./src"),
},
},
//启动服务配置
server: {
host: "0.0.0.0",
port: 8000,
open: true,
https: false,
proxy: {},
},
// 生产环境打包配置
//去除 console debugger
build: {
minify: "terser",
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
});
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }],
"exclude": ["node_modules", "dist"]
}
?package
{
"name": "my-vite-vue-ts",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^1.1.4",
"@types/nprogress": "^0.2.0",
"axios": "^0.26.1",
"element-plus": "^2.1.4",
"fast-glob": "^3.2.11",
"pinia": "^2.0.12",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"vite-plugin-svg-icons": "^2.0.1",
"vue": "^3.2.25",
"vue-router": "^4.0.14"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.2.0",
"typescript": "^4.5.4",
"vite": "^2.8.0",
"vue-tsc": "^0.29.8"
}
}
?app.vue
<script lang="ts">
import HelloWorld from "./components/HelloWorld.vue";
import { defineComponent, ref } from "vue";
export default defineComponent({
// 已启用类型推断
props: {
// testA : String,
},
components: {
HelloWorld,
},
setup() {
return {};
},
});
</script>
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
router/index.ts
import { createRouter, createWebHashHistory } from "vue-router";
const modules = import.meta.glob("../views/*/*.vue");
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod);
});
}
const Router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: "/login",
component: modules["../views/login/index.vue"],
},
{
path: "/",
component: modules["../views/dashboard/index.vue"],
},
],
});
export default Router;
router/beforEach.ts
import router from "./index";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { RouteLocationNormalized } from "vue-router";
NProgress.configure({ showSpinner: false });
router.beforeEach(
async (
to: RouteLocationNormalized,
_: RouteLocationNormalized,
next: any
) => {
// Start progress bar
NProgress.start();
console.log(
"------router.beforeEach and nprogress is working---------------"
);
next();
}
);
router.afterEach((to: RouteLocationNormalized) => {
NProgress.done();
});
components/SvgIcon/index.vue
<template>
<div
v-if="isExternal"
:style="styleExternalIcon"
class="svg-external-icon svg-icon"
/>
<svg v-else :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
<script lang="ts">
import { defineComponent, computed } from "vue";
import { isExternal } from "@/utils/validate";
export default defineComponent({
name: "SvgIcon",
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: String,
default: "",
},
},
computed: {
isExternal() {
return isExternal(this.iconClass);
},
iconName() {
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className) {
return "svg-icon " + this.className;
} else {
return "svg-icon";
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
"-webkit-mask": `url(${this.iconClass}) no-repeat 50% 50%`,
};
},
},
});
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
views/dashboard/index.vue
<template>
<div class="dashborad">
dashborad
<p>
<router-link to="/login">
<span class="text">Red -- sass is working </span>
</router-link>
</p>
<p>
<el-button type="primary"
>Button element is working---------------</el-button
>
</p>
<p>
<span>
<svg-icon :icon-class="'eye'" :class-name="'abc'" /> svgIcon is working---------------
</span>
</p>
<p>
<el-icon :size="20"><alarm-clock /></el-icon>
el-icon is working---------------
</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { usemainStore } from "@/store/index";
export default defineComponent({
data() {
const mainStore = usemainStore();
console.log(
"------router is working---------------" + this.helloWorld + this.count
);
mainStore.changeState();
return {};
},
watch: {},
mounted() {},
methods: {},
});
</script>
<style lang="scss">
.dashborad {
font-size: 20px;
.text {
color: red;
}
}
</style>
?npm run dev 可以正常跑起来。接下来。?
?接下来添加mock
修改main.ts
import '@/mock/login'
?添加*.d.ts
declare module 'mockjs';
添加src/mock/login.ts?
import Mock from "mockjs";
Mock.mock("/api/login", "post", function (params: String) {
return {
code: 200,
data: "xxx",
msg: "success",
};
});
修改dashboard.vue
mounted() {
const mainStore = usemainStore();
mainStore.changeState();
},
修改changeState
changeState() {
this.count++;
this.helloWorld = "haha";
console.log(
"------pinia is working---------------" + this.helloWorld + this.count
);
loginApi
.login({
userName: "a",
passWord: "a",
})
.then((res) => {
console.log(res);
});
},
添加loginApi
import http from "@/service/http";
import * as T from "./types";
const loginApi: T.ILoginApi = {
login(params) {
console.log("start post ");
return http.post("/login", params);
},
};
export default loginApi;
export interface ILoginParams {
userName: string;
passWord: string | number;
}
export interface ILoginApi {
login: (params: ILoginParams) => Promise<any>;
}
http.ts
//http.ts
import axios, { AxiosRequestConfig } from "axios";
import NProgress from "nprogress";
//?设置请求头和请求路径
axios.defaults.baseURL = "/api";
axios.defaults.timeout = 10000;
axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
axios.interceptors.request.use(
(config): AxiosRequestConfig<any> => {
const token = window.sessionStorage.getItem("token");
if (token) {
//@ts-ignore
config.headers.token = token;
}
return config;
},
(error) => {
return error;
}
);
//?响应拦截
axios.interceptors.response.use((res) => {
if (res.data.code === 111) {
sessionStorage.setItem("token", ""); //?token过期操作
}
return res;
});
interface ResType<T> {
code: number;
data?: T;
msg: string;
err?: string;
}
interface Http {
get<T>(url: string, params?: unknown): Promise<ResType<T>>;
post<T>(url: string, params?: unknown): Promise<ResType<T>>;
upload<T>(url: string, params: unknown): Promise<ResType<T>>;
download(url: string): void;
}
const http: Http = {
get(url, params) {
return new Promise((resolve, reject) => {
NProgress.start();
axios
.get(url, { params })
.then((res) => {
NProgress.done();
resolve(res.data);
})
.catch((err) => {
NProgress.done();
reject(err.data);
});
});
},
post(url, params) {
return new Promise((resolve, reject) => {
NProgress.start();
axios
.post(url, JSON.stringify(params))
.then((res) => {
NProgress.done();
resolve(res.data);
})
.catch((err) => {
NProgress.done();
reject(err.data);
});
});
},
upload(url, file) {
return new Promise((resolve, reject) => {
NProgress.start();
axios
.post(url, file, {
headers: { "Content-Type": "multipart/form-data" },
})
.then((res) => {
NProgress.done();
resolve(res.data);
})
.catch((err) => {
NProgress.done();
reject(err.data);
});
});
},
download(url) {
const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = url;
iframe.onload = function () {
document.body.removeChild(iframe);
};
document.body.appendChild(iframe);
},
};
export default http;
?package.json
{
"name": "my-vite-vue-ts",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^1.1.4",
"@types/nprogress": "^0.2.0",
"axios": "^0.26.1",
"element-plus": "^2.1.4",
"fast-glob": "^3.2.11",
"pinia": "^2.0.12",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"vite-plugin-svg-icons": "^2.0.1",
"vue": "^3.2.25",
"vue-router": "^4.0.14"
},
"devDependencies": {
"@vitejs/plugin-vue": "^2.2.0",
"typescript": "^4.5.4",
"vite": "^2.8.0",
"vue-tsc": "^0.29.8"
}
}
?结果拦截成功。本文到此结束。需要源码打包的看下面链接。没分的留言。
vite-vue-ts精简模版集成pinia+svg+router+@src-Typescript文档类资源-CSDN下载本源码已经调试通过集成Vite-vue-ts集成pinia+svg+router+@srca更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/ldy889/85018930
|