vue的refs和ref

vue的refs和ref

获取dom元素

  • 通过refs获取dom元素一般在mounted生命周期函数执行时获取
    • 在mounted函数执行之前是无法获取到dom元素的,因为此时dom还没有挂载到页面中
    • 当ref绑定在v-for里面时,此时通过refs获取到的是一个数组
#普通绑定
<div id="app">
    <p ref="p1">普通绑定</p>
</div>

<script>
new Vue({
    el:"#app",
    created(){
        console.log(this.$refs.p1) #undefined
    },
    mounted(){
        console.log(this.$refs.p1) #p1的dom元素
    }
})
</script>

#在v-for中绑定
<div id="app">
    <ul>
        <li v-for="i in 5" ref="li">{{i}}</li>
    </ul>
</div>

<script>
new Vue({
    el:"#app",
    mounted(){
        console.log(this.$refs.li) #获取到的是一个含有5个li元素的数组
    }
})
</script>

refs获取dom元素异常

  • 当从后台获取数据,然后通过v-if或v-for动态渲染页面元素时,如果在mounted函数中直接通过refs获取dom元素,得到的结果是undefined
    • vue在更新dom元素时是采用异步的方式,只要检测到数据的变化,就开启的一个异步队列,然后把这个异步队列放到事件循环的末尾,等待执行
    • 也就是vue在数据更新后不是直接重新渲染页面元素,而是等待下一次事件循环开始才进行重新渲染的
    • 当在created或则mounted发起请求获取数据时,data和methods中的数据已经初始化完成,也就是此时获取数据之后修改data中的数据,代表着数据更新
  • 解决方式1:添加nextTick函数
    • 调用nextTick函数:this.$nextTick()
    • nextTick函数返回的是一个promise对象
    • nextTick函数作用:在数据更新之后,它会等待重新渲染页面元素完成,才会执行它的回调函数
<body>
    <div id="app">
        <ul>
            <li v-for="i in arr" :key="i.id" ref="li">
                <span>{{i.name}}</span>
            </li>
        </ul>
    </div>
    <script src="./data.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                arr: [],
                bool: false
            },
            methods: {
                // 获取数据
                async getData() {
                    data().then(async data => {
                        this.arr = data

                        await this.$nextTick()

                        console.log(this.$refs.li) #获取到的是一个含有5个li元素的数组
                    })
                },
            },
            created() {
                this.getData()
            },
        })
    </script>
</body>
  • 解决方式2:在mounted函数中调用修改数据函数时,添加async,await修饰符
    • 只适合修改函数返回一个promise对象的情况
    • 原理:在async函数中,只要遇到await修饰的代码段,程序都会停止下来,等待代码段执行完成之后,才会继续向下执行,此时分为两部分"修改数据,更新dom元素都属于await修饰的代码段",await修饰的代码段执行完成,就代表着dom元素已经更新完成
<body>
    <div id="app">
        <ul>
            <li v-for="i in arr" :key="i.id" ref="li">
                <span>{{i.name}}</span>
            </li>
        </ul>
    </div>
    <script src="./data.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                arr: [],
                bool: false
            },
            methods: {
                // 获取数据
                async getData() {
                    let arr = await data().catch(err => err)
                    this.arr = arr
                },
            },
            async mounted(){
                await this.getData()
                console.log(this.$refs.li) #获取到的是一个含有5个li元素的数组
            }
        })
    </script>
</body>
  • 解决方式3:由于无论在任何一个地方调用methods中的函数修改data中的数据都会重新渲染页面中的元素,也就是代表着updated()生命周期函数都会执行
    • updated生命周期函数执行时,页面中的元素都已经重新渲染完成,所以可以获取dom元素
<body>
    <div id="app">
        <ul>
            <li v-for="i in arr" :key="i.id" ref="li">
                <span>{{i.name}}</span>
            </li>
        </ul>
    </div>
    <script src="./data.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                arr: [],
                bool: false
            },
            methods: {
                // 获取数据
                async getData() {
                    let arr = await data().catch(err => err)
                    this.arr = arr
                },
            },
            mounted(){
                this.getData()
            },
        	updated(){
                console.log(this.$refs.li) #获取到的是一个含有5个li元素的数组
            }
        })
    </script>
</body>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值