为什么出现ref

在没有学习Vue之前,我们实现直接操作页面上的DOM元素都是通过JS/jQuery,因为jQueryDOM元素的操作非常的方便。但是学习了Vue之后,对DOM的操作完全交给VM了,这个时候手动的获取DOM元素再使用JS/jQuery就没有那么方便。于是出现了ref,即ref的功能之一就是获取DOM元素的,当然还有其他的功能。

所以ref主要的两个作用如下:

  • 使用ref获取页面DOM元素
  • 使用ref获取子组件对象

使用ref获取DOM元素使用案例

<template>
    <div id="app">
        <input type="text" ref="msgText" v-model="msg" />
        <button @click="getElement">获取元素值</button>
    </div>
</template>
<script>
export default {
    data: () => ({
        msg: 'Hello ref'
    }),
    methods: {
        getElement() {
                console.log(this.$refs.msgText.value)
        }
    },
    mounted() {
        console.log('mounted: ' + this.$refs.msgText.value)
    },
    beforeMount() {
            console.log('beforeMount: ' + this.$refs.msgText.value)
    },
};
</script>

运行代码,从结果中可以看到,在beforeMount 这个钩子函数中,我们是无法获取到这个DOM 元素的值,结合之前学习的 Vue 生命周期的相关知识,当执行到beforeMount 钩子函数时,Vue虽然已经将模板编译完成,但是尚未挂载到页面 DOM 元素上,还只是挂载在虚拟DOM上,因此我们可以得出 ref是在页面渲染完成后才被创建的。

使用 ref获取子组件对象使用案例

在child组件中写入如下代码

<template id="child">
    <div>
        <input type="datetime" name="datetime" v-model="local">
        <button @click="getLocalData">获取当前时间</button>
    </div>
</template>
<script>
export default {
    data() {
        return {
            local: ''
        }
    },
    methods: {
        getLocalData() {
            var date = new Date()
            this.local = date.toLocaleString()
        }
    },
}
</script>

在parent组件中写入如下代码:

<template>
    <div id="app">
        <input type="text" ref="msgText" v-model="msg" />
        <button @click="getElement">获取元素值</button>
        <hr>
        <child ref="childComponent"></child>
    </div>
</template>
<script>
import child from './child'
export default {
    data() {
        return {
            msg: 'Hello ref'
        }
    },
    mounted() {
        console.log('mounted: ' + this.$refs.msgText.value)
    },
    methods: {
        getElement() {
            console.log('input 输入框的值为:' + this.$refs.msgText.value)//Hello ref
            this.$refs.childComponent.getLocalData()//时间
            console.log('子组件 input 输入框的值为:' + this.$refs.childComponent.local)
        }
    },
    components: {
        child
    }
}
</script>

可以看到,当我们将 ref添加到子组件上,我们就可以在 Vue 实例上获取到这个注册的组件引用,同注册的DOM 元素一样,我们都可以使用添加的ref 属性值作为key 获取到注册的对象。此时,我们就可以获取到这个子组件上的 data选项和 methods 选项。

总结

因为Vue 采用 Virtual DOM 的做法渲染网页,如果我们直接操作 DOM,很容易产生实际网页跟 Vue 产生的 Virtual DOM 不同步的问题,而通过使用ref 属性之后,在一些需要获取 DOM 元素的情况下,我们就可以很方便的获取 DOM 元素。当然,当我们决定在项目中使用 Vue,还是需要转变我们的思路,将操作 DOM 转变成操作数据。同样的,通过将ref属性添加到子组件上,我们就可以很轻松的获取到子组件的相关信息,这无疑给父组件获取子组件数据、调用子组件的方法提供了一种新的思路。

Logo

前往低代码交流专区

更多推荐