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 js
and Decorator
decorator set up, if we use the project ts
, then the decorator with the method described herein is different, please reference the ts
decorator. It should be noted that using this mode, variables will be polluted, so variables with the same name cannot appear
What is Decorator
Decorator
Decorator is a kind of class- class
related grammar, so Decorator
decorator can only be used in class
class, 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.js
Configure 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.json
Configure 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
@PropSync
The 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-model
method 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 Vue
methods 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 Decorator
decorator 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 Decorator
decorator. 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?" 》