Talk about using Decorator decorator in Vue project

Preface

Original intention: A few days ago, in other Vue projects of the company, I found out that it was developed with Decorator model. It seemed that the overall code was pretty good, so I made a note and shared it with everyone. If you don’t like it, don’t spray it.

Suitable for the crowd: primary front-end development, big guys detour.

This project is using jsand Decoratordecorator set up, if we use the project ts, then the decorator with the method described herein is different, please reference the tsdecorator. It should be noted that using this mode, variables will be polluted, so variables with the same name cannot appear

What is Decorator

DecoratorDecorator is a kind of class- classrelated grammar, so Decoratordecorator can only be used in classclass, not in ordinary grammar or expression. Personal understanding: The decorator can provide us with a layer of interception, first execute the things in the decorator, and then execute our operations. For details, please see "Decorator" by Teacher Ruan Yifeng

installation

Component

npm install --save vue-class-component
npm install --save vue-property-decorator

Configuration

babel.config.jsConfigure in the root directory of the project as follows

module.exports = {
    
    
  presets: [
    '@vue/app'
  ],
  plugins: [
    ['@babel/plugin-proposal-decorators', {
    
     legacy: true }],
    ['@babel/plugin-proposal-class-properties', {
    
     loose: true }],
  ]
}

jsconfig.jsonConfigure in the root directory of the project as follows

{
    
    
    "compilerOptions": {
    
    
      "experimentalDecorators": true
    }
}

Instructions

Here I will introduce several methods commonly used in Vue. For details, please refer to Vue-property-decorator

Life cycle, methods, data

These writing methods are the same as before, just write directly, see the following case comparison

Original writing

<script>
export default {
    
    
    data() {
    
    
        return {
    
    
            msg: "hello 蛙人"
        }
    },
    created() {
    
    
    
    },
    methods: {
    
    
        test() {
    
    
        
        }
    }
}
</script>

Decorator writing

<script>
import {
    
     Vue } from 'vue-property-decorator'
class App extends Vue {
    
    
    msg = "hello 蛙人"
    created() {
    
    
    
    }
    test() {
    
    
    
    }
}
export default App
</script>

Emit

Original writing

<script>
export default {
    
    
  methods: {
    
    
    send() {
    
    
      this.$emit("custom", 123)
    }
  }
}
</script>

Decorator writing

<script>
import {
    
     Vue, Emit } from 'vue-property-decorator'
class Hello extends Vue {
    
    
  created() {
    
    
    this.send()
  }

  @Emit("custom")
  send() {
    
    
    return 123
  }
}
export default Hello
</script>

Provide

Original writing

<script>
export default {
    
    
  provide() {
    
    
    return {
    
    
      msg: this.msg
    }
  }
}
</script>

Decorator writing

<script>
class App extends Vue {
    
    
  @Provide() msg = this.msg
  msg = "hello 蛙人"
}
export default App
</script>

Inject

Original writing

export default {
    
    
  inject: {
    
    
    msg: {
    
    
      default: () => "",
      required: true
    } 
  }
}
</script>

Decorator writing

import {
    
     Vue, Component,Inject } from 'vue-property-decorator'
@Component
class Hello extends Vue {
    
    
  @Inject({
    
     required: true, default: () => "" }) msg
}
export default Hello

Prop

Original writing

<script>
export default {
    
    
  props: {
    
    
    msg: {
    
    
      type: () => String,
      required: true
    }
  }
}
</script>

Decorator writing

<script>
import {
    
     Vue, Prop } from 'vue-property-decorator'
class Hello extends Vue {
    
    
  @Prop({
    
     required: true, type: String }) msg
}
export default Hello
</script>

PropSync

Original writing

// 父组件
<HelloWorld :msg.sync="msg" v-show="msg"/>

// 子组件
<script>
export default {
    
    
  props: {
    
    
    msg: {
    
    
      require: true
    }
  },
  created() {
    
    
    setTimeout(() => {
    
    
      this.test()
    }, 5000)
  },
  methods: {
    
    
    test() {
    
    
      this.$emit("update:msg", false)
    }
  }
}
</script>

Decorator writing

@PropSyncThe first parameter is, this.$emit("update:msg")inside msg, the statement is followed by variables

<script>
import {
    
     Vue, Component, PropSync } from 'vue-property-decorator'
@Component
class Hello extends Vue {
    
    
  @PropSync("msg", {
    
     required: true }) variable
  created() {
    
    
    setTimeout(() => {
    
    
      this.variable = false
    }, 5000)
  }
}
export default Hello
</script>

Watch

Original writing

export default {
    
    
  data() {
    
    
    return {
    
    
      str: 123  
    }
  },
  created() {
    
    
    setTimeout(() => {
    
    
      this.str = 12
    }, 5000)
  },
  watch: {
    
    
    str: function(newVal, oldVal) {
    
    
      console.log(newVal, oldVal)
    }
  }
}
</script>

Decorator writing

import {
    
     Vue, Component, Watch } from 'vue-property-decorator'
@Component
class Hello extends Vue {
    
    
  str = 123

  created() {
    
    
    setTimeout(() => {
    
    
      this.str = 12
    }, 2000)
  }

  @Watch("str", {
    
    deep: true})
  test(newVal, oldVal) {
    
    
    console.log(newVal, oldVal)
  }
}
export default Hello

Computed

Original writing

<script>
export default {
    
    
  computed: {
    
    
    test: {
    
    
       get() {
    
    
         return this.msg
       },
       set(val) {
    
    
         return this.msg = val
       }
     }
   }
}
</script>

Decorator writing

<script>
import {
    
     Vue, Component } from 'vue-property-decorator'
@Component
class App extends Vue {
    
    
  get test() {
    
    
    return this.msg
  }
  set test(val) {
    
    
    return this.msg = val
  }

}
export default App

Model

Sometimes we want to write a v-modelmethod for the component , as follows

Original writing

// 父组件
<HelloWorld :msg="msg" v-model="msg"/>

// 子组件
<input type="text" @input="test" :value="msg">

<script>
export default {
    
    
  props: {
    
    
    msg: {
    
    
      require: true
    }
  },
  model: {
    
    
    prop: "msg",
    event: "input"
  },
  methods: {
    
    
    test(e) {
    
    
      this.$emit("input", e.target.value)
    }
  }
}
</script>

Decorator writing

// 父组件
<HelloWorld :msg="msg" v-model="msg"/>

// 子组件
<input type="text" @input="test" :value="msg">

<script>
import {
    
     Vue, Component, Model, Emit } from 'vue-property-decorator'
@Component
class Hello extends Vue {
    
    
  @Model("input", {
    
    default: () => ""}) msg
  
  test(e) {
    
    
    this.send(e)
  }
  @Emit("input")
  send(e) {
    
    
    return e.target.value
  }
}
export default Hello
</script>

Ref

Original writing

<HelloWorld :msg="msg" ref="val"/>

<script>
export default {
    
    
  name: 'App',
  components: {
    
    
    HelloWorld
  },
  data() {
    
    
    return {
    
    
      msg: "hello 蛙人"
    }
  },
  mounted() {
    
    
    console.log(this.$refs.val)
  },
}
</script>

Decorator writing

<HelloWorld :msg="msg" ref="val"/>

<script>
import {
    
     Vue, Component, Ref } from 'vue-property-decorator'
@Component({
    
    
  components: {
    
    
    HelloWorld
  }
})
class App extends Vue {
    
    
  @Ref("val") val
  msg = "hello 蛙人"
  
  mounted() {
    
    
    console.log(this.val)
  }
}
export default App
</script>

Component

This method is imported from the component library. If you use the life cycle method, remember to import this decorator, otherwise it will not take effect. The decorator can also write native Vuemethods in an object .

<script>
import {
    
     Vue, Component } from 'vue-property-decorator'
@Component({
    
    
    components: {
    
    
        
    },
    watch: {
    
    
        str: function(val) {
    
    
            console.log(val)
        }
    }
})
export class App extends Vue {
    
    }
</script>

Expand

Of course, you can expand the package Decoratordecorator according to your needs , the decorator receives three parameters

  • target
  • Target key
  • Describe the object

If you don’t understand the description of object properties here, please see my article "In-depth understanding of JavaScript objects"

<script>
function Decorator(data) {
    
    
    return (vue, key, describe) => {
    
    
      // vue 当前执行环境对象
      // key 当前装饰器函数对象 test
      // describe 描述对象里面value是函数
      let fn = describe.value
      describe.value = function () {
    
    
        let status = window.confirm(data)
        if (status) return fn()
      }
    }
}
import {
    
     Vue, Component } from 'vue-property-decorator'
@Component
class App extends Vue {
    
    
  @Decorator("请点击确定")
  test() {
    
     
    window.confirm("你是否完成了")
  }
}
export default App
</script>

In the above example, you can extend your own Decoratordecorator. The decorator is equivalent to a layer of interception. The operation in the decorator is executed first, and the logical operation of our function itself is executed. I will only make one case here, depending on your needs.

thank

Thank you for opening this article during your busy schedule. I hope it will be helpful to you. If you have any questions, you are welcome to correct me.

I’m a frogman, if you think it’s ok, please give me a thumbs up.

Interested friends can join [Front-end entertainment circle exchange group] Welcome everyone to communicate and discuss

Good articles in the past

"Talk about what are CommonJs and Es Module and their difference"

"Map that takes you easily to understand the data structure"

"Do you know all the JavaScript tips used in these jobs?"

"[Recommended Collection] Share some commonly used Git commands in work and how to solve special problem scenarios"

"Deconstruction: Make data access more convenient!

"Do you really understand the features of ES6?

Guess you like

Origin blog.csdn.net/weixin_44165167/article/details/114830173