回首Vue3之实例篇(一)

1,557 阅读1分钟

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

这篇文章我们来讲一下实例 property $data$props$el的使用,以及我们需要注意的地方。

如何使用

$data

该函数返回组件实例的 data 对象。实例创建之后,可以通过 vm.$data 访问原始数据对象。组件实例也代理了 data 对象上所有的 property,因此访问 vm.a 等价于访问 vm.$data.a。举个例子:

const { createApp, ref } = Vue
const app = createApp({
    data() {
        return {
            name: '也笑'
        }
    },
    setup() {
        const englishName = ref('slifree')
        return {
            englishName
        }
    },
})
const vm = app.mount("#app")

上述示例中,vm.name===vm.$data.name值为:也笑,所以说vm.$data可以访问组件实例的 data 对象的原始数据。但是同为响应式数据的englishName却访问不到,vm.$data.englishName===undefined,vm.englishName==='slifree',因为这个数据是setup函数中创建的,没有在 data 对象上。

值得我们注意的是:一旦被侦听后,你就无法在根数据对象上添加响应式 property。因此推荐在创建实例之前,就声明所有的根级响应式 property。

$props

在说$props之前,我们先了解一下props:一个用于从父组件接收数据的数组或对象。它可以是基于数组的简单语法,也可以是基于对象的支持诸如类型检测、自定义验证和设置默认值等高阶配置的语法。props有四个参数,使用如下:

简单使用

//数组形式,直接使用
props: ['name']

//对象形式,简单使用
props:{
    name: String,// 类型检查
}

高阶使用

props: {
     name: {
      type: String, // 类型检查
      default: '也笑', //默认值
      required: true, //'Boolean' 定义该 prop 是否是必填项
      validator: value => { //'Function' 自定义验证函数会将该 prop 的值作为唯一的参数代入
        return value.length >= 1
      }
    }

通过上述内容,我们对props有一定的了解。接下来,我们来说一下$props,类比$data我们可以知道它是:当前组件接收到的 props 对象。组件实例代理了对其 props 对象 property 的访问,使用如下:

app.component('my-component',{
    props:['name'],
    render(){
        console.log(this.$props)
        return h('h1',{},[
            h('div',{},`Hi,${this.name}!`),
            h('div',{},`Hello,${this.$props.name}!`)
        ])
    }
})

渲染结果如下:

Hi,也笑!
Hello,也笑!

根据上述内容,我们可以看出vm.name 等价于访问 vm.$props.name

$el

组件实例正在使用的根 DOM 元素。对于使用了片段的组件,$el 是占位 DOM 节点,Vue 使用它来跟踪组件在 DOM 中的位置,使用如下:

自定义组件

app.component('my-component', {
    props: ['name'],
    setup() {
        const { ctx } = getCurrentInstance()
        onMounted(() => {
            console.log(ctx.$el)
        })
    },
    render() {
        return h('h1', {}, [
            h('div', {}, `Hi,${this.name}!`),
            h('div', {}, `Hello,${this.$props.name}!`)
        ])
    }
})

自定义组件中ctx.$el的结果为:

<h1><div>Hi,也笑!</div><div>Hello,也笑!</div></h1>

这里我们结合getCurrentInstance来跟踪组件在 DOM 中的位置,可以快速的获取到组件DOM,但是我们不推荐这样使用,而是建议模板引用(即vm.$refs)来直接访问 DOM 元素。

总结

  1. 并不是所有响应式数据都能通过vm.$data获取到,只有data对象上的才可以。

  2. props要根据需求给定对应的参数,在setup中我们会以参数的形式把它传进去,而不用vm.$props去访问。

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