React18 ,Vue3 之 ref获取dom和组件

821 阅读2分钟

React

一. React获取DOM

1. 在React元素上绑定一个ref字符串(不推荐)

import React, { PureComponent, createRef } from 'react'

export class App extends PureComponent {
  constructor() {
  }

  getNativeDOM() {
    // 1.方式一: 在React元素上绑定一个ref字符串
    // console.log(this.refs.why)
    
    // 2.方式二:createRef(), 将创建出来的对象绑定到元素
   // console.log(this.titleRef.current)
   
   //方式三:传入回调函数
     console.log(this.titleEl)

  }

  render() {
    return (
      <div>
        <h2 ref="why">Hello World</h2>
        <button onClick={e => this.getNativeDOM()}>获取DOM</button>
      </div>
    )
  }
}

export default App

2. createRef()(推荐)

  constructor() {
    this.titleRef = createRef()
  }

<h3 ref={this.titleRef}>hello</h3>

3. 传入一个回调函数(16.3之前的版本)


 constructor() {
    this.titleEl = null
  }

 <h2 ref={el => this.titleEl = el}>你好</h2>

二. React获取组件实例

1. 获取类组件实例

跟上面第二种方式一样,创建createRef

import React, { PureComponent, createRef } from 'react'


class HelloWorld extends PureComponent {
  test() {
    console.log("test------")
  }

  render() {
    return <h1>Hello World</h1>
  }
}

export class App extends PureComponent {
  constructor() {
    super()

    this.hwRef = createRef()
  }

  getComponent() {
    console.log(this.hwRef.current)
    this.hwRef.current.test()
  }

  render() {
    return (
      <div>
        <HelloWorld ref={this.hwRef}/>
        <button onClick={e => this.getComponent()}>获取组件实例</button>
      </div>
    )
  }
}

export default App

2. 获取函数式组件实例

函数式组件是没有实例的,所以无法通过ref获取他们的实例, 需使用React.forwardRef

import React, { PureComponent, createRef, forwardRef } from 'react'


const HelloWorld = forwardRef(function(props, ref) {
  return (
    <div>
      <h1 ref={ref}>Hello World</h1>
      <p>哈哈哈</p>
    </div>
  )
})


export class App extends PureComponent {
  constructor() {
    super()

    this.hwRef = createRef()
  }

  getComponent() {
    console.log(this.hwRef.current)
  }

  render() {
    return (
      <div>
        <HelloWorld ref={this.hwRef}/>
        <button onClick={e => this.getComponent()}>获取组件实例</button>
      </div>
    )
  }
}

export default App

Vue

一.Vue 获取静态DOM

1.设置ref

vue2: 模板中ref="XXX",然后使用this.$refs.XXX

vue3:

1.为节点添加一个 ref 名称(必须和变量名相同)
2.创建 ref 响应式常量并且与 DOM 节点名称一致 ,且值为 null
3.在 onMounted 之后通过 常量的 value 获取到 DOM 节点


<template>
 <div ref="Dom" @click="getDom">hhh</div>
</template>

<script setup>
import { ref, onMounted, computed } from "vue";

const Dom =ref(null);
const getDom = () => {
  console.log(Dom.value);
  Dom.value.style = "color:red;font-size: 100px";
};
onMounted(() => {
  console.log(Dom.value);
});
</script>

<style scoped></style>

二. 获取动态DOM

  1. 为节点添加一个 ref 名称(必须和变量名相同)

  2. 动态的ref必须使用箭头函数的方式

<template>
  <div>
    <ul @click="getDomList">
      <li v-for="(item, i) in list" :key="i" :ref="getDom">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUpdate } from "vue";

//动态获取dom
const list = ref([
  {
    name: "amy",
  },
  {
    name: "nike",
  },
]);
// 创建数组用来存储遍历的DOM元素
let resultList = [];

const getDom = (e) => {
  //获取dom传入resultlist
  console.log(e);

  resultList.push(e);
};

//操作dom
const getDomList = () => {
  console.log(resultList);
  resultList.map((item) => (item.style = "color:red;font-size: 100px"));
};
// 问题:组件更新的时候会重复的设置dom元素给数组:
// 解决方式:ref获取v-for遍历的DOM元素,需要在组件更新的时候重置接受dom元素的数组
onBeforeUpdate(() => {
  resultList = [];
});
</script>