在vue-class-component中怎么写watch?
Vue Property Decorator
Install
需要用到vue-property-decorator
这个库
npm i -S vue-property-decorator
Usage
有几个修饰其和1个function(Mixin):
@Prop
@PropSync
@Model
@Watch
@Provide
@Inject
@ProvideReactive
@InjectReactive
@Emit
@Ref
-
@Component
(provided by vue-class-component) -
Mixins
(the helper function namedmixins
provided by vue-class-component)
See also
@Prop(options: (PropOptions | Constructor[] | Constructor) = {})
decorator
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@Prop(Number) readonly propA: number | undefined
@Prop({ default: 'default value' }) readonly propB!: string
@Prop([String, Boolean]) readonly propC: string | boolean | undefined
}
等同于
export default {
props: {
propA: {
type: Number
},
propB: {
default: 'default value'
},
propC: {
type: [String, Boolean]
}
}
}
提醒:
If you'd like to set type
property of each prop value from its type definition, you can use reflect-metadata.
- Set
emitDecoratorMetadata
totrue
. - Import
reflect-metadata
before importingvue-property-decorator
(importingreflect-metadata
is needed just once.)
import 'reflect-metadata'
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class MyComponent extends Vue {
@Prop() age!: number
}
Each prop's default value need to be defined as same as the example code shown in above.
It's not supported to define each default
property like @Prop() prop = 'default value'
.
@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})
decorator
import { Vue, Component, PropSync } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@PropSync('name', { type: String }) syncedName!: string
}
等同于
export default {
props: {
name: {
type: String
}
},
computed: {
syncedName: {
get() {
return this.name
},
set(value) {
this.$emit('update:name', value)
}
}
}
}
Other than that it works just like @Prop
other than it takes the propName as an argument of the decorator, in addition to it creates a computed getter and setter behind the scenes. This way you can interface with the property as it was a regular data property whilst making it as easy as appending the .sync
modifier in the parent component.
@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {})
decorator
import { Vue, Component, Model } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@Model('change', { type: Boolean }) readonly checked!: boolean
}
等同于
export default {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: {
type: Boolean
}
}
}
@Model
property can also set type
property from its type definition via reflect-metadata
.
@Watch(path: string, options: WatchOptions = {})
decorator
import { Vue, Component, Watch } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@Watch('child')
onChildChanged(val: string, oldVal: string) {}
@Watch('person', { immediate: true, deep: true })
onPersonChanged1(val: Person, oldVal: Person) {}
@Watch('person')
onPersonChanged2(val: Person, oldVal: Person) {}
}
等同于
export default {
watch: {
child: [
{
handler: 'onChildChanged',
immediate: false,
deep: false
}
],
person: [
{
handler: 'onPersonChanged1',
immediate: true,
deep: true
},
{
handler: 'onPersonChanged2',
immediate: false,
deep: false
}
]
},
methods: {
onChildChanged(val, oldVal) {},
onPersonChanged1(val, oldVal) {},
onPersonChanged2(val, oldVal) {}
}
}
@Provide(key?: string | symbol)
/ @Inject(options?: { from?: InjectKey, default?: any } | InjectKey)
decorator
import { Component, Inject, Provide, Vue } from 'vue-property-decorator'
const symbol = Symbol('baz')
@Component
export class MyComponent extends Vue {
@Inject() readonly foo!: string
@Inject('bar') readonly bar!: string
@Inject({ from: 'optional', default: 'default' }) readonly optional!: string
@Inject(symbol) readonly baz!: string
@Provide() foo = 'foo'
@Provide('bar') baz = 'bar'
}
等同于
const symbol = Symbol('baz')
export const MyComponent = Vue.extend({
inject: {
foo: 'foo',
bar: 'bar',
optional: { from: 'optional', default: 'default' },
[symbol]: symbol
},
data() {
return {
foo: 'foo',
baz: 'bar'
}
},
provide() {
return {
foo: this.foo,
bar: this.baz
}
}
})
@ProvideReactive(key?: string | symbol)
/ @InjectReactive(options?: { from?: InjectKey, default?: any } | InjectKey)
decorator
These decorators are reactive version of @Provide
and @Inject
. If a provided value is modified by parent component, then the child component can catch this modification.
const key = Symbol()
@Component
class ParentComponent extends Vue {
@ProvideReactive() one = 'value'
@ProvideReactive(key) two = 'value'
}
@Component
class ChildComponent extends Vue {
@InjectReactive() one!: string
@InjectReactive(key) two!: string
}
@Emit(event?: string)
decorator
The functions decorated by @Emit
$emit
their return value followed by their original arguments. If the return value is a promise, it is resolved before being emitted.
If the name of the event is not supplied via the event
argument, the function name is used instead. In that case, the camelCase name will be converted to kebab-case.
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
count = 0
@Emit()
addToCount(n: number) {
this.count += n
}
@Emit('reset')
resetCount() {
this.count = 0
}
@Emit()
returnValue() {
return 10
}
@Emit()
onInputChange(e) {
return e.target.value
}
@Emit()
promise() {
return new Promise(resolve => {
setTimeout(() => {
resolve(20)
}, 0)
})
}
}
等同于
export default {
data() {
return {
count: 0
}
},
methods: {
addToCount(n) {
this.count += n
this.$emit('add-to-count', n)
},
resetCount() {
this.count = 0
this.$emit('reset')
},
returnValue() {
this.$emit('return-value', 10)
},
onInputChange(e) {
this.$emit('on-input-change', e.target.value, e)
},
promise() {
const promise = new Promise(resolve => {
setTimeout(() => {
resolve(20)
}, 0)
})
promise.then(value => {
this.$emit('promise', value)
})
}
}
}
@Ref(refKey?: string)
decorator
import { Vue, Component, Ref } from 'vue-property-decorator'
import AnotherComponent from '@/path/to/another-component.vue'
@Component
export default class YourComponent extends Vue {
@Ref() readonly anotherComponent!: AnotherComponent
@Ref('aButton') readonly button!: HTMLButtonElement
}
等同于
export default {
computed() {
anotherComponent: {
cache: false,
get() {
return this.$refs.anotherComponent as AnotherComponent
}
},
button: {
cache: false,
get() {
return this.$refs.aButton as HTMLButtonElement
}
}
}
}
关注的我的公众号不定期分享前端知识,与您一起进步!
Aco的故事
element-ui的日期选择框底部清空按钮点击不关闭日期选择框的实现办法
all2005赞 1阅读 7k
Vue中的diff算法
款冬赞 27阅读 14.1k评论 7
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault思否赞 20阅读 5k评论 10
vue-property-decorator使用手册
似曾相识赞 17阅读 29.5k评论 7
前端开发工具
寒青赞 14阅读 2.6k
万字长文~vue+express+mysql带你彻底搞懂项目中的权限控制(附所有源码)
水冗水孚赞 11阅读 1.5k
[译]Vue.js + Astro 比 Vue SPA 更好吗?
杭州程序员张张赞 7阅读 4.1k评论 3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。