How to encapsulate a more easy-to-use Dialog component
Most people do not understand the knowledge points of this article "how to encapsulate an easy-to-use Dialog component", so the editor summarizes the following contents, detailed contents, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "how to encapsulate a more easy-to-use Dialog component" article.
Scene
In the project, we often encounter the scene of using pop-up windows, but sometimes the pop-up windows included in the component library can not meet our needs and need to be encapsulated by ourselves, so how do we customize a pop-up window that is more convenient to use?
Build an environment
First of all, we need to build a Vue3+ts environment.
Use vite's official template:
Yarn create vite demo-app-template vue-ts
Enter and install dependencies
Cd demo-appyarn
Start app after dependent installation is complete
Yarn dev create component
First create a MyDialog.vue under the src/components directory to build a basic framework for components
Import {ref, reactive} from "vue"; defineProps ({message: {type: String, default: "",}, title: {type: String, default: "",},}); const emits = defineEmits (); const visible = ref (true); function clickConfirm () {console.log ("confirm"); emits ("confirm");} function clickClose () {console.log ("cancel"); emits ("close") {{title}} {{message}} confirm to cancel .wrap {position: absolute; top: 0; left: 0; background: rgba (15,15,15,0.5); width: 100%; height: 100%;} .container {position: absolute; top: 50%; left: 50%; transform: translate (- 50%,-50%) Min-width: 300px; min-height: 200px; padding: 10px; background: white; display: flex; flex-direction: column;}. Content {flex: 1; padding: 10px; text-align: left;}. Title {min-height: 30px;} .controll {display: flex; width: 100%; justify-content: space-around;} create hook functions that call components
Create a hooks directory under the src directory, and then create a useMyDialog.ts. Hooks directory under the useMyDialog.ts directory.
Function call component we need to:
Convert components to VNode
Convert VNode to DOM and render to the page
Import {createVNode, render, ComponentPublicInstance} from "vue"; export default function useMyDialog (option?: any) {const props = {... option,}; const vm = createVNode (MyDialog, props); const container = document.createElement ("div"); render (vm, container); document.querySelector ("# app")? .append (container.firstElementChild!);}
Ps:
Container.firstElementChild! Bingo! Indicates that container.firstElementChild is not null or undefined
Next let's test it in App.vue.
Import useMyDialog from ". / hooks/useMyDialog"; function showDialog () {useMyDialog ({message: "test1", onClose: () = > {console.log ("self");},});} display Dialog
Caching, hiding and hiding of Dialog
We need to return close so that we can manually call the close function to close Dialog. Exe.
Add in useMyDialog.ts
Import {ComponentPublicInstance,VNode} from "vue"; export default function useMyDialog (option?: any) {const userCloseFn = option?.onClose; props.onClose = () = > {close (); userCloseFn? UserCloseFn ();}; function close (vm: VNode) {(vm.implementent.proxy as ComponentPublicInstance). Visible = false;} return {close: close.bind (null, vm),}} cache
Now every time you click the Show Dialog button, a new component instance is created, which is not what we expected, so we need to cache the component.
Add in useMyDialog.ts
Import {ComponentPublicInstance} from 'vue'const instances: any [] = []; export default function useMyDialog (option?: any) {const tempVm: any = instances.find ((item) = > `${item.vm.props?.message?? "}` = `${(option as any). Message??"}`); if (tempVm) {(tempVm.vm.proxy as ComponentPublicInstance). Visible = true Return {close: close.bind (null, tempVm.vm),};}} complete code
Src/hooks/useMyDialog.ts
Import {createVNode, render, ComponentPublicInstance, VNode} from "vue"; import MyDialog from ".. / components/MyDialog.vue"; const instances: any [] = []; export default function useMyDialog (option?: any) {const props = {... option,}; const userCloseFn = option?.onClose; props.onClose = () = > {close (vm); userCloseFn? UserCloseFn ();}; function close (vm: VNode) {(vm.principent.proxy as ComponentPublicInstance). Visible = false;} const tempVm: any = instances.find ((item) = > `${item.vm.props?.message? ""}` = `${(option as any). Message?? "}`); if (tempVm) {(tempVm.vm.proxy. As ComponentPublicInstance). Visible = true Return {close: close.bind (null, tempVm.vm),};} const vm = createVNode (MyDialog, props); const container = document.createElement ("div"); render (vm, container); document.querySelector ("# app")? .appendChild (container.firstElementChild!); instances.push ({vm}); return {close: close.bind (null, vm),} } the above is the content of this article on "how to encapsulate a more easy-to-use Dialog component". I believe you all have some understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.