回首Vue3之实例篇(二)

1,061 阅读1分钟

这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战

这篇文章我们来讲一下实例 property $options$parent$parent$root$refs$attrs的使用,以及我们需要注意的地方。

如何使用

$options

用于当前组件实例的初始化选项。当你需要在选项中包含自定义 property 时会有用处,当然你可以调用createApp({})大括号中包含的所有属性,如下:

const app = createApp({
  customOption: 'foo',
  data() {
    return {
        name: '也笑'
    }
  },
  created() {
    console.log(this.$options.customOption) // => 'foo'
  }
})
const vm = app.mount("#app")

上述代码中展示了获取自定义属性的用法,那么我们如果想拿个name值应该怎么取呢?通过回首Vue3之实例篇(一)这篇文章,我们知道可以这样拿到name值:vm.namevm.$data.name

为了突出$options的使用,我们也可也这样获取数据:vm.$options.data().name,虽然这种使用方式我们不推荐。

$parent

父实例,如果当前实例有的话。在Vue2中的组件中,我们可以通过this.$parent来获取父组件的实例,在Vue3同样也是可以的,以$options的代码为例:

vm.$parent===null

因为是根实例,所有父实例为null

$root

当前组件树的根组件实例。如果当前实例没有父实例,此实例将会是其自己,如下:

app.component('my-component', {
    setup() {
        const { ctx } = getCurrentInstance()
        onMounted(() => {
            console.log(ctx.$root)
        })
    }
})
const vm = app.mount("#app")

上述代码中,ctx.$root===vm.$root,这是因为组件my-component的父实例是vmvm没有父实例,是它自身的原因。

$slots

用来以编程方式访问通过插槽分发的内容。每个具名插槽都有其相应的 property (例如:v-slot:foo 中的内容将会在 this.$slots.foo() 中被找到),如下:

自定义组件

app.component('my-component', {
    template:`<h1>hello<slot/></h1>`,
    created(){
        console.log(this.$slots.default());
    }
})

调用

<my-component>
    <i>也笑</i>
</my-component>

因为是默认插槽,所以我们在获取插槽内容的时候是:this.$slots.default()。我们既然可以通过这种方式获取插槽内容,那么我们就可以用渲染函数这样来写组件,如下:

app.component('my-component', {
  render() {
    return h('div', [
      h('header', this.$slots.header()),
      h('main', this.$slots.default()),
      h('footer', this.$slots.footer())
    ])
  }
})

$refs

一个对象,持有注册过ref attribute的所有 DOM 元素和组件实例。也就说我们可以通过这个实例属性来获取注册过ref属性的元素,如下:

<div id="app">
    <h1 ref='name'>也笑</h1>
    <h1 ref='englishName'>slifree</h1>
</div>

vm.$refs.name等于<h1>也笑</h1>。值得我们注意的是:在Vue3中, $ref 将不再自动创建数组,也就是说,如果两个两个相同的ref,在获取的时候只会取最后一个,如下:

<div id="app">
    <h1 ref='name'>也笑</h1>
    <h1 ref='name'>slifree</h1>
</div>

vm.$refs.name等于<h1>slifree</h1>

$attrs

官方说,包含了父作用域中不作为组件props自定义事件的 attribute 绑定和事件。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定,并且可以通过 v-bind="$attrs" 传入内部组件——这在创建高阶的组件时会非常有用。

假定我们这样定义一个组件:

app.component('my-component', {
    props:['name'],
    template:`<h1>slifree,{{name}}</h1>`,
    created(){
        console.log(this.$attrs);
    }
})

调用如下:

<my-component id="slifree" name="也笑" class="red" style="color: red;">
</my-component>

上述的console.log则如下:

Proxy {id: "slifree", class: "red", style: {…}, __vInternal: 1}

我们可以通过这个实例属性来获取绑定在组件上的信息。

总结

  1. Vue3中, $ref 将不再自动创建数组,如果ref值重复,则会获取最后一个DOM元素。这一点需要我们注意。

  2. 使用渲染函数来写组件的时候,可以是多种多样的,我们要选取一个合理的或者你熟练的方式去实现它。

想了解更多文章,传送门已开启:回首Vue3目录篇