前言
最近再写弹框组件时 通过调用函数的方式调用弹框 需要获取到组件实例 在此总结一下
Vue2
获取当前组件实例
1 render()
1 |
|
2 | function create(Component, props) { |
3 | const vm = new Vue({ |
4 | render: (h) => h(Component, { props }), |
5 | }).$mount(); |
6 |
|
7 | |
8 | |
9 | document.body.appendChild(vm.$el); |
10 |
|
11 | |
12 | const comp = vm.$children[0]; |
13 |
|
14 | |
15 | comp.remove = () => { |
16 | document.body.removeChild(vm.$el); |
17 | vm.$destroy(); |
18 | }; |
19 | return comp; |
20 | } |
2 Vue.extend()
1 |
|
2 | function create(Component, props) { |
3 | |
4 | const Constructor = Vue.extend(Component); |
5 | const component = new Constructor({ |
6 | propsData: props, |
7 | }).$mount(); |
8 | |
9 | document.body.appendChild(component.$el); |
10 | component.remove = () => { |
11 | document.body.removeChild(component.$el); |
12 | component.$destroy(); |
13 | }; |
14 | return component; |
15 | } |
获取父组件实例
获取子组件实例
Vue3
获取当前组件实例
createApp 获取组件实例
1 | import { createApp, h } from "vue"; |
2 | const div = document.createElement("div"); |
3 | const app = createApp({ |
4 | render() { |
5 | return h(Component, { |
6 | title: "提示", |
7 | content: "内容", |
8 | onXxx: () => { |
9 | console.log("xxx"); |
10 | }, |
11 | }); |
12 | }, |
13 | }).mount(div); |
14 | document.body.appendChild(div); |
如果是title 和 content 是插槽
1 | import { createApp, h } from "vue"; |
2 | const div = document.createElement("div"); |
3 | const app = createApp({ |
4 | render() { |
5 | return h( |
6 | MessageBox, |
7 | { |
8 | onXxx: () => { |
9 | console.log("xxx"); |
10 | }, |
11 | }, |
12 | { |
13 | |
14 | title, |
15 | content, |
16 | } |
17 | ); |
18 | }, |
19 | }).mount(div); |
20 | document.body.appendChild(div); |
获取父组件实例
1 | import { getCurrentInstance } from 'vue' |
2 | const instance = getCurrentInstance() |
3 | const parent = instance.parent |
获取子组件实例
Vue3 中实例没有$children 属性了 那么子组件实例如何获取呢?
1 ref
以 form 组件为例 点击登录需要获取 loginForm 的 validate 方法
1 |
|
2 | <template> |
3 | <x-form :model="userInfo" :rules="rules" ref="loginForm"> |
4 | <x-form-item label="用户名" prop="username"> |
5 | <x-input |
6 | v-model="userInfo.username" |
7 | placeholder="请输入用户名" |
8 | clear |
9 | ></x-input> |
10 | </x-form-item> |
11 | <x-form-item> |
12 | <x-button @click="login" type="primary">登录</x-button> |
13 | </x-form-item> |
14 | </x-form> |
15 | </template> |
16 | <script lang=ts setup> |
17 | const loginForm = ref(null) |
18 | const login = () => { |
19 | loginForm.value.validate(valid => { |
20 | if(valid){ |
21 | openMessageBox({title: '提示',content: '登录成功'}) |
22 | } |
23 | } |
24 | </script> |
但是需要在loginForm 中暴露validate方法
1 |
|
2 | const validate = (callback) => { |
3 | ... |
4 | }; |
5 | defineExpose({validate}) |
2 slots.default()
如果子组件是通过插槽的方式传递进来的 可以通过slots.default() 方法获取
1 | setup(props,{slots}){ |
2 | const children = slots.default() |
3 | } |
1 |
|
2 | import { useSlots } from "vue"; |
3 | const slots = useSlots(); |
4 | const children = slots.default(); |
可以通过这种方式约束子组件标签
1 |
|
2 | import ChildCompont form './ChildChomponent' |
3 | children.forEach( tag => { |
4 | if(tag.type !== ChildCompont){ |
5 | throw new Error('子组件必须是 ChildComponent') |
6 | } |
7 | }) |
这种方法可以获取到子组件实例 但是不能调用子组件中的方法