[Vue] Vue's $ref property is an empty object or undefined problem and solution (covering uniapp/H5/WeChat applet)

Table of contents

Problem: Getting this.$refs is an empty object or undefined

Reason 1: In uniapp, non-H5 terminals can only be used to obtain custom components, and cannot be used to obtain built-in component instances (such as: view, text)

Solution: ref uses a custom component on the non-H5 side

Reason 2: The debugging base library with too low version is used

Reason 3: The ref component uses conditional rendering, namely v-if, v-show. These DOM nodes cannot be accessed when mounted. For details, please refer to In-depth Responsive Principles-Vue.js

Reason 4: The v-for loop is used to dynamically bind ref (most of the time, the backend data is requested to render DOM dynamically), this.$ref[name] gets an array, see ref attribute-Vue.js for details

Extended scenario: uni-app's H5/applet implementation anchor point


Problem: Getting this.$refs is an empty object or undefined

console.log(this.$refs) // {}

Reason 1: In uniapp, non-H5 terminals can only be used to obtain custom components, and cannot be used to obtain built-in component instances (such as: view, text)

<view ref="viewRef"></view>
<text ref="viewRef"></text>
// js
console.log(this.$refs) // n内置组件获取不到ref{}

Solution: ref uses a custom component on the non-H5 side

<jz-loading ref="loading"></jz-loading>
//js
console.log(this.$refs['loading']) // 输出实例

Reason 2: The debugging base library with too low version is used

Solution: switch to a higher version of the basic library

Reason 3: The ref component uses conditional rendering, namely v-if, v-show. These DOM nodes cannot be accessed when mounted. For details, please see In-depth

Solution: Use this.$nextTick(() => {}) method to get ref after rendering

mounted() {
    // 操作数据.
    .......
    this.$nextTick(()=>{
        console.log(this.$refs[name]) // 输出实例
    })
}

Reason 4: The v-for loop is used to dynamically bind ref (most of the time, the backend data is requested to render DOM dynamically), this.$ref[name] gets an array, see ref attribute-Vue.js for details

 Solution:

由this.$refs[name]改为this.$refs[name][0]

Extended scenario: uni-app's H5/applet implementation anchor point

Implementation method (H5 side): H5 implementation method is relatively simple, get the offsetTop property of $el of the ref component instance

methods:{
    handleScrollTo(name){
        //H5
        uni.pageScrollTo({
            scrollTop: this.$refs[name][0].$el.offsetTop,
            duration: 100
        });
    }
}

Implementation method (small program side): using this.$refs[name][0].$el.offsetTop on the small program side will find that the $el property cannot be found

The reason is that $el only supports the H5 side 

For small programs, we can use node query, use uni.createSelectorQuery() and uni.createSelectorQuery().selectViewport().scrollOffset() to query node information

 

Attached is the implementation idea, get the relative coordinate top of the anchor component, and then get the scrolling distance scrollTop of the current screen 

scrollTop - Math.abs(top) will get the distance required to scroll to the anchor point

const query = uni.createSelectorQuery().in(this)
query.select(`#${id}`).boundingClientRect(data => {
    console.log(data) // 返回节点的相对坐标信息top、bottom等
    //查询当前屏幕的滚动位置等信息
    uni.createSelectorQuery().selectViewport().scrollOffset(res => {
        uni.pageScrollTo({
            scrollTop: res.scrollTop - Math.abs(data.top),
             duration: 100
        });
    }).exec();
}).exec();
     

If the article helps everyone, you can like, comment and collect~

Guess you like

Origin blog.csdn.net/haidong55/article/details/125751435