The latest project needs to bevueThe project is transformed in combination with the use of ts. This should be the development trend of medium and large projects. I saw a good introductory tutorial, combined with it and made some expansion records. This article starts from installation to vueComponentsThe writing has been explained, suitable for getting started.
1. IntroduceTypescript
npm install vue-class-component vue-property-decorator --save
npm install ts-loader typescript tslint tslint-loader tslint-config-standard --save-dev
vue-class-component: Extend vue to support typescript, and use the original vue syntax to support ts by declaring it
vue-property-decorator: Extend more decorators based on vue-class-component
ts-loader: enable webpack to recognize ts files
tslint-loader: tslint is used to constrain file encoding
tslint-config-standard: tslint configures standard-style constraints
2. Configuration file
webpack configuration
Depending on the different configurations of the project, if the project created by vue cli 3.0 needs to be configured in the middle, if it is a version below 3.0, it needs to be configured in the middle. (The following instructions are changed in the file)
Add .ts in the purpose is to introduce ts files in the code without writing .ts suffix.
resolve: {
extensions: ['.js', '.vue', '.json', '.ts'],
alias: {}
}
Add rules of ts in
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
enforce: 'pre',
loader: 'tslint-loader'
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/]
}
}
]
}
Configuration
The ts-loader will retrieve the file and parse the ts file using the rules. For detailed configuration, please refer to /docs/handbook/
Post test project documents
{
// Compile options
"compilerOptions": {
// Output directory
"outDir": "./output",
// Whether to include sourceMap that can be used for debug
"sourceMap": true,
// Analysis in strict mode
"strict": false,
// Module system used
"module": "esnext",
// How to handle modules
"moduleResolution": "node",
// Compile output target ES version
"target": "es5",
// Allow default import from modules that have not been set to default export
"allowSyntheticDefaultImports": true,
// Use each file as a separate module
"isolatedModules": false,
// Enable the decorator
"experimentalDecorators": true,
// Enable design type metadata (for reflection)
"emitDecoratorMetadata": true,
// Report an error when there is any type implicit in expression and declaration
"noImplicitAny": false,
// nofunctionAll return paths have return values and errors are reported.
"noImplicitReturns": true,
// Import external help library from tslib: such as __extends, __rest, etc.
"importHelpers": true,
// Print file name during compilation
"listFiles": true,
// Remove comments
"removeComments": true,
"suppressImplicitAnyIndexErrors": true,
// Compilation allowedjavascriptdocument
"allowJs": true,
// parse the base directory of non-relative module names
"baseUrl": "./",
// Specify the path to the special module
"paths": {
"jquery": [
"node_modules/jquery/dist/jquery"
]
},
// List of library files that need to be introduced during compilation
"lib": [
"dom",
"es2015",
""
]
}
}
Configuration
Add a new file to the directory. Since we installed tslint-config-standard before, we can directly use the rules in tslint-config-standard, and the file is as follows:
{
"extends": "tslint-config-standard",
"globals": {
"require": true
}
}
3. Let the project identify.ts
Since TypeScript does not support *.vue suffix files by default, when introducing it in the vue project, you need to create a file and place it in the root directory.
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
4. Writing vue components
Most methods in the vue component are changed to use @xxx (decorator) to indicate the currently defined data, similar to the injection in ng. The business logic js part can be directly written in ts.
Basic writing
The writing method of template template and style style remains unchanged, and the script module has been changed. The basic writing method is as follows:
import { Component, Vue } from "vue-property-decorator";
@Component
export default class Test extends Vue {
};
lang="ts": The current language under script Zhang declares is ts
@Component: Indicate this class as a vue component
export default class Test extends Vue: export current component class inherits vue
Define data in data()
The data in data has been changed from the original data() method to be directly defined in the object.
export default class Test extends Vue {
public message1: string = "heimayu";
public message2: string = "It looks so good";
}
props value
Props is not as comfortable as data, because it needs to use a decorator. The following is the writing method
@Prop()
propA:string
@Prop()
propB:number
$emit value
Without parameters
// Originally written: this.$emit('bindSend')
// Write now directly ()
// Multiple definitions
@Emit()
bindSend():string{
return
}
Method with parameters
// Originally written: this.$emit('bindSend', msg)
// Now write directly: (msg)
// Multiple definitions below
@Emit()
bindSend(msg:string){
// to do something
}
emit with parameters
// The test here is to change the @ event name referenced by the component. At this time, you should write @test instead of @bindSend2
@Emit('test)
private bindSend2(){
}
Watch watch data
// Original writing method watch:{}
@Watch('propA',{
deep:true
})
test(newValue:string,oldValue:string){
console.log('propA value changed' + newValue);
}
computed compute attribute
public get computedMsg(){
return 'Here is the computed property' + ;
}
public set computedMsg(message:string){
}
Complete code case
{{message}}
import { Component, Prop, Vue, Watch, Emit } from "vue-property-decorator";
import Hello from "./";
// Indicate this class as a vue component
@Component({
components: {
Hello
}
})
export default class Test extends Vue {
// The data in the original data is expanded and written here
public message: string = "asd";
//Expand data in original props
@Prop({
type: Number,
default: 1,
required: false
})
propA?: number
@Prop()
propB:string
//Original computed
public get computedMsg(){
return 'Here is the computed property' + ;
}
public set computedMsg(message:string){
}
//Original watch attribute
@Watch('propA',{
deep:true
})
public test(newValue:string,oldValue:string){
('propA value changed' + newValue);
}
// In the past, when you needed to pass values to the parent, you could just use emit in the method directly. Currently, you need to use emit to process it
@Emit()
private bindSend():string{
return
}
@Emit()
private bindSend1(msg:string,love:string){
// If you do not process, you can not write the following, and the parameters will be automatically passed back.
// msg += 'love';
// return msg;
}
//The original method placed in methods is flattened
public handleSend():void {
this.bindSend1(,'love');
}
// The parameters in emit here indicate what the parent accepts, similar to the previous $emit('Parent defined method')
@Emit('test')
private bindSend2(){
return 'This can be accepted by test';
}
}
summary