@Component
export default class myFormInVue extends Vue {
// do something here...
}
@Component
export default class myFormInVue extends Vue {
showErrorMessages: boolean = false
//do something when showErrorMessages
@Watch('errorMessages')
onErrorMessage(val) {
if(val.length > 0) {
let vm = this
vm.showErrorMessages = true
vm.onValidate = false
}
}
}
class Point {
private _x: number;
@configurable(false)
get x() { return this._x; }
}
export default class FormData {
@Required
firstName: String
lastName: String
@Required
@Password
password: String
}
@Component
export default class myFormInVue extends Vue {
formData = new FormData()
showErrorMessages: boolean = false
onValidate: boolean = false
@Watch('errorMessages')
onErrorMessage(val) {
if(val.length > 0) {
let vm = this
vm.showErrorMessages = true
vm.onValidate = false
}
}
validateForm() {
let vm = this
vm.errorMessages = Validate(@Required vm.formData)
vm.onValidate = true
}
}
//tsconfig.json
{
"compilerOptions": {
// this aligns with Vue's browser support
"target": "es5",
// this enables stricter inference
// for data properties on `this`
"strict": true,
// if using webpack 2+ or rollup,
// to leverage tree shaking:
"module": "es2015",
"moduleResolution": "node"
}
}
#Install Vue Cli if not already installed
npm install --global @vue/cli
# Create a new project,
# then choose the "Manually select features" option
vue create my-project-name
//Vue Components using Vue.extend
import Vue from 'vue'
const Component = Vue.extend({
// type inference enabled
})
const Component = {
// this will NOT have type inference,
}
//Class Styled Vue Components
@Component
export default class myFormInVue extends Vue {
//data objects are declared as class properties
myBool: boolean = false
//computed Properties are declared as getters
get myComputedProperty {
}
//methods are declared as methods on a class
myMethods(val) {
}
//lifecyclehooks are declared as normal methods
created () {
}
}
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class MyComp extends Vue {
dontKillBary = false
// DO NOT do this
sendMessage = () => {
// Does not update the expected property.
// `this` value is not a Vue instance in fact.
// Barry will be killed
this.dontKillBary = true
}
//to save Barry do this
sendMessage () {
this.dontKillBarry = true
}
}
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class Posts extends Vue {
numberOfTimesToShootBarry = 0
// DO NOT do this
// because of how Vue Components behave, gets executed twice
// Poor Barry is Shot two times
constructor() {
this.numberOfTimesToShootBarry += 1
}
//use lifecycle hooks instead
created() {
//now he will be shot just once
this.numberOfTimesToShootBarry += 1
}
}
//tsconfig.json
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
@Prop @PropSync @Model @Watch @Provide @Inject |
@ProvideReactive @InjectReactive @Emit @Ref @Component (provided by vue-class-component) |
---|
class ToDoItem extends Vue {
@Prop
Todo;
@Prop(String)
name;
@Prop([String, Null])
title;
@Prop({ default: true })
showDetails;
}
@Component
class ToDoItem extends Vue {
@Emit()
addTodo() {
return this.newTodo;
}
}
@Component
class ToDoItem extends Vue {
@Watch('myProp')
onMyPropChanged(val: string, oldVal: string) {
// ...
}
@Watch('myObject', { immediate: true, deep: true })
onMyObjectChanged(val: MyObject, oldVal: MyObject) { }
}
//decorators.ts
import 'reflect-metadata'
const addValidationRule = function(target, propertyKey, rule) {
let rules = Reflect.getMetadata("validation", target, propertyKey) || []
rules.push(rule)
let properties: string[] = Reflect.getMetadata("validation", target) || []
if(properties.indexOf(propertyKey) < 0) {
properties.push(propertyKey)
}
Reflect.defineMetadata("validation", properties, target)
Reflect.defineMetadata("validation", rules, target, propertyKey)
}
//decorators.ts
...
const requiredRule = {
evaluate (target: any, value: any, key: string): string | null {
if(value) {
return null
}
return `${key} is required`
}
}
const Required = function(target, propertyKey) {
addValidationRule(target, propertyKey, requiredRule)
}
//decorators.ts
...
const passwordRule = {
evaluate(target: any, value: any, key: string) {
let passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/
if(passwordRegex.test(value)) {
return null
}
return `${key} is not valid`
}
}
const Password = function(target, propertyKey) {
addValidationRule(target, propertyKey, passwordRule)
}
//decorators.ts
...
const Validate = function(target) {
const keys = Reflect.getMetadata('validation', target) as string[]
let errorMessages: string[] = []
if(Array.isArray(keys)) {
for(const key of keys) {
const rules = Reflect.getMetadata("validation", target, key)
if (!Array.isArray(rules)) {
continue;
}
for(const rule of rules) {
const error = rule.evaluate(target, target[key], key)
if(error) {
errorMessages.push(error)
}
}
}
}
return errorMessages
}
export { Required, Password, Validate }
//formData.ts
import { Required, Password } from '@/decorators/decorators'
export default class FormData {
@Required
firstName: String
lastName: String
@Required
@Password
password: String
}
// Vue Form Component
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
import { Validate } from '@/decorators/decorators'
import FormData from '@/modules/formData'
@Component
export default class myFormInVue extends Vue {
formData = new FormData()
errorMessages: string [] = []
showErrorMessages: boolean = false
@Watch('errorMessages')
onErrorMessage(val) {
if(val.length > 0) {
let vm = this
vm.showErrorMessages = true
}
}
submitForm() {
let vm = this
vm.errorMessages = Validate(vm.formData)
}
}
</script>