vue获取组件实例

时间:2021-11-11 01:27:24

vue获取组件实例

选项式获取组件实例

在选项式中可以直接通过this来获取组件实例,通过this来访问实例对象的各种方法

//该组件实例管理的 DOM 根节点。
this.$el
//表示组件当前已解析的 props 对象。
this.$props
//数据
this.$data
//父组件实例
this.$parent
//根组件实例
this.$root
//插槽对象
this.$slots
//一个包含 DOM 元素和组件实例的对象
this.$refs
//其他属性:https://cn.vuejs.org/api/component-instance.html

组合式中获取组件实例

在组合式用,代码都写在setup函数中,无法通过this获取组件实例,需要通过getCurrentInstance()方法,getCurrentInstance()获取的实例对象和选项式获取组件实例不同

<script lang='ts'>
import { defineComponent,getCurrentInstance} from 'vue';
export default defineComponent({
    setup(props, { attrs, slots, emit, expose }) {
        const instance = getCurrentInstance()
    }
})
</script>

和选项式相同的含$的实例对象

在选项式中的实例的属性都含$符号,在组合式中需要通过proxy这个对象来获取选项式中的实例,也就是说选项式中的实例对象在组合式中,属于是组合式实例对象的proxy成员变量

const instance = getCurrentInstance()
const proxy = instance.proxy

//该组件实例管理的 DOM 根节点。
proxy.$el
//表示组件当前已解析的 props 对象。
proxy.$props
//数据
proxy.$data
//父组件实例
proxy.$parent
//根组件实例
proxy.$root
//插槽对象
proxy.$slots
//一个包含 DOM 元素和组件实例的对象
proxy.$refs
//其他属性:https://cn.vuejs.org/api/component-instance.html

//true
console.log(instance.parent.proxy == instance.proxy.$parent);

实例对象的ctx属性问题

在组合式中实例的ctx属性在生产环境中是无法获取的,也就是说,想获取上下文对象,应该在setup函数中获取

错误做法

//开发环境能获取,但在生产中ctx为空
const { ctx } = getCurrentInstance()   //×

正确做法

setup(props,ctx){}

getCurrentInstance被标记为non-public APIs

https://github.com/vuejs/docs/issues/1422,尽管getCurrentInstance是非公开API但是你依旧可以使用它,因为它是内部实例,在你开发vue组件库时依旧可以使用。

在vue的官方文档中找不到getCurrentInstance(),是因为这方法是内部方法

Because the instance is an internal instance that exposes non-public APIs. Anything you use from that instance can technically break between any release types, since they are not subject to semver constraints.

I’m not sure why you need the setup context in nested composables, but explicitly passing arguments to composables make then less coupled to the consuming component, thus easier to understand and test in isolation.

In general a library designed to work with Composition API should expose special variables via its own composables (e.g. useRoute from vue-router) instead of the requiring the user to grab it from the instance.