我是靠谱客的博主 机智悟空,最近开发中收集的这篇文章主要介绍vue装饰器-像react一样使用class的方式来写vue代码data、methods、computed、watch、生命周期钩子混入mixin私有组件注册componentspropEmit@Provide/@Inject 、@Ref 装饰器写法@ProvideReactive/ @InjectReactive,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

data、methods、computed、watch、生命周期钩子

原写法

<template>
  <div class="helloworld">
    <h1>{{ msg }}</h1>
    <h2 v-text="msg"></h2>
    <h3>{{length}}</h3>
    <div>
      <p>{{ count }}</p>
      <button @click="add">+1</button>
    </div>
  </div>
</template>

<script lang="ts">
export default {
  data () {
    return {
      msg: 'helloworld',
      count: 1
    }
  },
  methods: {
    add () {
      this.count++
    }
  },
  computed: {
    length () {
      return this.msg.length
    }
  },
  watch: {
    count (newVal, oldVal) {
      console.log(newVal, oldVal)
      if (newVal >= 5) {
        this.count = 5
      }
    }
  },
  created () {
    alert('传统vue开发')
  }
}
</script>

<style lang="less" scoped>

</style>

装饰器写法

<template>
  <div class="helloworld">
    <h1>{{ msg }}</h1>
    <h2 v-text="msg"></h2>
    <h3>{{length}}</h3>
    <div>
      <p>{{ count }}</p>
      <button @click="add">+1</button>
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
@Component()
export default class HelloWorld extends Vue {
  @Watch('count')
  handleCount (newVal, oldVal) {
    console.log(newVal, oldVal)
    if (newVal >= 5) {
      this.count = 5
    }
  }

  msg = 'helloworld'
  count = 1
  add () {
    this.count++
  }

  get length () {
    return this.msg.length
  }

  created () {
    alert('使用装饰器进行vue开发')
  }
}
</script>

<style lang="less" scoped>

</style>

混入mixin

原写法

<template>
  <div class="helloworld">
    <h1>{{ msg }}</h1>
    <h2 v-text="msg"></h2>
    <h3>{{length}}</h3>
    <div>
      <p>{{ count }}</p>
      <button @click="add">+1</button>
    </div>
  </div>
</template>

<script lang="ts">
const mixin = {
  data () {
    return {
      msg: 'helloworld',
      count: 1
    }
  },
  methods: {
    add () {
      this.count++
    }
  },
  computed: {
    length () {
      return this.msg.length
    }
  },
  watch: {
    count (newVal, oldVal) {
      console.log(newVal, oldVal)
      if (newVal >= 5) {
        this.count = 5
      }
    }
  },
  created () {
    alert('传统vue开发')
  }
}
export default {
  mixins: [mixin]
}
</script>

<style lang="less" scoped>

</style>

装饰器写法

<template>
  <div class="helloworld">
    <h1>{{ msg }}</h1>
    <h2 v-text="msg"></h2>
    <h3>{{length}}</h3>
    <div>
      <p>{{ count }}</p>
      <button @click="add">+1</button>
    </div>
  </div>
</template>

<script lang="ts">
import Component, { mixins } from 'vue-class-component'
// import { Component, Vue, Watch } from 'vue-property-decorator'
const mixin = {
  data () {
    return {
      msg: 'helloworld',
      count: 1
    }
  },
  methods: {
    add () {
      this.count++
    }
  },
  computed: {
    length () {
      return this.msg.length
    }
  },
  watch: {
    count (newVal, oldVal) {
      console.log(newVal, oldVal)
      if (newVal >= 5) {
        this.count = 5
      }
    }
  },
  created () {
    alert('传统vue开发')
  }
}
@Component
export default class HelloWorld extends mixins(mixin) {
  created () {
    console.log(this.msg) // helloworld
  }
}
</script>

<style lang="less" scoped>

</style>

私有组件注册components

原写法

import {componentA,componentB} from '@/components'
export default {
	components: {componentA,componentB}
}

装饰器写法

vue-class-component写法

import Component from 'vue-class-component'
import {componentA,componentB} from '@/components'
@Component({
  components: {componentA,componentB},
  props: {},
  watch: {
    new (newVal, oldVal) {}
  }
})

vue-property-decorator扩展的装饰器写法

import {Component,Vue} from 'vue-property-decorator'
import {componentA,componentB} from '@/components'
 
 @Component({
    components:{
        componentA,
        componentB,
    },
    directives: {
        focus: {
            // 指令的定义
            inserted: function (el) {
                el.focus()
            }
        }
    }
})
export default class HelloWorld extends Vue{}

prop

原写法

export default{
    props:{
        propA:String, // propA:Number
        propB:[String,Number],
        propC:{
            type:Array,
            default:()=>{
                return ['a','b']
            },
            required: true,
            validator:(value) => {
                return [
                    'a',
                    'b'
                 ].indexOf(value) !== -1
        }
    }
  }
}

装饰器写法

import {Component,Vue,Prop} from vue-property-decorator;
 
@Component
export default class YourComponent extends Vue {
    @Prop(String)
    propA:string;
    
    @Prop([String,Number])
    propB:string|number;
    
    @Prop({
     type: String, // type: [String , Number]
     default: 'default value', // 一般为String或Number
      //如果是对象或数组的话。默认值从一个工厂函数中返回
      // defatult: () => {
      //     return ['a','b']
      // }
     required: true,
     validator: (value) => {
        return [
          'InProcess',
          'Settled'
        ].indexOf(value) !== -1
     }
    })
    propC:string 
}

Emit

原写法

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)
      })
    }
  }
}

装饰器写法

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)
    })
  }
}

@Provide/@Inject 、@Ref 装饰器写法

父组件(helloworld/index.vue)

<template>
  <div class="helloworld">
    <h1 ref="h1" :title="count">{{count}}</h1>
    <h2 ref="h2">h2</h2>
    <a-button type="primary" @click="addOne">primary</a-button>
    <a-button type="dashed" @click="addOne">dashed</a-button>
    <a-button type="danger" @click="addOne">danger</a-button>
  </div>
</template>

<script lang="ts">
// import Component, { mixins } from 'vue-class-component'
import { Component, Vue, Provide, Ref } from 'vue-property-decorator'
import Button from '@/components/Button/index.vue'
@Component({
  components: {
    'a-button': Button
  }
})
export default class HelloWorld extends Vue {
  // Provide提供给子组件的数据并非响应式的
  @Provide() msg = 'hlloworld'
  @Provide('abc') obj = { id: 0, name: 'xxx' }
  @Ref('h1') readonly h1!: HTMLHeadingElement
  count = 1
  addOne () {
    this.count++
    this.$nextTick(() => {
      console.log('+++++++', this.h1.getAttribute('title'))
    })
  }

  created () {
    // console.log(this.h1)
  }
}
</script>

<style lang="less" scoped>

</style>

子组件(components/Button/index.vue)

<template>
  <div class="button">
    <button class="a-button" :class="hover" @click="handleButton" @mouseenter="handleEnter" @mouseleave="handleLeave" :style="handleType(type)">
      <slot></slot>
    </button>
  </div>
</template>

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

interface Style {
  border?: string;
  backgroundColor?: string;
  color?: string;
}
@Component()
export default class Button extends Vue {
  @Inject() readonly msg!: string
  @Inject({ from: 'abc', default: {} }) readonly obj!: { id: number; name: string }
  @Prop({ type: String, default: 'default' }) readonly type!: string
  @Emit('click')
  handleButton () {
    console.log('触发了点击事件')
  }

  hover = ''

  handleType (type: string) {
    let style: Style
    switch (type) {
      case 'dashed':
        style = { border: '1px dashed burlywood', color: 'rgba(0,0,0,.65)' }
        break
      case 'primary':
        style = { backgroundColor: '#1890FF', color: 'white' }
        break
      case 'danger':
        style = { backgroundColor: '#FF4D4F', color: 'white' }
        break
      default:
        style = { border: '1px solid #eee', color: 'rgba(0,0,0,.65)' }
        break
    }
    return style
  }

  handleEnter () {
    this.hover = this.type
  }

  handleLeave () {
    this.hover = ''
  }

  created () {
    console.log(this.msg, this.obj)
  }
}

</script>

<style scoped lang="less">
.button {
  display: inline-block;
  margin: 0 10px;
}
.a-button {
  margin: 0;
  border: 1px solid transparent;  //自定义边框
  outline: none;
  height: 32px;
  border-radius: 5px;
  padding: 0px 15px;
  &:hover {
    cursor: pointer;
    text-decoration: none;
  }
}
.primary {
  background-color: #40a9ff !important;
}
.danger {
  background-color: #ff7875 !important;
}
.defaule {
  border: 1px #1890FF solid !important;
  color: #1890FF !important;
}
.dashed {
  border: 1px #1890FF dashed !important;
  color: #1890FF !important;
}

</style>

@ProvideReactive/ @InjectReactive

这两个装饰器的功能与@Provide/ @Inject类似,但是它注入的属性是响应式的,父级注入的属性一旦修改,子组件可以获取到变化

// 父组件
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
}

最后

以上就是机智悟空为你收集整理的vue装饰器-像react一样使用class的方式来写vue代码data、methods、computed、watch、生命周期钩子混入mixin私有组件注册componentspropEmit@Provide/@Inject 、@Ref 装饰器写法@ProvideReactive/ @InjectReactive的全部内容,希望文章能够帮你解决vue装饰器-像react一样使用class的方式来写vue代码data、methods、computed、watch、生命周期钩子混入mixin私有组件注册componentspropEmit@Provide/@Inject 、@Ref 装饰器写法@ProvideReactive/ @InjectReactive所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部