Vue 與 React 父子元件之間的家長裡短

FinGet發表於2018-06-08

原文部落格地址:https://finget.github.io/2018/06/08/vue-react-props/

Vue

// father.js
<template>
  <div id="father">
      這是父元件:
      <p>父元件</p>
      <Child ref="child" :msg="msg" @click="faClick"></Child>
  </div>
</template>

<script>
import Child from `./child`;
export default {
  data() {
    return {
      msg: `父元件傳給子元件` // 傳遞給子元件的值
    };
  },
  components: {
    Child
  },
  methods: {
    faClick(msg) { // msg 子元件傳遞給父元件的值
      alert(msg);
    },
    childSayHello() { // 父元件呼叫子元件的方法
      this.$refs,child.sayHello();
    }
  }
}
</script>
// child.js
<template>
  <div id="child">
      這是子元件:<p>父元件傳遞的值:{{msg}}</p>
      <button @click="click">接收父元件方法</button>
  </div>
</template>

<script>
export default {
  props: [`msg`],
  data() {
    return {
      childMsg : `哈哈哈`
    };
  },
  methods: {
    click() {
      this.$emit(`click`,this.childMsg); // 第一個引數為派發的事件名, 第二個引數為傳遞的值
    },
    sayHello() {
      alert(`I am child!`);
    }
  }
}
</script>

父元件向子元件傳值:

  1. 在父元件中引入並註冊子元件
  2. 在子元件中定義 props:[`msg`] (不能省略引號)
  3. 通過 :msg="msg" 的方法傳遞變數,也可以通過 msg="msg" 傳遞字串

父元件呼叫子元件的方法:

  1. 在父元件中給子元件繫結一個 ref="xxx" 屬性
  2. 通過 this.$refs.xxx.方法 呼叫

子元件向父元件傳值:

  1. 在子元件中定義一個方法
  2. 通過 this.$emit(`事件名`,`引數`) 派發一個事件,並傳遞引數
  3. 父元件中通過 @事件名 的方式監聽事件
  4. 父元件中定一個一個方法,該方法的引數對應子元件傳遞過來的引數

子元件呼叫父元件的方法:

子元件可以通過this.$parent.xxx 直接呼叫父元件的方法。

通過子元件派發的事件,不僅可以向父元件傳遞引數,父元件也可以通過傳遞的引數,改變向子元件傳遞的值,從而改變子元件。

props 還可以進行一系列的格式校驗,更多內容檢視官網

props: {
    // 基礎的型別檢查 (`null` 匹配任何型別)
    propA: Number,
    // 多個可能的型別
    propB: [String, Number],
    // 必填的字串
    propC: {
      type: String,
      required: true
    },
    // 帶有預設值的數字
    propD: {
      type: Number,
      default: 100
    },
    // 帶有預設值的物件
    propE: {
      type: Object,
      // 物件或陣列且一定會從一個工廠函式返回預設值
      default: function () {
        return { message: `hello` }
      }
    },
    // 自定義驗證函式
    propF: {
      validator: function (value) {
        // 這個值必須匹配下列字串中的一個
        return [`success`, `warning`, `danger`].indexOf(value) !== -1
      }
    }
  }

React

// father.js
import React, { Component } from `react`

import Child from `./child.js`;

class Father extends Component {
  constructor(props) {
    super(props);
    this.state = {
      con: `父元件給子元件`
    }
  }
  // 傳遞給子元件的方法,並接收子元件例項,繫結在this.child上
  onRef = (ref) => {
    this.child = ref
  }
  // 通過this.child 就可以直接呼叫子元件的內部方法
  click = () => {
    this.child.sayHello();
  }
  // 傳遞個子元件的方法
  faClick = (msg) => {
    alert(msg);
  }
  render() {
    return (
      <div>
        <p>這是父元件</p>
        <button onClick={this.click}>呼叫子元件方法</button>
        <div>
          這是子元件
          <Child onRef={this.onRef} connect={this.state.con} click={(msg) => this.faClick(msg)}/>
        </div>
      </div>
    )
  }
}

export default Father;
// child.js
import React, { Component } from `react`

class Child extends Component {
  constructor(props) {
    super(props);
  }
  // 呼叫父元件傳遞的方法,並傳遞子元件例項
  componentDidMount(){
    this.props.onRef(this);
  }
  // 呼叫父元件傳遞的方法
  click= ()=> {
    this.props.click(`哈啊哈`);
  }
  // 子元件內部方法
  sayHello = () => {
    alert(`I am child`);
  }
  render() {
    return (
      <div>
         <p>{this.props.connect}</p>
         <button onClick={this.click}>接收父元件的方法</button>
      </div>
    )
  }
}

export default Child;

父元件向子元件傳值:

  1. 在父元件中引入子元件
  2. 通過 connect={this.state.con} 方式可以傳遞值
  3. 子元件通過 this.props.connect 接收

父元件呼叫子元件的方法:

  1. 給子元件傳遞一個方法 onRef={this.onRef}
  2. 子元件在 componentDidMount 生命週期裡 呼叫這個方法,並回傳自身例項
  3. 父組在該方法中接收子元件例項,並掛載在父元件例項屬性上,例:this.child = ref
  4. 最後就可以通過 this.child.xxx 直接呼叫子元件方法

子元件向父元件傳參:

  1. 在父元件中給子元件傳遞一個方法,click={(msg) => this.faClick(msg)}
  2. 在子元件中通過一個事件接收這個方法,onClick={this.click}
  3. 通過click= ()=> {this.props.click(`哈啊哈`);} 從而傳遞引數

子元件呼叫父元件方法

  1. 父元件可以直接傳遞一個方法給子元件
  2. 子元件可以通過 this.props.xxx 呼叫

不能直接通過 <button onClick={this.props.click(`哈啊哈`)}>接收父元件的方法</button> 進行傳參,這樣在元件初始化時,事件就執行了。

Vue 與 React 的不同:

  1. React 的子元件中不用定義父元件傳值對應的變數
  2. React 的子元件不用派發事件,父元件可以直接傳遞方法
  3. 子元件通過this.props.click 可以呼叫父元件傳遞的方法,並傳參

相關文章