1、环境安装
npm install vue-class-component vue-property-decorator -S
npm install -g typescript
2、组件使用
- Vue中有三大组件:类组件 + 扩展式组件 + 函数式组件
- 扩展式组件中使用 TypeScript 语法时,方法与 Vue + JavaScript 开发时相似,而类组件中使用 TypeScript 语法与 Vue + JavaScript 开发时则相差较大。而函数式组件,只能接受父级传递的数据进行渲染。
3、Vue项目中使用三种组件
App.vue
<template>
<div>
<ClassComponent proid="pro1"/>
<ExtendComponent proid="pro1" />
<FunctionComponent a = "1" b="你好"/>
</div>
</template>
<script lang="ts">
import { Vue, 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 {
}
</script>
(1)扩展式组件
<template>
<div>
<h2>扩展式组件</h2>
<p>{{ msg }}</p>
<p>{{ reverseMsg }}</p>
<button @click="test">测试组件的点击事件</button>
<div>
<input type="text" v-model="name" v-focus>
</div>
<p>{{ proid }}</p>
<div ref="box">ref</div>
{{ sex | sexFilter }}
</div>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
props: {
proid: {
type: String,
required: true,
default: 'hahahah'
}
},
data () {
return {
sex: 0,
msg: 'hello world',
name: '',
obj: { id: 1, name: '李没睡', child: { name: '222' } }
}
},
computed: {
reverseMsg (): string {
return this.msg.split('').reverse().join('')
},
newObj<T> (): T {
return JSON.parse(JSON.stringify(this.obj))
}
},
methods: {
test () {
console.log('11111')
this.obj.child.name = '3333'
}
},
watch: {
name (newVal: string, oldVal: string) {
console.log(newVal, oldVal)
},
'obj.name' (newVal: string, oldVal: string) {
console.log(newVal, oldVal)
},
newObj: {
deep: true,
immediate: true,
handler (newVal, oldVal) {
console.log(newVal, oldVal)
}
}
},
mounted () {
(this.$refs.box as HTMLDivElement).style.background = '#f66'
},
filters: {
sexFilter (val: number) {
return val === 1 ? '男' : '女'
}
},
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
})
</script>
(2)类组件
<template>
<div>
<h2>类组件</h2>
<p>{{ msg }}</p>
<p>{{ reverseMsg }}</p>
<button @click="test(555)">测试组件的点击事件</button>
<div>
<input type="text" v-model="name" v-focus>
</div>
<p> {{ proid }} -- {{ title }}</p>
<div ref='bbox'>bbox</div>
{{ sex | sexFilter('person') }}
</div>
</template>
<script lang="ts">
import { Vue, Component, Watch, Prop, Ref } from 'vue-property-decorator'
@Component({
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
},
filters: {
sexFilter (val: number, type: string) {
if (type === 'person') {
return val === 1 ? '男' : '女'
} else {
return val === 1 ? '公' : '母'
}
}
}
})
export default class extends Vue {
@Ref('bbox')
bboxing!: HTMLDivElement
mounted () {
}
@Prop({ required: true })
readonly proid: string | undefined
@Prop({ default: '默认标题' })
readonly title?: string | undefined
msg = 'hello vue'
name = ''
obj = { id: 1, name: '李没睡', child: { name: '222' } }
sex = 0
test (str: string) {
console.log('2222' + str)
this.obj.child.name = '3333'
}
get reverseMsg () {
return this.msg.split('').reverse().join('-')
}
get newObj () {
return JSON.parse(JSON.stringify(this.obj))
}
@Watch('name')
onNameChange<T> (newVal: T, oldVal: T) {
console.log(newVal, oldVal)
}
@Watch('newObj', { deep: true, immediate: true })
onObjChange<T> (newVal: T, oldVal: T) {
console.log(newVal, oldVal)
}
}
</script>
(3)函数式组件(一般只进行展示)
<template functional>
<div>
<h2>函数式组件</h2>
{{ props.a }} --- {{ props.b}}
</div>
</template>
4、总结
- 使用 TypeScript 开发前需要懂得装饰器的语法。
- 开发时我们可以使用扩展式组件或者类组件,但是一般使用的是类组件。
- 后续我们会讲解如何在 Vue + TypeScript 开发环境下进行状态管理以及数据请求等,这样我们就能基本完成项目的实际开发。