目录
Vue3三种实例
1. Application Instance
应用实例
// main.js
import { createApp } from 'vue'
const app = createApp(App);
app.use(router).use(store); // 支持链式调用
app.mount('#app')
console.log(app, '===app instance===')
● createApp 创建一个Application Instance
● 应用实例用来注册应用的全局内容
2. Component Instance
组件实例
// main.js
const app = createApp(App);
const vm = app.mount('#app') // 返回的组件实例
console.log(vm, '===component instance===')
● 组件实例里有组件返回的属性和方法 、内置属性、全局数据(比如use后的antd)
3. Internal Component Instance
组件内部实例
import { getCurrentInstance } from 'vue'
...
setup(){
const internal = getCurrentInstance()
console.log(internal, '===internal instance===')
console.log('internal中的proxy,可以拿到组件实例的内容')
}
● internal中的proxy,可以拿到组件实例的内容
● internal中的appContext和全局应用实例的是_context是完成一致,appContext可以全局共享的状态属性,可以使用全局注册的内容在组件内进行操作和处理
Vue3组件通信的四种方法
1. 父组件访问子组件实例
<template>
<customizComponents ref="customizComponents">
</template>
...
import { ref } from 'vue'
...
setup(){
const customizComponents = ref()
const test = () => {
console.log(customizComponents.value) // 访问子组件的属性和方法
}
}
2. 子组件访问父组件实例(不推荐)
import { onMounted,getCurrentInstance } from 'vue'
...
setup(){
onMounted(() => {
const internal = getCurrentInstance()
console.log(internal.proxy?.$parent) // 可以访问父组件的属性和方法
})
}
● 不推荐,应该保持单向数据流,子组件应该发送特定的事件去触发父组件的改变
● $parent可以嵌套调用访问,直到null
3. 父组件跨级传递
自上而下跨层级传递数据(provide、inject)
import { provide, inject } from 'vue'
// parent
setup(){
provide("key", "test value")
}
// child component
setup(){
const parentMessageData = inject("key")
console.log(parentMessageData,'==parentMessageData')
}
● 响应式对象也是可以被provide,这样父子双方的数据是可以同步的
4. 事件监听器完成父子组件的通信
● 父组件有slot,子组件是以slot形式存在的,没法添加ref, 想拿到子组件的属性和方法(如:表单中form表单嵌套input等)
● vue2中 $on,$off等事件监听器,被废除,需使用第三方库, 官方推荐mitt这个库作为事件监听器(库大小小于200字节)
// parent.vue
<template>
<div><slot></slot></div>
</template>
setup() {
emitter.on('test-value', (e) => {
console.log(e)
})
onUnmounted(() => {
emitter.off('form-item-created', callback)
funcArr = []
})
}
// child.vue
<template>
<div></div>
</template>
setup() {
emitter.emit('test-value', '11111')
}
// use parent component
<template>
<parent>
<child />
</parent>
</template>