The fastest way is to use an excellent component library, such as elder-UI el-Dialog. It is also very convenient to use. There are probably several ways to do this:
Method one: Put dialog and Content-body together
child.vue
<el-dialog
title="Tip"
:visible.sync="visible"
width="30%"
:before-close="handleClose">
<span>This is a piece of information</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">Take away</el-button>
<el-button type="primary" @click="dialogVisible = false">determine</el-button>
</span>
</el-dialog>
Copy the code
parent.vue
<child
:visible="visible"
:otherData="otherData"/>
Copy the code
At the same time, you need to write Visible to the current page and clear the data when closed. (PS: because of the prop passed in from the outer layer, it cannot be modified internally. If it needs to be modified, it should emit to the parent level for synchronous update)
<child
+ :visible.sync="visible"
:otherData="otherData"/>
close() {
this.$emit('update:visible'.false);
}
Copy the code
Method 2: Place the outer dialog in parent and import the abstract Content-Body content as a component
child.vue
<span>This is a paragraph</span>
Copy the code
parent.vue
<el-dialog
title="Tip"
:visible.sync="visible"
width="30%"
:before-close="handleClose">
<child />
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">Take away</el-button>
<el-button type="primary" @click="dialogVisible = false">determine</el-button>
</span>
</el-dialog>
Copy the code
The parent component needs to define the visible property and clear the data when closed
child.vue
resetFields() {
// Clear the child data
Object.assign(this.$data,this.$options.data())
}
Copy the code
parent.vue
handleClose() {
this.visible = false;
this.$refs['child'].resetFields();
}
Copy the code
Method 3: Combine Vuex state management, so that you do not need to passattrs
orprops
Incoming communication, global maintenance of a state
child.js
const viewmodel = {
state: {
visible: false
},
mutations: {
setVisible(state, payload){ state.visible = payload; }}}Copy the code
<el-dialog
title="Tip"
:visible.sync="visible"
width="30%"
:before-close="handleClose">
<child />
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">Take away</el-button>
<el-button type="primary" @click="dialogVisible = false">determine</el-button>
</span></el-dialog> ... mapState('child'['visible'])
...mapMutation('child'['setVisible'])
Copy the code
Some of the ideas above make people feel more redundant, can be used, but not recommended. If a page has multiple pop-ups, it doesn’t feel elegant, so some wrapping is needed.
First of all, a dialog component needs visible to control show/hide, title to control the popbox title, Content to represent the content area, and close to represent the outer call to close the popbox.
props: {
title: {
type: String.default: ' '
},
component: {
type: Function.default: () = >{}},close: {
type: Function.default: () = >{}}}methods: {
closeDialog() {
// Clear the popbox data
Object.assign(this.$data, this.$options.data());
// Call the close method in props to empty the data
this.close();
// Destroy the component and remove the Watcher listener
this.$refs.component.$destroy(); }}Copy the code
We define a customDialog component that internally defines the data property Visible.
- We use extend to generate a new sub method, point sub to the parent prototype chain, merge the incoming properties into options under sub, inherit the parent prototype method, and merge the sub
super
Point to the parent object. - The method is then new, essentially generating a new vUE instance through a series of init operations.
- The vUE instance is then applied
$mount
Operation, the essence is to carry out virtual DOM patch operation, return EL object - Finally, append the EL object to the body and complete the rendering of the popbox component
const DialogConstructor = Vue.extend(CustomDialog);
inst = new DialogConstructor();
inst.visible = true;
inst.$mount();
document.body.appendChild(inst.$el);
Copy the code
Question 1: How can I change the properties of the inner frame from the outer layer
By passing in the propsData property
+ const createDialog = propsData= > {
const DialogConstructor = Vue.extend(CustomDialog);
inst = new DialogConstructor({
+ propsData
});
inst.visible = true;
inst.$mount();
document.body.appendChild(inst.$el); +}Copy the code
This allows us to construct different popboxes by createDialog({title: XXX})
Fault 2: A pop-up frame that has been opened needs to be constructed again when opened again
The opened subrack instances are saved to a map and obtained by setting a unique UID value
const createDialog = () = >{+const instance = {};
return propsData= > {
const uid = propsData.id || propsData.title;
let inst = instance[uid];
if (inst) {
+ inst.visible = true;
} else{... + instance[uid] = inst; } +returninst; }}Copy the code
In addition, if the current instance propsData has been updated, the instance needs to be updated
const createDialog = () = > {
return propsData= > {
const instance = {};
if(inst) {
inst.visible = true;
+ const originPropsData = mapValues(
+ inst.$options.props,
+ value= > value.default
+ );
+ Object.assign(inst.$props, originPropsData, propsData); }}}Copy the code
Question 3: How do I close the pop-up correctly in the opening sequence
Open instance objects can be stored on a stack. Every time I open it, I’m actually pushing the instance onto the stack; Every time you close it, you’re actually pushing the instance off the stack. Set a $closeDialog method attached to the Vue prototype chain. The main task is to get the current instance, call the close method of the current instance, and push the current instance off the stack.
const createDialog = () = > {
const instance = {};
+ const openedDialogQueue = [];
return propsData= > {
const uid = propsData.id || propsData.title;
let inst = instance[uid];
+ Vue.prototype.$closeDialog = () = >{+constcurrentInst = openedDialogQueue.pop(); + currentInst && currentInst.closeDialog(); +};if (inst) {
inst.visible = true;
// NOTE:Update props
const originPropsData = mapValues(
inst.$options.props,
value= > value.default
);
Object.assign(inst.$props, originPropsData, propsData);
// NOTE:It mainly deals with the sequence of opening and closing multiple bullet frames
+ openedDialogQueue.push(inst);
} else {
const DialogConstructor = Vue.extend(CustomDialog);
inst = new DialogConstructor({
propsData
});
inst.visible = true;
inst.$mount();
document.body.appendChild(inst.$el);
openedDialogQueue.push(inst);
instance[uid] = inst;
}
return inst;
};
}
Copy the code
Such a simple box to achieve, after each use only need to write a short few lines of code can be done
this.$dialog({
id: 'key'.title: 'play box'.component: () = > <div>Hello, world!</div>,})Copy the code
conclusion
Above is oneself study net big guy after sum up some experience, improved development efficiency to a certain extent. Life and work need to summarize, write this article, on the one hand to record their own thoughts, on the other hand to share with you to study together, if there is anything wrong, hope to get your correction, thank you very much!
custom-dialog