preface
There is relatively little support for Typescript in the official Vue2 documentation. There are two ways to define components
- use
Vue.component
或Vue.extend
Define Vue components - use
vue-class-component
Decorator to define class-based Vue components
There is another way to do this on the market, and that is the community’s secondary encapsulation of vue-property-decorators based on vue-class-Component decorators, which we’ll be sharing today
NPM vue-property-decorator Document address
Build WebPack5 + Vue2 + Ts
Install node, VUE-CLI, webpack TS these here I will not describe more, do not understand the partners can see my previous several articles, there is about the environment build, the build project is relatively simple, refer to vue-CLI build project
Go to the directory where the project is to be created and run the CMD command
vue create vue-ts-demo
Copy the code
Enter, we select the third custom option
Then, check the typescript box of your choice, which I selected below
After press enter, select 2.x because we are sharing vue 2.x + ts
This is followed by some description of the configuration, yes/no, and of course a series of yes’s, and then here it is
Familiar, so let’s go into the project directory and start the project, and then we can take a quick look at the project directory structure at this point, and most of the directory structures are familiar, just with a little change
- Added tsconfig.json (ts configuration file)
- Shims-tsx.d.ts (TSX support)
- Shims-vue.d. ts (supports TS for VUE)
The other difference is that vue is written in TS when you open the file. Take a home.vue to show you
<template>
<div class="home">
<img alt="Vue logo" src=".. /assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
@Component({
components: {
HelloWorld,
},
})
export default class Home extends Vue {}
</script>
Copy the code
It looks very different from the syntax of the vue template we wrote before, don’t worry, today we are going to share how vue2 uses TS, ok, into the whole, let’s go straight to the code
How to write components
How to create a vue component using vue-property-derActor
Component creates a Component
The @Component decorator can receive an object as a parameter and declare components, filters, directives, etc. There is no decorator option (shown below)
Basic template syntax
<template>
<div class="about">
<h1>I'm the About.vue component</h1>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component
export default class about extends Vue {}
</script>
Copy the code
@prop Receives parameters
The @prop decorator takes a parameter and is often used this way
@Prop('String')
: specifyprop
Type, stringString, Number, Boolean
Etc.@Prop({ default: 1, type: Number })
: object that specifies the default value{default:'1'}
@Prop([String,Number])
: array, specifiedprop
The optional type of[String, Boolean]
// Parent component:
<template>
<div class="Props">
<Child :name="name" :age="age" :sex="sex"></Child>
</div>
</template>
<script lang="ts">
import {Component, Vue,} from 'vue-property-decorator';
import Child from './Child.vue';
@Component({
components: {Child}, // it says @component is an acceptable argument
})
export default class PropsPage extends Vue {
private name = 'Hs';
private age = 18;
private sex = 1;
}
</script>
// Subcomponent:
<template>
<div>
name: {{name}} | age: {{age}} | sex: {{sex}}
</div>
</template>
<script lang="ts">
import {Component, Vue, Prop} from 'vue-property-decorator';
@Component
export default class Child extends Vue {
@Prop(String) readonly name! : string |undefined;
@Prop({ default: 20.type: Number}) private age! : number; @Prop([String.Number]) private sex! : string | number; }</script>
Copy the code
@propsync is not the same as @prop
The @propSync decorator is used in much the same way as @prop, except that the parent component needs to match.sync when passed
- The first parameter is the name of the property passed by the parent component
- The second argument is the same as the first argument to @prop
- @propSync will generate a new calculated property,
Properties passed by the parent component can be reversed, and the parent component changes them synchronously
// Parent component:
<template>
<div class="Props">
<Child :name.sync="name"></Child>
</div>
</template>
<script lang="ts">
import {Component, Vue,} from 'vue-property-decorator';
import Child from './Child.vue';
@Component({
components: { Child }, // it says @component is an acceptable argument
})
export default class PropsPage extends Vue {
private name = 'Hs';
}
</script>
// Subcomponent:
<template>
<div>
name: {{name_copy}}
<button @click="setProp">Modify the prop</button>
</div>
</template>
<script lang="ts">
import {Component, Vue, PropSync} from 'vue-property-decorator';
@Component
export default class Child extends Vue {
@PropSync("name".String) name_copy! : string |undefined;
setProp(){
this.name_copy = "abcd" // The parent component changes synchronously}}</script>
Copy the code
@ Watch listen
The @watch decorator accepts two arguments:
- Name of the property being listened on
- Optional attributes: {immediate? : Boolean Whether to call the callback function,deep, immediately after the listener starts? : Boolean depth listening}
<template>
<div class="about">
<h3> {{age}}</h3>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from "vue-property-decorator";
@Component
export default class About extends Vue {
private age = 18;
@Watch("age")
// Optional @watch ('age', {immediate: true, deep: true})
onChangeAge(v: number, o: number): void{}}</script>
Copy the code
@emit Broadcast events
The @EMIT decorator receives an optional parameter, broadcast event name, or broadcast event name with the callback method name if this parameter is not defined
- The return value of the callback function defaults to the second argument, or if promise is returned, the resolve callback is triggered by default
/ / the parent component
<template>
<div class="about">
<ChildComp @childEmit="chileEmit" />
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import ChildComp from "./Child.vue";
@Component
export default class About extends Vue {
chileEmit(n: string): void {
console.log("Child component emit, argument:", n); }}</script>
/ / child component
<template>
<div>
<h3>I'm a child component</h3>
<button @click="customClickName"> @emit age+1 </button>
</div>
</template>
<script lang="ts">
import { Component, Emit, Vue } from "vue-property-decorator";
@Component
export default class Child extends Vue {
@Emit("childEmit")
customClickName(): string {
return "hs"}}</script>
Copy the code
@ ref handle
The @ref decorator takes an optional argument to reference an element or child component, that is, Ref =” this value”
<template>
<div class="about">
<button @click="getRef"
ref="child_btn">age++</button>
<hr>
<ChildComp :name="name"
:age="age"
ref="child_c"
@childEmit="chileEmit" />
</div>
</template>
<script lang="ts">
import { Component, Provide, Ref, Vue, Watch } from "vue-property-decorator";
import ChildComp from "./Child.vue";
@Component({
components: { ChildComp }
})
export default class About extends Vue {
@Ref("child_c") readonly child_comp! : ChildComp; @Ref("child_btn") readonly child_btn_dom! : HTMLButtonElement;getRef() {
console.log(this.child_comp, this.child_btn_dom); }}</script>
Copy the code
@provide / @inject and @providereActive / @Injectreactive ‘
Provide/inject a decorator. The key can be string or symbol and is used the same way
- Same: Provide/ProvideReactive data, use Inject/InjectReactive inside child components are available
- Difference: The value of ProvideReactive is modified by the parent and the child can be captured using InjectReactive
// Top-level component
<template>
<div class="about">
<ChildComp />
</div>
</template>
<script lang="ts">
import{Component, Provide, Vue}from "vue-property-decorator";
import ChildComp from "./Child.vue";
@Component({
components: { ChildComp },
})
export default class About extends Vue {
@Provide("provide_value") private p = "from provide";
}
</script>
/ / child component
<template>
<div>
<h3>I'm a child component</h3>
<h3>Provide /inject Cross-level parameter transmission {{provide_value}}</h3>
</div>
</template>
<script lang="ts">
import { Component, Inject, Vue } from "vue-property-decorator";
@Component
export default class Child extends Vue { @Inject() readonly provide_value! : string; }</script>
Copy the code
How to use TSX
TSX is similar to JSX, which is equivalent to typescript + XML. As an example of an existing project that doesn’t change, we built our environment to support TSX
To create a demo.tsx, type in the following simple content, basically the same as the class component we shared above, except that the template becomes the Render function, which gives us more flexibility.
import { Component, Emit, Prop, PropSync, Vue, Watch } from "vue-property-decorator";
@Component
export default class Demo extends Vue {
public name = "Hs"
public str = "hello tsx"
public data = [1.2.3.4]
// Prop@Prop() demo_name! : string @Prop(Number) demo_age! : number// Propsync
@PropSync("propsync".Number) propsync_copy! : number |undefined
// Computed
get _age() :number {
this.str = this.str + "-x"
return this.demo_age * 10
}
//watch
@Watch("str")
onhangeStr(v: string, o: string) {
console.log(v, o)
}
//emit
@Emit("tsx_emit")
clickEvent() { return "params 123" }
// Render function
render() {
return (
<div>
<h2>Data attribute: {this.name}-{this. STR}</h2>
<h2>prop: {this.demo_name}</h2>
<h2>Evaluate attributes: {this._age}</h2>
<h2>prop-sync: {this.propsync_copy}</h2>
<h2>traverse</h2>
{
this.data.map(c => {
return <span>{c} - </span>})}<button onClick={()= > this.clickEvent()}>emit</button>
</div>)}}Copy the code
Ok, the use of TSX is basically similar to TS, here are simple examples and use ways, easy to understand and learn, more importantly, how to learn TS well, it is really a shooter.
A little encouragement, great growth, welcome to like collection