vue3+vite+pinia+cass最新版本编写流程,无报红
Vue Router,pinia插件安装和使用npm install vue-router@4 pinia
新增src/router/index.ts
// 引入Vue Router的核心方法与类型
import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
// 定义所有路由规则,便于权限控制、自动化管理
const routes: RouteRecordRaw[] = [
<template>
<router-view />
</template>{
<template>
<router-view />
</template><template>
<router-view />
</template>path: '/',<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>// 首页路由
<template>
<router-view />
</template><template>
<router-view />
</template>name: 'Home',
<template>
<router-view />
</template><template>
<router-view />
</template>component: () => import('@/views/Home.vue'), // 懒加载,提升首屏性能
<template>
<router-view />
</template>},
<template>
<router-view />
</template>{
<template>
<router-view />
</template><template>
<router-view />
</template>path: '/about',<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template> // 关于页路由
<template>
<router-view />
</template><template>
<router-view />
</template>name: 'About',
<template>
<router-view />
</template><template>
<router-view />
</template>component: () => import('@/views/About.vue'),
<template>
<router-view />
</template>},
]
// 创建并导出router实例,统一在main.ts注册
export const router = createRouter({
<template>
<router-view />
</template>history: createWebHistory(), // 使用HTML5 history模式,支持SEO与回退
<template>
<router-view />
</template>routes,
})新增src/store/index.ts<template>
<router-view />
</template> (mkdir -p src/store && touch src/store/index.ts)
// 引入并创建Pinia实例,便于主入口集成
import { createPinia } from 'pinia'
// 导出Pinia实例
export const pinia = createPinia()新增src/store/useUserStore.ts<template>
<router-view />
</template><template>
<router-view />
</template>(mkdir -p src/store && touch src/store/useUserStore.ts)
// src/store/useUserStore.ts
import { defineStore } from 'pinia'
import http from '@/utils/http'
import type { UserInfo } from '@/types/user'
export const useUserStore = defineStore('user', {
<template>
<router-view />
</template>state: () => ({
<template>
<router-view />
</template><template>
<router-view />
</template>name: '未登录用户' as string,
<template>
<router-view />
</template><template>
<router-view />
</template>isLoggedIn: false as boolean,
<template>
<router-view />
</template>}),
<template>
<router-view />
</template>actions: {
<template>
<router-view />
</template><template>
<router-view />
</template>async login(name: string) {
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>// 演示写死,实际可以用 http.post 登录
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>this.name = name
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>this.isLoggedIn = true
<template>
<router-view />
</template><template>
<router-view />
</template>},
<template>
<router-view />
</template><template>
<router-view />
</template>logout() {
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>this.name = '未登录用户'
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>this.isLoggedIn = false
<template>
<router-view />
</template><template>
<router-view />
</template>},
<template>
<router-view />
</template><template>
<router-view />
</template>async fetchUser() {
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>// 泛型声明:确保 data 是 UserInfo 类型
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>const data = await http.get<UserInfo>('/user/info')
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>this.name = data.name
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>this.isLoggedIn = data.isLoggedIn
<template>
<router-view />
</template><template>
<router-view />
</template>}
<template>
<router-view />
</template>}
})新增<template>
<router-view />
</template>src/views/AppHome.vue<template>
<router-view />
</template><template>
<router-view />
</template>(mkdir -p src/views && touch src/views/AppHome.vue)
<template>
<template>
<router-view />
</template>
<template>
<router-view />
</template><template>
<router-view />
</template><h1>首页</h1>
<template>
<router-view />
</template><template>
<router-view />
</template><p>欢迎:{{ user.name }}</p>
<template>
<router-view />
</template><template>
<router-view />
</template><button v-if="!user.isLoggedIn" @click="user.login('张三')">登录</button>
<template>
<router-view />
</template><template>
<router-view />
</template><button v-else @click="user.logout()">登出</button>
<template>
<router-view />
</template><template>
<router-view />
</template><button @click="refreshUser">刷新用户信息</button>
<template>
<router-view />
</template><template>
<router-view />
</template><router-link to="/about">关于我们</router-link>
<template>
<router-view />
</template>
</template>新增tsconfig.app.json
{
<template>
<router-view />
</template>"compilerOptions": {
<template>
<router-view />
</template><template>
<router-view />
</template>"baseUrl": ".",
<template>
<router-view />
</template><template>
<router-view />
</template>"paths": {
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>"@/*": ["src/*"]
<template>
<router-view />
</template><template>
<router-view />
</template>}
<template>
<router-view />
</template>}
}新增src/views/AppAbout.vue<template>
<router-view />
</template><template>
<router-view />
</template>(touch src/views/AppAbout.vue)
<template>
<template>
<router-view />
</template>
<template>
<router-view />
</template><template>
<router-view />
</template><h1>关于我们</h1>
<template>
<router-view />
</template><template>
<router-view />
</template><p>本网站是由 Vue 3 + Vite + TypeScript 构建的现代前端项目。</p>
<template>
<router-view />
</template><template>
<router-view />
</template><router-link<template>
<router-view />
</template>to="/">返回首页</router-link>
<template>
<router-view />
</template>
</template>新增vite.config.ts
import path from 'path'<template>
<router-view />
</template>// ← 这一行很重要!
export default defineConfig({
<template>
<router-view />
</template>plugins: ,
<template>
<router-view />
</template>resolve: {
<template>
<router-view />
</template><template>
<router-view />
</template>alias: {
<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>'@': path.resolve(__dirname, 'src'),<template>
<router-view />
</template>// 确保 __dirname 和 'src' 用对
<template>
<router-view />
</template><template>
<router-view />
</template>},
<template>
<router-view />
</template>},
})修改App.vue
<template>
<router-view />
</template>sass,axios插件的安装和使用,环境变量配置,跨域
安装
npm install -D sass<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template># 只需安装 sass,Vite 已自动支持 .scss/.sassnpm install axios新建src/styles/_variables.scss<template>
<router-view />
</template> (touch src/styles/_variables.scss)
$primary-color: #42b983;
$font-size-base: 16px;src/styles/global.scss<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>(touch src/styles/global.scss<template>
<router-view />
</template>)
@use './variables' as *;body {<template>
<router-view />
</template>font-size: $font-size-base;<template>
<router-view />
</template>color: $primary-color;<template>
<router-view />
</template>font-family: 'Roboto', Arial, sans-serif;<template>
<router-view />
</template>margin: 0;}main.ts新增
import './styles/global.scss'vite.config.ts新增
<template>
<router-view />
</template>css: {<template>
<router-view />
</template><template>
<router-view />
</template>preprocessorOptions: {<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>scss: {<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>additionalData: `@use "@/styles/variables.scss" as *;`<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>}<template>
<router-view />
</template><template>
<router-view />
</template>}<template>
<router-view />
</template>},新建src/utils/http.ts<template>
<router-view />
</template><template>
<router-view />
</template>(touch src/utils/http.ts),处理不当会报错("Property 'isLoggedIn' does not exist on type 'AxiosResponse'.ts(2339)")
import axios<template>
<router-view />
</template>from 'axios'import type { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'const http = axios.create({<template>
<router-view />
</template>baseURL: import.meta.env.VITE_API_BASE_URL,<template>
<router-view />
</template>timeout: 10000,<template>
<router-view />
</template>headers: { 'Content-Type': 'application/json' }})http.interceptors.request.use(<template>
<router-view />
</template>config => config,<template>
<router-view />
</template>error => Promise.reject(error))http.interceptors.response.use(<template>
<router-view />
</template>(response: AxiosResponse) => {<template>
<router-view />
</template><template>
<router-view />
</template>if (response.data && typeof response.data === 'object' && 'data' in response.data) {<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>return response.data.data<template>
<router-view />
</template><template>
<router-view />
</template>}<template>
<router-view />
</template><template>
<router-view />
</template>return response.data<template>
<router-view />
</template>},<template>
<router-view />
</template>(error: AxiosError) => Promise.reject(error))// 重点是这一行的泛型const get = (url: string, config?: AxiosRequestConfig): Promise => {<template>
<router-view />
</template>return http.get(url, config)}const post = (url: string, data?: unknown, config?: AxiosRequestConfig): Promise => {<template>
<router-view />
</template>return http.post(url, data, config)}export default { get, post }新建.env<template>
<router-view />
</template>.env.production<template>
<router-view />
</template><template>
<router-view />
</template>(touch .env<template>
<router-view />
</template> &&<template>
<router-view />
</template> touch .env.production )
VITE_API_BASE_URL=https://dev-api.example.com
VITE_APP_TITLE=My Vite AppVITE_API_BASE_URL=https://prod-api.example.com
VITE_APP_TITLE=My Vite App 修改vite.config.ts,新增
<template>
<router-view />
</template>server: {<template>
<router-view />
</template><template>
<router-view />
</template>proxy: {<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>// 只要是 /api 开头的请求,代理到后端<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>'/api': {<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>target: 'https://dev-api.example.com',<template>
<router-view />
</template> // 后端接口地址<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>changeOrigin: true,<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>rewrite: path => path.replace(/^\/api/, ''),<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>}<template>
<router-view />
</template><template>
<router-view />
</template>}<template>
<router-view />
</template>},新建src/types/user.ts<template>
<router-view />
</template><template>
<router-view />
</template><template>
<router-view />
</template>(mkdir -p src/types &&<template>
<router-view />
</template>touch src/types/user.ts<template>
<router-view />
</template>)
// src/types/user.tsexport interface UserInfo {<template>
<router-view />
</template>name: string<template>
<router-view />
</template>isLoggedIn: boolean}总结:
数据流写法,先写http自定义请求,再写pinia连接口拿数据,之后写view层代码,写router层,(注册插件,代码结构,一般是会提前搞好)
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]