至此,我们就完成了将 Vue 3.x 搭建 TypeScript 环境、搭建完整项目结构的攻略。
一、准备工作
1. 安装 node.js(版本需大于等于 12.0.0) 和 npm(版本需大于等于 6.0.0);
2. 在终端中执行 npm install -g @vue/cli 安装 Vue CLI(版本需大于等于 4.5.0);
3. 在终端中执行 vue create my-project 创建一个 Vue 项目;
4. 在创建项目的时候,选择 Manually select features,然后选择 TypeScript、Router、Vuex、Linter / Formatter;
5. 等待项目的依赖安装完成后,在终端运行 npm run serve 启动项目。
二、Vue3 携手 TypeScript
1. 安装依赖:在终端中运行 npm install --save-dev vue@next @vue/compiler-sfc @vue/test-utils @types/node @types/vue @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-plugin-vue;
2. 配置 TypeScript:在项目根目录创建 tsconfig.json 文件,并添加以下内容:
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "test/"]
}
- 修改 main.ts:将import Vue from 'vue'修改为import { createApp } from 'vue'、Vue.config.productionTip = false修改为app.config.productionTip = false、new Vue({ render: h => h(App) }).$mount('#app')修改为app.mount('#app');
- 修改样式文件(.css/.less/.scss):在样式文件最顶部添加lang="scss"(示例为 Sass);
- 配置 webpack:在项目根目录创建 vue.config.js文件,并添加以下内容:
module.exports = {
    chainWebpack: config => {
        // TypeScript Loader
        config.module
            .rule('typescript')
            .test(/\.ts$/)
            .use('babel-loader')
            .loader('babel-loader')
            .end()
            .use('ts-loader')
            .loader('ts-loader')
            .end()
            .include
            .add(/src/)
            .add(/test/)
            .end();
    }
};
- 创建组件:在 src/components目录下创建一个名为HelloWorld.vue的组件,并添加以下内容:
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: String
  }
});
</script>
<style lang="scss">
.hello {
  h1 {
    font-size: 36px;
  }
}
</style>
- 修改 App.vue:在 Vue3.x 中,需要在主组件中使用defineComponent定义父组件。修改src/App.vue文件,并添加HelloWorld组件:
<template>
  <div id="app">
    <HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
  </div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
export default defineComponent({
  name: 'App',
  components: {
    HelloWorld
  }
})
</script>
- 验证效果:在终端中运行 npm run serve,在浏览器中查看项目是否正常运行。
三、搭建完整项目结构
1. 目录结构参考:
my-project/
├── node_modules/
├── public/
├── src/
│   ├── api/
│   │   └── index.ts            // 接口请求工具的定义
│   ├── assets/
│   │   ├── logo.png
│   │   └── ...
│   ├── components/
│   │   └── HelloWorld.vue
│   ├── router/
│   │   └── index.ts            // 路由配置
│   ├── store/
│   │   ├── index.ts            // Vuex store 的定义
│   │   ├── actions.ts
│   │   ├── mutations.ts
│   │   ├── getters.ts
│   │   └── modules/
│   ├── utils/
│   │   ├── index.ts            // 工具函数
│   │   └── ...
│   ├── views/
│   │   ├── Home.vue
│   │   └── ...
│   ├── App.vue
│   └── main.ts
├── tests/
│   ├── e2e/
│   └── unit/
├── .eslintrc.js
├── babel.config.js
├── package-lock.json
├── package.json
└── tsconfig.json
- 编写接口请求工具:在 src/api目录下创建index.ts文件,并添加以下内容:
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
interface RequestOptions extends AxiosRequestConfig {}
interface RequestPromise extends Promise<AxiosResponse<any>> {}
export class Http {
  private static DEFAULT_TIMEOUT = 10000;
  private $http: AxiosInstance;
  private static instance: Http;
  private constructor(config: RequestOptions) {
    this.$http = axios.create(config);
  }
  public static getInstance(config: RequestOptions): Http {
    if (!this.instance) {
      this.instance = new Http({
        timeout: Http.DEFAULT_TIMEOUT,
        ...config
      });
    }
    return this.instance;
  }
  public request(options: RequestOptions) {
    const instance = this.$http;
    return instance(options) as RequestPromise;
  }
}
export const http = Http.getInstance({
  baseURL: 'https://jsonplaceholder.typicode.com/'
});
- 配置路由:在 src/router目录下创建index.ts文件,并添加以下内容:
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '../views/Home.vue';
const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
];
const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});
export default router;
- 创建 Vuex store:在 src/store目录下创建index.ts文件,并添加以下内容:
import { createStore } from 'vuex';
import { actions } from './actions';
import { mutations } from './mutations';
import { getters } from './getters';
import { moduleA } from './modules/moduleA';
export default createStore({
  state: {
    count: 0
  },
  mutations,
  actions,
  getters,
  modules: {
    moduleA
  }
});
- 在 src/main.ts中引入路由和 Vuex:在main.ts文件中,引入 Router 和 Vuex :
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
const app = createApp(App);
app.use(router);
app.use(store);
app.mount('#app');
- 测试:在浏览器中打开 http://localhost:8080,路由和 Vuex 是否正常运行。
至此,我们就完成了将 Vue 3.x 搭建 TypeScript 环境、搭建完整项目结构的攻略。
示例说明:
1. 在接口请求工具之中,使用 class 和 interface 进行封装,并在外部调用时使用单例的模式返回实例,避免了频繁创建的问题;
2. 在模块化 Vuex store 的过程中,我们使用模块化的方式对 store 进行分层。在 moduleA.ts 文件中,我们看到除了 state、mutations、actions、getters 之外,还会有子模块 children,以此来进行更加细致和完善的 store 管理。
本文标题为:Vue3 携手 TypeScript 搭建完整项目结构
 
				
         
 
            
        - Bootstrap每天必学之标签与徽章 2024-02-25
- axios和ajax的区别点总结 2023-02-24
- BootStrap入门教程(三)之响应式原理 2024-01-02
- CSS linear-gradient属性案例详解 2022-11-20
- 网页设计经验之杜绝设计中的视觉噪音(图文) 2024-01-03
- 微信小程序输入多行文本的实战记录 2024-02-20
- 使用CSS的pointer-events属性实现鼠标穿透效果的神奇技巧 2024-01-05
- js直接编辑当前cookie的脚本 2023-12-01
- jQuery中文入门指南,翻译加实例,jQuery的起点教程 2024-02-07
- 使用AngularJS实现表单向导的方法 2024-01-05
 
						 
						 
						 
						 
						 
				 
				 
				 
				