Vue3 全家桶(vue3 + typescript + vite + pinia + vue-router + axios + vue-i18n)项目搭建

文件结构

Vue3 全家桶(vue3 + typescript + vite + pinia + vue-router + axios + vue-i18n)项目搭建_第1张图片

生成一个vue项目

  • 初始化
// 使用 npm
npm init vite@latest vue3-ts-frontend --template vue-ts

// 使用 yarn
yarn create vite vue3-ts-frontend --template vue-ts
  • 添加依赖
npm install ant-design-vue -S
npm install vue-router -S
npm install vue-i18n -S
npm install pinia -S
npm install axios -S
  • 配置
  1. 修改tsconfig.json, 新增compilerOptions.baseUrlcompilerOptions.paths
{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "skipLibCheck": true,
    "baseUrl": "./", // 新增
    "paths": { // 新增
      "@": ["./src"],
      "@/*": ["./src/*"],
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
  1. 修改vite.config.ts, 新增resolve.aliasserver
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path'; // 新增

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: { // 新增
    //设置别名
    alias: {
      '@': resolve(__dirname, './src'),
    },
  },
  server: { // 新增
    port: 8080, //启动端口
    hmr: {
      host: '127.0.0.1',
      port: 8080,
    },
    // 设置 https 代理
    proxy: {
      '/api': {
        target: 'http://localhost:3000', // 后端 api 地址
        changeOrigin: true,
        rewrite: (path: string) => path.replace(/^\/api/, ''),
      },
    },
  },
});

集成 ant design vue

在 main.ts 中引入并使用

import { createApp } from 'vue';
import Antd from 'ant-design-vue';
import App from './App.vue';
import 'ant-design-vue/dist/antd.css';

const app = createApp(App);
app.use(Antd);
app.mount('#app');

集成 vue-router

  1. 在src下创建router/index.ts文件
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/login',
    name: 'login',
    meta: {
      title: '登录',
      keepAlive: true,
      requireAuth: false
    },
    component: () => import('@/pages/login/index.vue'),
  },
  {
    path: '/',
    name: 'home',
    meta: {
      title: '首页',
      keepAlive: true,
      requireAuth: true
    },
    component: () => import('@/pages/home/index.vue'),
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});
export default router;
  1. 在 main.ts 中引入并使用
import { createApp } from 'vue';
import App from './App.vue';
import router from '@/router';

const app = createApp(App);
app.use(router);
app.mount('#app');
  1. 修改App.vue
<template>
  <div id="app">
    <router-view />
  </div>
</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>

集成 vue-i18n

  1. 在src下创建locales/index.tslocales/zh-CN.tslocales/en-US.ts文件

index.ts

import { createI18n } from 'vue-i18n/index';
import zh from './zh-CN';
import en from './en-US';

const defaultLanguage = 'zh-CN';
const i18n = createI18n({
  locale: defaultLanguage,
  silentTranslationWarn: true,
  messages: { zh, en },
});

export default i18n;

zh-CN.ts

export default {
  home: {
    title: '首页',
    test: '测试',
  },
};

en-US.ts

export default {
  home: {
    title: 'Home',
    test: 'Test',
  },
};
  1. 在 main.ts 中引入并使用
import { createApp } from 'vue';
import App from './App.vue';
import i18n from '@/locales';

const app = createApp(App);
app.use(i18n);
app.mount('#app');
  1. 在 src/pages/home/index.vue 中使用
<template>
  <div>
    <h1 v-text="$t('home.title')" />
    <div v-text="test" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';

const { t } = useI18n();

const test = ref(t('home.test'));
</script>

集成 pinia

  1. 在src下创建store/index.tsstore/user.ts文件

index.ts

import { createPinia } from 'pinia';

const store = createPinia();
export default store;

user.ts

import { defineStore } from 'pinia';

export const useUserStore = defineStore({
  id: 'user', // 必填且唯一
  state: () => {
    return {
      name: 'TFBoys',
    };
  },
  actions: {
    updateName(name: string) {
      this.name = name;
    },
  },
});
  1. 在 main.ts 中引入并使用
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

const app = createApp(App);
app.use(store);
app.mount('#app');
  1. 在 src/pages/home/index.vue 中使用
<template>
  <div>
    <div v-text="userStore.name" />
    <a-button v-text="$t('home.updateState')" @click="onUpdateName" />
  </div>
</template>

<script setup lang="ts">
import { useUserStore } from '@/store/user';

const userStore = useUserStore();
const onUpdateName = () => {
  // 通过 actions 去修改 state
  userStore.updateName('杨洋');
}
</script>

Vue3 全家桶(vue3 + typescript + vite + pinia + vue-router + axios + vue-i18n)项目搭建_第2张图片

集成 axios

  1. 在src下创建utils/request.ts文件
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios';

const service = axios.create({
  // baseURL: 'http://localhost:3000',
  withCredentials: true,
});

// Request interceptors
service.interceptors.request.use(
   (config: AxiosRequestConfig) => {
    // do something
    return config;
   },
   (error: any) => {
    Promise.reject(error);
   }
);

// Response interceptors
service.interceptors.response.use(
  async (response: AxiosResponse) => {
    // do something
    return response.data;
   },
   (error: any) => {
    // do something
    return Promise.reject(error);
   }
);

export default service;
  1. 在src下创建engine/index.tsengine/Users.ts文件

index.ts

import Users from './Users';

export {
  Users,
};

Users.ts

import request from '@/utils/request';

export default class Users {
  static fetchAll = () => request.get(`/api/users/list`);
};
  1. 在 src/pages/home/index.vue 中使用
<template>
  <div>
    <div v-for="user in userList" :key="user.id">
      {{ user.username }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { Users } from '@/engine';

const userList = ref([]);
const init = async() => {
  const { data } = await Users.fetchAll();
  userList.value = data;
};

init();
</script>

Vue3 全家桶(vue3 + typescript + vite + pinia + vue-router + axios + vue-i18n)项目搭建_第3张图片
Vue3 全家桶(vue3 + typescript + vite + pinia + vue-router + axios + vue-i18n)项目搭建_第4张图片
关于后台的搭建可参考
Nodejs + Express 搭建 简单的 后台服务

你可能感兴趣的:(前端,typescript,vue.js,javascript)