安装:
npm i @vue/cli -g
vue create 目录 | .
// typescript
// use class-style component yes↓
npm run serve
配置:
tsconfig.json 配置ts编译环境
xx.d.ts 支持vue,jsx ts写法
定义组件: src/components
1.类式
2.扩展式
3.函数式**
类组件中
<template>
<div>
<h3>类组件</h3>
<h4>data数据</h4>
<div>{{msg1}}</div>
<div>{{msg2}}</div>
<!-- <div>{{msg3}}</div> -->
<div>{{msg4}}</div>
<div>{{msg5}}</div>
<h4>计算属性</h4>
<div>{{cptMsg1}}</div>
<h4>事件</h4>
<button @click="show(12,'bmw')">事件</button>
<h4>props</h4>
<div>{{this.p1}}</div>
<h4>ref</h4>
<div ref="box">box</div>
<h4>指令</h4>
<div v-direc1>direc1</div>
<div v-direc1="'qq'">direc1</div>
<h4>过滤器</h4>
<div>{{ 'bmw3' | filt1}}</div>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { Component, Prop, Watch, Ref } from "vue-property-decorator";
import { Person } from "../types";
@Component({
directives: {//局部指令
direc1: (el: HTMLElement, binding) => console.log("direct1", binding.value)
},
filters: {//局部过滤器
filt1(data: string, arg: number = 2): string {
return "自行车" + arg;
}
}
})
export default class ClassComponent extends Vue {
//props定义 需要依赖装饰器
@Prop()
readonly p1!: string; // ! 操作符(Bang Operator)显式地告诉编译器它的值不为空
@Prop({ default: "pp2默认值" })
readonly pp2: string | undefined; //默认值
@Prop({ default: 110, type: Number })
readonly pp3: number | undefined; //类型约定
// @Prop() private readonly pp4:string="qq"//×
//元数据 ~~ data -》 类内的实例属性
msg1: string = "武汉加油";
msg2: string = "武汉加油" + this.p1;
// msg3:undefined = undefined; //undefined 非响应式
msg4: any = null; //页面不渲染,响应式
msg5: Person = { id: 1, name: "alex" };
//实例方法 ~~methods
show(arg1: number, arg2: string): void {
alert("类组件的实例方式" + arg1 + arg2);
}
//计算属性
get cptMsg1(): string {
return "经过计算后的" + this.msg1;
}
//钩子函数
mounted(): void {
console.log("class-component mounted", this.msg5.name);
this.bbox.style.background = "red";
}
//属性检测
@Watch("msg1")
onMsg1Change(newValue: string, oldValue: string): void {
console.log("msg1数据变化了", newValue, oldValue);
}
@Watch("msg5", { deep: true, immediate: true })
onMsg5Change(newValue: string, oldValue: string): void {
console.log("msg1数据变化了", newValue, oldValue);
}
//ref 引用元素
@Ref("box")
bbox!: HTMLDivElement;
//指令、过滤器
//全局 ~~ vuejs
}
</script>
扩展组件:
<template>
<div>
<h3>扩展组件</h3>
<h4>data数据</h4>
<div>{{msg}}</div>
<button @click="show(12,'bmw')">事件</button>
<h4>计算属性</h4>
<div>{{cptMsg}}</div>
<h4>ref</h4>
<div ref="box">box</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
data(){
return {
msg:'q7'
}
},
props:{
pp1:{
type:String,
default:'默认值',
required:false,
// validator:(val:string)=>val.length>2
}
},
computed:{
cptMsg():string{
return '计算后的'+this.msg;
}
},
methods:{
show(arg1:number,arg2:string):void{
alert('扩展式组件的实例方法'+arg1+arg2)
}
},
mounted():void{
console.log('extend component mounted')
// this.box.style.background='red';
},
watch:{
msg(newValue: string, oldValue: string){
console.log('exnrtend component msg变化')
}
}
})
</script>
函数式组件
<template functional>
<div>
<h3>函数式组件</h3>
<h4>props</h4>
<div>{{props.bb1}}</div>
<h4>事件</h4>
<button @click="parent.show(121)">按钮</button>
</div>
</template>
App.vue:
<template>
<div id="app">
<h3>vue + ts</h3>
<ClassComponent p1="111" pp2="222"/>
<ExtendComponent p1="111"/>
<FunctionComponent bb1="333"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import {Component} from 'vue-property-decorator';
import ClassComponent from './components/ClassComponent.vue'
import ExtendComponent from './components/ExtendComponent.vue'
import FunctionComponent from './components/FunctionComponent.vue'
@Component({
components:{
ClassComponent,ExtendComponent,FunctionComponent
}
})
export default class App extends Vue{
show(arg:number):void{
alert('app show '+ arg)
}
}
</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>