# Vue3与TSX尝鲜版 ## 涉及到的主要依赖 1. `vite@2.0.4` 2. `vue@3.0.7` 3. `vuex@4.0.0` 4. `vue-router@4.0.4` 5. `typescript@4.2.2` ## 准备工作 1. 确保安装`yarn` ```bash npm install yarn -g ``` 2. 确保安装`vite`脚手架 ```bash npm install -g create-vite-app # or yarn add -g create-vite-app ``` ## 开始 ### 项目初始化 ```bash yarn create vite-app ``` ### 集成TS ```bash yarn add --dev typescript ``` 项目根目录创建配置文件:`tsconfig.json`: ```js { "include": ["./**/*.ts"], "compilerOptions": { "jsx": "react", "target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, // "lib": ["es2017.object"] /* Specify library files to be included in the compilation. */, // "declaration": true /* Generates corresponding '.d.ts' file. */, // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ "sourceMap": true /* Generates corresponding '.map' file. */, // "outFile": "./", /* Concatenate and emit output to single file. */ "outDir": "./dist" /* Redirect output structure to the directory. */, "strict": true /* Enable all strict type-checking options. */, "noUnusedLocals": true /* Report errors on unused locals. */, "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ } } ``` ### 集成eslint ```bash yarn add --dev eslint eslint-plugin-vue ``` 项目根目录创建配置文件`.eslintrc.js`: ```js module.exports = { parser: 'vue-eslint-parser', parserOptions: { parser: '@typescript-eslint/parser', // Specifies the ESLint parser ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features sourceType: 'module', // Allows for the use of imports ecmaFeatures: { // tsx: true, // Allows for the parsing of JSX jsx: true, }, }, // settings: { // tsx: { // version: "detect" // Tells eslint-plugin-react to automatically detect the version of React to use // } // }, extends: [ 'plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. ], rules: { // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs // e.g. "@typescript-eslint/explicit-function-return-type": "off", }, }; ``` ### 集成pritter ```bash yarn add --dev prettier eslint-config-prettier eslint-plugin-prettier ``` 项目根目录创建配置文件:`.prettierrc.js`: ```js module.exports = { semi: true, trailingComma: "all", singleQuote: true, printWidth: 100, tabWidth: 2, endOfLine:"auto" }; ``` 到这一步,一个Vue3+TSX的项目就搭建起来了,以上配置文件的具体内容就不做解释了。 ### 修改入口文件 因为默认项目模板是以`src/main.js`为入口的,我们需要把它修改为`src/main.ts`。 在`根目录的index.html`中修改入口文件的引用即可: ```html ... ... ... ... ``` ### 优化TS类型推断 在src目录下,创建`shim.d.ts、source.d.ts` `shim.d.ts`: (这个其实不太需要,因为项目中全是通过tsx开发的) ```ts declare module '*.vue' { import Vue from 'vue'; export default Vue; } ``` `source.d.ts`: (优化编译器提示,声明静态资源文件) ```ts declare const React: string; declare module '*.json'; declare module '*.png'; declare module '*.jpg'; ``` ### 集成vue-router ```bash yarn add --dev vue-router@4.0.4 ``` 这里可以去`npm官网`查找最新版本 在src目录下,`新建router文件夹`,并在文件夹内`创建index.ts` `index.ts`: ```js import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router'; const routes: RouteRecordRaw[] = [ { path: '/', name: 'Home', component: () => import('../views/Home'), }, { path: '/about', name: 'About', component: () => import('../views/About'), }, ]; const router = createRouter({ history: createWebHistory(), routes, }); export default router; ``` 这里创建router的方式与之前不同,在vue3中,结合TS的类型推断,开发效率会高很多。 ### 集成vuex ```bash yarn add --dev vuex@4.0.0 ``` 在src目录下,新建store文件夹,并在文件夹内创建`index.ts` `index.ts`: ```js import { state } from './state'; import { createStore } from 'vuex'; export default createStore({ state, mutations: {}, actions: {}, modules: {}, }); ``` `state.js`: ```js export interface State { title: string; } export const state: State = { title: 'Vue(v3) 与 tsx 的结合~', }; ``` ### main.ts 最终main.ts中引入store、router: ```js import { createApp } from 'vue'; import App from './App'; import router from './router'; import store from './store'; createApp(App).use(router).use(store).mount('#app'); ``` ### TSX 最终我们的组件代码,都会是这样的:`App.tsx`: ```js import { defineComponent } from 'vue'; import {RouterLink, RouterView} from 'vue-router'; import './style/main.scss' export default defineComponent({ name: 'App', setup() { return () => ( <> ); } }); ``` 自我感觉TSX比模板好多了,并且html、组件标签的属性都带有类型推断。 ## 结尾 vue3正式版的发布,势必导致vue2的周边框架的集体更新,例如UI框架、基于Vue2的指令库等,作为这么久的白嫖党,也要为vue3社区的建设出一份力了。 Vue3与TS的结合是大趋势,如果不适应TS,那还是建议使用Vue2吧。23333~ 后续博主也将研究vite框架和vue3全家桶的新特性与API,争取输出有质量的文档。 *** 参考文章: [https://github.com/hyperMoss/vue-tsx](https://github.com/hyperMoss/vue-tsx)