使用 Vue + TypeScript 時項目中常用的裝飾器


備註: 代碼中 el-* 的標籤是 ElementUI 的組件。

一、@Component 裝飾器

@Component 裝飾器是用以聲明子組件。

1)父組件

	<template>
  		<div>
    		<h1>@Component - 聲明(引入)組件</h1>
    		<ComponentSub></ComponentSub>
  		</div>
	</template>

	<script lang="ts">
	import { Component, Vue } from 'vue-property-decorator';
	import ComponentSub from '@/components/decorator/other_decorator/ComponentSub.vue';
	
	@Component({ components: { ComponentSub } })
	export default class Home extends Vue { }
	</script>

2)子組件

	<template>
	  <p>這是子組件</p>
	</template>
	
	<script lang="ts">
	import { Component, Vue } from 'vue-property-decorator';
	
	@Component
	export default class ComponentSub extends Vue { }
	</script>

二、 @Emit 裝飾器

@Emit 裝飾器是用以子組件觸發父組件的自定義事件。

1)父組件

	<template>
	  <div>
	    <h1>@Emit - 子組件觸發父組件的自定義事件</h1>
		<EmitSub @bind-no-arg="welcomeNoArg" @welcome="sayHi"></EmitSub>
	  </div>
	</template>
	
	<script lang="ts">
	import { Component, Vue } from 'vue-property-decorator';
	import EmitSub from '@/components/decorator/property_decorator/EmitSub.vue';
	
	@Component({ components: { EmitSub } })
	export default class Prop extends Vue {
	  private welcomeNoArg(): void {
	    console.log(111);
	  }
	
	  private sayHi(arg: string[]): void {
	    console.log(arg);
	    alert(arg[0]);
	  }
	}
	</script>

2)子組件

<template>
  <div>
    <el-row>
      <el-button @click="bindNoArg">無返回值</el-button>
      <el-button @click="bindHaveArg">無返回值</el-button>
    </el-row>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Emit } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  @Emit() private bindNoArg(): void {
    console.log('bindNoArg');
  }

  @Emit('welcome') private bindHaveArg(): string[] {
    console.log('bindHaveArg');
    return ['Yes', 'No', 'Maybe'];
  }
}
</script>

三、 @Model 裝飾器

@Model 裝飾器是用以組件上實現雙向綁定。

1)父組件

	<template>
	  <div>
	    <h1>@Model - 組件上實現雙向綁定</h1>
		<el-button type="primary" @click="onAlterFoo">父組件改變foo</el-button>
	    <ModelSub v-model="foo"></ModelSub>
	  </div>
	</template>
	
	<script lang="ts">
	import { Vue, Component, Model } from 'vue-property-decorator';
	import ModelSub from '@/components/decorator/property_decorator/ModelSub.vue';
	
	@Component({ components: { ModelSub } })
	export default class ModelComponent extends Vue {
	  private foo: boolean = true;
	
	  private onAlterFoo() {
	    this.foo = !this.foo;
	  }
	}
	</script>

2)子組件

	<template>
	  <div>
	    <input type="checkbox" v-bind:checked="checked" 
	    	v-on:change="$emit('balabala', $event.target.checked)"
	    >
	  </div>
	</template>
	
	<script lang="ts">
	import { Vue, Component, Model, Prop } from 'vue-property-decorator';
	
	@Component
	export default class ModelComponent extends Vue {
	  @Model('balabala', { type: Boolean }) private checked!: boolean;
	}
	</script>

四、 @Prop 裝飾器

@Prop 裝飾器是用以接收來自父組件的數據。

1)父組件

	<template>
	  <div>
	    <h1>@Prop - 接收來自父組件的數據</h1>
	    <PropSub msg="中野三玖"></PropSub>
	  </div>
	</template>
	
	<script lang="ts">
	import { Component, Vue, Emit, Inject } from 'vue-property-decorator';
	import PropSub from '@/components/decorator/property_decorator/PropSub.vue';
	
	@Component({ components: { PropSub } })
	export default class Prop extends Vue { }
	</script>

2)子組件

<template>
  <div>
    這是子組件收到的值:{{ msg }}
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string; // ! 表示確定msg有值
}
</script>

五、 @Provide 裝飾器 和 @Inject 裝飾器

@Provide 裝飾器是用以注入數據,@Inject 裝飾器是用以獲取注入的數據。

1)父組件 @Provide

	<template>
	  <div>
	    <h1>@Provide/@Inject - 接收來自父組件的數據</h1>
	    父組件通過依賴注入賦予的值是:{{ foo }}
	    <ProvideInject></ProvideInject>
	  </div>
	</template>
	
	<script lang="ts">
	import { Component, Vue, Provide } from 'vue-property-decorator';
	import ProvideInject from '@/components/decorator/property_decorator/ProvideInject.vue';
	
	@Component({ components: { ProvideInject } })
	export default class Home extends Vue {
	  @Provide('bar') private foo = '111';
	}
	</script>

2)子組件 @Inject

<template>
  <div>
    子組件通過依賴注入接收的值是:{{ bar }}
  </div>
</template>

<script lang="ts">
import { Component, Vue, Inject } from 'vue-property-decorator';

@Component
export default class ProvideInject extends Vue {
  @Inject() private readonly bar!: string;
}
</script>

六、 @Watch 裝飾器

@Watch 裝飾器是用以監控數據是否改變。

	<template>
	  <div>
	    <h1>@Watch - 監控數據是否改變</h1>
	    <el-input v-model="child" placeholder="請輸入內容"></el-input>
	    <p>當前值:{{ val }} 原來值:{{ oldVal }}</p>
	  </div>
	</template>
	
	<script lang="ts">
	import { Component, Vue, Inject, Watch } from 'vue-property-decorator';
	
	@Component
	export default class ProvideInject extends Vue {
	  private child: number | null = null;
	  private val: number | null = null;
	  private oldVal: number | null = null;
	
	  @Watch('child')
	  private onChildChanged(val: number, oldVal: number): void {
	    this.val = val;
	    this.oldVal = oldVal;
	  }
	}
	</script>

參考文檔 :
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章