preface
The application of Design Pattern in VUE (1) The application of design pattern in VUE (2) the application of design pattern in VUE (3) the application of design pattern in VUE (4) The application of design pattern in VUE (5) the application of design pattern in VUE (6) The application of design pattern in VUE (7)
Why write these articles. Just as Design Pattern is a set of repeatedly used, known by most people, classified and summarized code Design experience (from Baidu Encyclopedia), I also want to discuss the charm of Design Pattern with everyone through sharing some accumulated work. The application scenarios introduced in this series of articles as an aid to illustration are real application scenarios in the workplace, of course, but common business scenarios are also covered by analogy
If you are familiar with the vue principle, you know that get/set of data is intercepted via Object.defineProperty, dependency Watcher is collected in get, and update watcher.notify () is triggered in set. This is the observer pattern in action
Add, notify, or trigger. The most obvious difference is that Observer adds a specific Observer object, while Publish/Subscribe adds a subscription event
// class Observer {update() {}} const Observer1 = new Observer() subject.add () subject.notify ()'event1'.function Subscribe() {
...do something 1
})
Publish.add('event1'.function Subscribe() {
...do something 2
})
Publish.add('event1'.function Subscribe() {
...do something 3
})
Publist.trigger('event1')
Copy the code
A,
- Two forms — invoice information and mailing information
- The mailing information form is only required if the VAT special invoice is selected
- The submit button does not take effect until all existing forms (one or two) have been validated, that is, the submit button is clicked to get the validation result of the form and the value of the input field
Second, the analysis
Most of the time we have a scenario where one form corresponds to a submit button. Now we have a scenario where a submit button controls N (greater than 1) and an unmanageable number of forms. We can solve this problem with observer mode
Using the form object (component) as an observer, click the Notify submit button to get the value for all Observers (form)
Three, the design
// invoiceForm.vue
<template>
... do something
</template>
<srcipt>
exportDefault {methods: {// All form components provide a unified interface to get valuesgetValue() {// Return a promise. Most VUE form validation is asynchronousreturnNew Promise(() => {// form validation, return value... do something }) } } } </script>Copy the code
// postForm.vue
<template>
... do something
</template>
<srcipt>
exportDefault {methods: {// Unified interface for obtaining valuesgetValue() {// Return a promisereturnnew Promise(() => { ... do something }) } } } </script>Copy the code
// stage.vue <template> <div> <! <invoice-form ref="invoice" />
<post-form v-if="isNeedPost" ref="post" />
<button @click="handleSubmit"</button> </div> </template> <script>export default {
data () {
isNeedPost: true
}
methods: {
async handleSubmit() {// There are two observers: invoice and postlet invoice = await this.$refs.invoice.getValue()
let post = {}
if (this.$refs.post) {
post = await this.$refs.post.getValue()
}
this.$axios.post({
invoice,
post
})
}
}
}
</script>
Copy the code
4. More complex scenarios
The above scenario is known to haveinvoiceForm
,postForm
In this scenario, contact forms can be added without limit
When ref and V-for are used together, the reference you get will be an array containing the subcomponents of the corresponding data source (from the VUE documentation)
Designed and implemented
<template>
<div>
<div>
<contact-form
v-for="(item, index) in contactGroup"
ref="contacts"
:key="index"
/>
</div>
<button @click="handleAdd"> Add a contact </button> < button@click ="handleSave"</button> </div> </template> <script>export default{
data () {
return {
contactGroup: [true]
}
},
methods: {
handleAdd () {
this.contactGroup.push(true)
},
async handleSave() {// pseudocode try {// this.$refs.contacts is an array const Promises = this.$refs.contacts.map(contact => contact.getValue())
const contacts = await Promise.all(promises)
this.$axios.post({contacts})} catch (error) {// Form validation does not pass console.dir(error)}}}} </script>Copy the code
At the end
The content of this article is relatively simple, and you may have a better solution to the above scenarios, but I personally feel that this requirement scenario is good for understanding the observer pattern.
In order to use the observer mode, we need to get the observed object (component) -- ref 2. In the first part of this series, we produced the input component in factory mode, for passthroughtypeThe status factory component design also needs to accept both props. What if there are more props that need to be passed through and there are events$attrs,$listenersOne of the key features of the design pattern is the ability to dynamically compose and decide which objects (components) to use. Dynamic Component 4, part 4 of this series is the ability to customize a step in an algorithm (component rendering). Of course, the above 4 examples are only based on the content of this series, but not all of them. Some people say that they are not familiar with the vUE document. I have friends around me who read the Vue document from beginning to end. People think should be the code design demand drive you to in-depth knowledge framework, most of the time framework has provided meet your requirements of the API or move straight line (documents), if the framework does not provide a ready-made can hack it through other API (this time may need to source further research), if still can't meet you, Give PR to the framework source code as your technical capabilities allow?Copy the code
This implementation also applies to react. Why vue? The React JSX template can be a bit awkward to understand, while the React JSX template can be seen as writing JavaScript to implement more flexible concepts