1. vite环境搭建
安装vite环境
npm init @vitejs/app
或者 yarn create @vitejs/app
使用vite初始化vue+ts项目
npm init @vitejs/app my-vue-app
或者 yarn create @vitejs/app my-vue-app
执行上面命令后选择 vue
最后选择vue-ts
最后一步进去刚刚创建的文件夹安装依赖 yarn install
2. 添加 vue-class-component
yarn add vue-class-component
因为习惯面对对象设计了,所以还是用回面对对象的语法糖吧,又可以省略学习3.0语法了
原来的app.vue
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent({
name: 'App',
components: {
HelloWorld
}
})
</script>
<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>
使用后
<!--
* @Description:
* @Autor: 杨自强
* @Date: 2021-12-31 11:16:34
* @LastEditors: 杨自强
* @LastEditTime: 2021-12-31 14:04:53
-->
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld />
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import HelloWorld from "./components/HelloWorld.vue";
@Options({
components: {
HelloWorld,
},
})
export default class App extends Vue {}
</script>
<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>
3. 看看效果
* @Description:
* @Date: 2021-12-31 11:51:52
* @LastEditTime: 2021-12-31 14:56:31
-->
<template>
<div class="hello">
<h1>{{ msg }}</h1>
{{count}}
<button @click="handleCount">count++</button>
</div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
@Options({
props: {
msg: {
type: String,
default: "134",
},
},
})
export default class HelloWorld extends Vue {
msg!: string;
count = 0;
handleCount() {
this.count ++
this.$emit('count',this.count)
}
}
</script>
4. vuex 模块
4.x 版本安装 yarn add vuex@next --save
再安装 yarn add vuex-module-decorators
创建目录store
demo.ts
以下写法是根据面向对象编写,操作原理跟原来差不多,不过比原来的用法好很多
/*
* @Description:
* @Date: 2022-01-03 09:35:07
* @LastEditTime: 2022-01-03 10:07:17
*/
import { VuexModule, Module, Mutation, Action, getModule } from 'vuex-module-decorators';
import store from '../index';
export interface IDemoState {
count: number
}
@Module({ dynamic: true, store, name: 'demo',namespaced: true })
class Demo extends VuexModule implements IDemoState {
public count = 0
@Mutation
private SET_COUNT(value: number) {
this.count = value
}
@Mutation
private CLEAR() {
this.count = 0
}
@Action
public setCount(value: number) {
this.SET_COUNT(value);
}
@Action
public clear() {
this.CLEAR();
}
}
export const DemoModule = getModule(Demo);
index.ts
import Vuex from 'vuex';
import {IDemoState} from './modules/demo'
export interface IRootState {
error: IDemoState;
}
export default new Vuex.Store<IRootState>({});
调用页面
<!--
* @Description:
* @Date: 2021-12-31 11:51:52
* @LastEditTime: 2022-01-03 10:07:21
-->
<template>
<div class="hello">
<h1>{{ msg }}</h1>
{{demoMoule.count}}
<button @click="handleCount">count++</button>
<button @click="handleClear">clear</button>
</div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import {DemoModule} from '../store/modules/demo'
@Options({
props: {
msg: {
type: String,
default: "134",
},
},
})
export default class HelloWorld extends Vue {
msg!: string;
get demoMoule() {
return DemoModule
}
mounted() {
console.log(DemoModule)
}
handleCount() {
this.demoMoule.setCount(this.demoMoule.count+1)
}
handleClear() {
this.demoMoule.clear()
}
}
</script>
配置eslint 规范
安装estlint 依赖 yarn add -D eslint eslint-plugin-vue
eslint-config-prettier
@typescript-eslint/parser
@typescript-eslint/eslint-plugin
具体配置.eslintrc.js
/*
* @Description:
* @Date: 2022-01-03 10:54:29
* @LastEditTime: 2022-01-03 14:00:51
*/
module.exports = {
env: {
browser: true,
es2021: true,
commonjs: true,
es6: true,
node: true,
},
extends: [ 'eslint:recommended', 'plugin:vue/vue3-recommended','prettier'],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['vue', '@typescript-eslint'],
rules: {
semi: ['error', 'always'],
'arrow-parens': ['error', 'always'],
'vue-scoped-css/no-unused-selector': 'off',
'comma-dangle': ['error', 'always-multiline'],
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 1, maxEOF: 1 }],
// '@typescript-eslint/no-namespace': 'off',
// '@typescript-eslint/ban-types': 'off',
// 'space-before-function-paren': 'off',
// '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
// '@typescript-eslint/no-this-alias': [
// 'error',
// {
// // Allow `const { props, state } = this`; false by default
// allowDestructuring: true,
// // Allow `const self = this`; `[]` by default
// allowedNames: ['self'],
// },
// ],
},
};
prettier
yard add prettier
.prettierc.js
/*
* @Description:
* @Date: 2022-01-03 11:07:29
* @LastEditTime: 2022-01-03 14:34:02
*/
// 参考资料:
//
// - <https://juejin.im/post/5a7d70496fb9a063317c47f1>
//
module.exports = {
/** tab的宽度 */
tabWidth: 2,
/** 使用tab进行缩进 */
useTabs: false,
/** 单行宽度 */
printWidth: 100,
/** 将多行JSX元素的 > 放在最后一行的末尾,而不是单独放在下一行(不适用于自闭元素) */
jsxBracketSameLine: false,
/** 尾随逗号 */
trailingComma: 'all',
/** 在语句的末尾打印分号 */
semi: true,
/** 使用单引号 */
singleQuote: true,
/** 方法名与括号间是否有空格 */
spaceBeforeFunctionParen: false,
/** 结尾符问题统一 */
endOfLine: 'auto',
/** 箭头函数的参数括起来 */
arrowParens: 'always',
};