记录自己从0到1写的第一个vue3项目

305 阅读4分钟

Vite3.0+Vue3+TypeScript+Pinia+Vant搭建移动端项目

1、项目初始化

按步骤提示创建项目

1.使用vite-cli命令创建项目
yarn create vite
2.输入项目名称
success Installed "create-vite@3.0.0" with binaries:
      - create-vite
      - cva
? Project name: » vite-project
3.选择项目使用的框架,在这里我们选择使用vue,默认是vue3
? Select a framework: » - Use arrow-keys. Return to submit.
    vanilla
>   vue
    react
    preact
    lit
    svelte
4.项目是否使用TypeScript
? Select a variant: » - Use arrow-keys. Return to submit.
    vue
>   vue-ts
5.进入项目,下载包,启动项目
cd vite-vue3-ts-pinia
yarn 
yarn dev

2.初始配置的调整

1.下载@types/node

//node.js本身并不支持typescript,所以直接在typescript项目里使用是不行的
yarn add @types/node

2.vite.config.ts文件

import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
​
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd(), '')
  return {
    base: './',// vite打包的前端项目默认只能通过根目录访问项目,比如http://localost:3000/,如果加上一个路径在进行访问会导致资源文件访问404,所以需要设置base路径
    plugins: [
      vue(),
    ],
    resolve: {
      // 设置路径简写
      alias: {
        '@': path.resolve(__dirname, './src'),
      }
    },
    server: {
      port: 80, //启动端口
      host: '0.0.0.0',
      open: '/',
      // 设置 https 代理
      proxy: {
        '/api': {
          target: 'address',
          changeOrigin: true,
          rewrite: (path: string) => path.replace(/^/api/, ''),
        },
      },
    },
    build: {
      // 提高超大静态资源警告门槛  默认500kb,修改为1500kb
      chunkSizeWarningLimit: 1500,
      // 清除console和debugger
      terserOptions: {
        compress: {
          drop_console: true,
          drop_debugger: true,
        },
      },
      rollupOptions: {
        output: {
          //对静态文件进行打包处理(文件分类)
          chunkFileNames: 'static/js/[name]-[hash].js',
          entryFileNames: 'static/js/[name]-[hash].js',
          assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
        }
      },
      outDir:'打包后输出文件位置',
    }
  }
});
​

3.Pinia

1.下载pinia

yarn add pinia

2.使用 官方文档:链接

1.src/store 目录并在其下面创建 index.ts,导出 store
 import { createPinia } from 'pinia'
​
 const store = createPinia()
​
 export default store
2.在 main.ts 中引入并使用
 import { createApp } from 'vue'
 import App from './App.vue'
 import store from './store'
 // 创建vue实例
 const app = createApp(App)
 // 挂载pinia
 app.use(store)
 // 挂载实例
 app.mount('#app');
3.定义State: 在 src/store 下面创建一个 user.ts
 import { defineStore } from 'pinia'
​
 export const useUserStore = defineStore({
   id: 'user', // id必填,且需要唯一
   state: () => {
     return {
       name: '张三'
     }
   },
   actions: {
     updateName(name) {
       this.name = name
     }
   }
 })
4.获取State: 在 src/components/usePinia.vue 中使用
 <template>
   <div>{{ userStore.name }}</div>
 </template>
​
 <script lang="ts" setup>
 import { useUserStore } from '@/store/user'
​
 const userStore = useUserStore()
 </script>
5.修改State:
 // 1. 直接修改 state (不建议)
 userStore.name = '李四'
​
 // 2. 通过 actions 去修改
 <script lang="ts" setup>
 import { useUserStore } from '@/store/user'
​
 const userStore = useUserStore()
 userStore.updateName('李四')
 </script>

4.vue-router4

1.下载

yarn add vue-router

2.使用

1.在src/router路径下创建router.ts并到导出router
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'home',
    meta: {
      title: '首页',
      keepAlive: true,
      intercept: false, // 校验登录
    },
    component: () => import('../views/home/index.vue'),
  },
  {
    path: '/my',
    name: 'my',
    meta: {
      title: '我的',
      keepAlive: true,
      intercept: false,
    },
    component: () => import('../views/my/index.vue'),
  },
  {
    path: '/my/setup',
    name: 'setup',
    meta: {
      title: '设置',
      keepAlive: true,
      intercept: false,
    },
    component: () => import('../views/my/setUp.vue'),
  },
];
​
const router = createRouter({
  history: createWebHistory(),
  routes,
});
export default router;
2.在main.ts中引入并使用
import { createApp } from 'vue';
import App from './App.vue';
​
import router from '@/router/router';
const app = createApp(App);
​
app.use(router);
app.mount('#app');
3.路由拦截

src下创建permission文件,内容如下:

import router from "@/router/router"
import { useUserInfo } from "@/store"
​
​
router.beforeEach((to: any, from: any, next: any) => {
  const userInfo = useUserInfo()
  const token = userInfo.token ?? false
  const url = to.path
​
  // 1.已登录 去登录页->跳转首页
  if (token && url === '/login') {
    next('/')
  }
​
  // 2.已登录 去其他页面->放行
  if (token && url !== '/login') {
    next()
  }
​
  // 3.未登录且intercept为true->跳转登录页
  if (!token && to.meta?.intercept) {
    next('/login')
  }
​
  // 4.未登录且intercept为false->放行
  if (!token && !to.meta?.intercept) {
    next()
  }
})

在main.ts中引入

import './permission'

5.vant 官方文档:链接

1.下载vant本体

yarn add vant

2.下载按需引入插件

yarn add unplugin-vue-components -D

3.配置插件,vite.config.ts文件中配置

import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd(), '')
  return {
    plugins: [
      vue(),
      Components({
        resolvers: [VantResolver()],
      }),
    ],
  }
})

4.tip

Vant 中有个别组件是以函数的形式提供的,包括 Toast,Dialog,Notify 和 ImagePreview 组件。在使用函数组件时,unplugin-vue-components 无法自动引入对应的样式,因此需要手动引入样式。

main.ts

import 'vant/es/toast/style';
import 'vant/es/dialog/style';
import 'vant/es/notify/style';
import 'vant/es/image-preview/style';

6.移动端rem适配

1.下载

yarn add postcss-pxtorem amfe-flexible

2.vite.config.ts文件中使用

import { defineConfig, loadEnv } from 'vite';
import postCssPxToRem from 'postcss-pxtorem'// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd(), '')
  return {
    ...
    css: {
      postcss: {
        plugins: [
          postCssPxToRem({
            // vant组件的兼容处理
            rootValue({ file }) {
              return file.indexOf('vant') !== -1 ? 37.5 : 72;
            },
            propList: ['*'],
            selectorBlackList: ['van']
          })
        ]
      }
    },
    ...
  }
});
​
​

3.main.ts中使用

import "amfe-flexible";//引入rem  

7.axios

1.下载

yarn add axios

2.使用

1.src/utils/axios.ts
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios';
​
const service = axios.create({
  // 本地开发时使用proxy代理接口
  baseURL: import.meta.env.VITE_MODE === "development" ? '/api' : import.meta.env.VITE_AXIOS_URL,
  timeout: 10000
}); // Request interceptors
​
​
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // do something
    return config;
  },
  (error: any) => {
    Promise.reject(error);
  }
); // Response interceptors
​
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // do something
    return Promise.resolve(response)
  },
  (error: any) => {
    // do something
    return Promise.reject(error);
  }
);
​
export default service;
​
2.src/api/login.ts
import request from '@/utils/axios';
​
/**
 * @description: 账号登录
 * @param {string} username 账户
 * @param {string} password 密码
 * @return {*}
 */
export const sign_in = (username: string, password: string) => {
  return request.get('/', { username, password });
}

\