父组件伸手子组件的方式总结

3,207 阅读3分钟

1. 前言

现在每天写的最多的就是组件了,必不可少地会碰到处理组件之间数据传递的问题。涉及到父子组件通信的话一般分为子组件获取父组件的数据以及方法和父组件获取子组件的数据以及方法。这篇文章就是总结react,vue父组件如何伸手获取子组件的数据以及调用子组件方法的。

2. react

以下的代码都是基于16.8版本。

2.1 类组件

react在hook出来前,只要是需要维护状态的组件都需要用类组件。

子组件

class A extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '吕肥肥'
    }
    this.inputRef = React.createRef();
  }
  render() {
    return (
      <input 
         type="text" 
         value={this.state.name} 
         onChange={(e) => this.setState(e.target.value)} ref={this.inputRef}
      />
    )
  }
}

父组件

class B extends React.Component {
  constructor(props) {
    super(props);
    this.child = React.createRef();
  }
  getChildValue = () => {
    console.log(this.child.current.inputRef.current.name);
  }
  render() {
    return (
      <div>
        <A ref={this.child} />
        <button onClick={this.getChildValue}></button>
      </div>
    )
  }
}

从上面代码可以看出react的类组件主要是通过ref来当做父组件伸手获取子组件的工具。

2.2 函数组件

在函数组件中要获取子组件的数据,需要两步骤

1.将ref传递到子组件中
2.需要使用forwardRef对子组件进行包装

子组件

function A(props, parentRef) {
  return (
    <div>
      <input type="text" ref={parentRef} />
    </div>
  )
}

let ForwardChild = forwardRef(A);

父组件

export default () => {
  const parentRef = useRef();
  function focusHander() {
    console.log(parentRef.current.value);
  }
  return (
    <div>
      <ForwardChild ref={parentRef} />
      <button onClick={focusHander}>获取焦点</button>
    </div>
  )
}

从上面代码可以看出react的函数组件也是通过ref来实现父组件伸手获取子组件数据的,但是呢他有一个明细的缺点,子组件A会向父组件暴露他的所有信息。

2.3 函数组件(优化)

下面就用到hook的一些钩子来做对应的优化

子组件

import React, { useState, useRef, useImperativeHandle, forwardRef } from 'react'

function A(props, parentRef) {
  const inputRef = useRef();
  const [name, setName] = useState('吕肥肥');
  useImperativeHandle(parentRef, () => {
    return {
      name
    }
  })
  return (
    <div>
      <input type="text" ref={inputRef} onChange={setName(e.target.value) } />
    </div>
  )
}

let ForwardChidl = forwardRef(Child);

父组件

export default () => {
  const parentRef = useRef();

  const say = () => {
    console.log(parentRef.current.name);
  }
  return (
    <>
      <ForwardChidl ref={parentRef} />
      <button onClick={say}>打印子组件name</button>
    </>
  )
}

上面了hook里面的useImperativeHandle做了对应的优化,只对外面暴露子组件的一部分。

3. vue

上面介绍了react中父组件如何获取子组件的数据,接下来让我们也来看看vue中父组件父组件是如何获取子组件信息的。

3.1 方法1 从父组件调用子组件方法获取数据

子组件

methods: {
    // 父组件获取数据
    getName () {
      return this.name;
    }
}

父组件

methods: {
    handleName () {
        let name = this.$refs['list'].getName();
        console.log(name);
    }
}

vue大法真香。(这里吐槽一下react用了hook后我们就需要用更多的api去代替之前只需要一个ref)

3.2 方法2 子组件调用父组件方法通过传值,将子组件的值传到父组件

子组件

methods: {
    val () {
      m.$emit('returnValue', true);
    }
}

父组件

<A v-bind:returnValue="getVal"></A>

methods: {
    getVal (result) {
        console.log(result)
    }
}

4. 总结

这篇笔记其实是我自己在写组件库的时候发现react中使用了hook后父组件获取子组件的信息的时候会变得很麻烦,就写了该文章对2大框架这个操作做一个总结记录。

好久没写文章了,以后要让自己动起来。