# take_out_vue **Repository Path**: qwe2982213384/take_out_vue ## Basic Information - **Project Name**: take_out_vue - **Description**: 移动端外卖项目前端,基于vite+vue3+axios+vant3技术栈 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: dev - **Homepage**: https://gitee.com/qwe2982213384/take_out_vue - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-08-04 - **Last Updated**: 2023-08-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 0 接口文档地址 `http://121.89.205.189:3001/apidoc/#api-Banner-GetBannerList` # 1 下载项目模板 ``` # npm 6.x npm create vite@latest vue3-mobile-shop --template vue # npm 7+ npm create vite@latest vue3-mobile-shop -- --template vue ``` # 2 运行项目 ``` cd vue3-mobile-shop npm install npm run dev ``` # 3 环境变量文件 ```js // .env.development VITE_BASE_URL=/api ``` ```js // .env.production VITE_BASE_URL= http://121.89.205.189:3001/api ``` # 4 配置 + sass支持:`npm install sass -S` + 12 + vant支持: `https://vant-contrib.gitee.io/vant/#/zh-CN/` + `npm install vant` + `npm install unplugin-vue-components -D` ```js // vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path'; // vant按需加载包 import Components from 'unplugin-vue-components/vite'; import { VantResolver } from 'unplugin-vue-components/resolvers'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), // 配置vant组件按需加载 Components({ resolvers: [VantResolver()], }) ], // 配置别名 resolve:{ alias:{ "@":path.resolve(__dirname,'src') } }, // 配置代理服务器 server:{ // 设置局域网访问 // npm run dev --host host:'0.0.0.0', proxy:{ '/api':{ target:'http://121.89.205.189:3001', changeOrigin:true } } } }) ``` # 4 配置ts支持.vue文件和@别名 + 修改main.js为main.ts + 修改index.html中引入的文件为:main.ts + 在项目根目录书写ts配置文件和env.d.ts类型定义文件 ```js // tsconfig.json { "compilerOptions":{ "baseUrl": "./", "paths": { "@/*": ["src/*"] }, "lib": ["ES6", "DOM"], "module": "esnext", "moduleResolution": "node", "types": ["vite/client"] } } ``` ```js // env.d.ts declare module '*.vue' { import { DefineComponent } from "vue"; const component: DefineComponent<{}, {}, any> export default component; } ``` # 5 统一配置请求响应拦截器 + 下载axios:`npm install axios -S` ```js // utils/request.ts import axios from 'axios' import { Notify } from 'vant'; let baseURL = import.meta.env.VITE_BASE_URL // 创建axios的一个实例 const request = axios.create({ baseURL, timeout:5000, }) // 给实例添加请求拦截器 request.interceptors.request.use(config=>{ config.headers.token = localStorage.getItem('token')||''; return config; },(err)=>{ return Promise.reject(err) }) // 给实例添加请求响应拦截器 request.interceptors.response.use((res)=>{ // 响应内容中有token就自动存储到本地存储 if(res.data?.data?.token){ localStorage.setItem('token',res.data.data.token) } // 响应内容中有message提示信息 if(res.data?.message){ const type = res.data.code==200?'success':'danger'; // vant 里面的函数组件 Notify Notify({ message: res.data.message, type, }) } // 把后端数据提前出来给then return res.data },(err)=>{ console.log(err); return Promise.reject(err) }) // 后期使用这个实例发送请求,就会有上面的默认配置 export default request; ``` # 6 配置pinia和vue-router和reset.css > App.vue ```html ``` > store/userStore.ts ```js import { defineStore } from "pinia"; export const useUserStore = defineStore('user',{ state(){ return { userid:'', tel:'' } }, actions:{ setUserId(payload:string){ this.userid = payload; // 当获取用户id,把他存到本地存储 - 数据的持久化 localStorage.setItem('userid',payload) }, setTel(payload:string){ this.tel = payload; // 当获取用户tel,把他存到本地存储 - 数据的持久化 localStorage.setItem('tel',payload) }, logout(){ this.userid = ''; this.tel = ''; localStorage.removeItem('userid') localStorage.removeItem('tel') localStorage.removeItem('token') } } }) ``` > router/index.ts ```js import {createRouter,createWebHashHistory} from 'vue-router' import Home from '@/views/Home.vue'; import Register from '@/views/Register/index.vue'; import Step1 from '@/views/Register/Step1.vue'; import Step2 from '@/views/Register/Step2.vue'; import Step3 from '@/views/Register/Step3.vue'; import Address from '@/views/Address.vue'; import Login from '@/views/Login.vue'; import Cart from '@/views/Cart.vue'; import City from '@/views/City.vue'; import Detail from '@/views/Detail.vue'; import NotFound from '@/views/NotFound.vue'; import Search from '@/views/Search.vue'; import Order from '@/views/Order.vue'; import User from '@/views/User.vue'; const routes = [ {path:'/',component:Home}, { path:'/register', component:Register, redirect:'/register/step1', children:[ {path:'step1',component:Step1}, {path:'step2',component:Step2}, {path:'step3',component:Step3}, ] }, { path:'/address', component:Address, meta:{ needCheckLogin:true } }, {path:'/login',component:Login}, { path:'/cart', component:Cart, meta:{ needCheckLogin:true } }, {path:'/city',component:City}, {path:'/detail/:id',component:Detail}, {path:'/search',component:Search}, { path:'/order', component:Order, meta:{ needCheckLogin:true } }, { path:'/user', component:User, meta:{ needCheckLogin:true } }, {path:'/:pathMatch(.*)*',component:NotFound} ]; const router = createRouter({ history:createWebHashHistory(), routes:routes as any }) // 全局路由守卫 router.beforeEach(to=>{ // to:去到的路由信息对象 if(to.meta.needCheckLogin){ console.log('需要检查登录状态'); return true; }else{ console.log("不需要检查登录状态"); return true; } }) export default router; ``` > style/reset.css ```css html,body{ height:100%; width: 100%; background-color: #f6f6f6;; } *{ margin: 0; padding: 0; } a{ color:black; text-decoration: none; } a:active,a:hover,a:visited{ color:black; text-decoration: none; } img{ display: block; } ``` > main.ts ```js // main.ts import { createApp } from 'vue' import App from './App.vue' import {createPinia} from "pinia" import router from '@/router' import '@/style/reset.css' import 'vant/es/image-preview/style'; import 'vant/es/toast/style'; import 'vant/es/dialog/style'; import 'vant/es/notify/style'; createApp(App).use(createPinia()).use(router).mount('#app') ```