Vue 中,如何將函數做爲 props 傳遞給組件

做者:Michael Thiessen
譯者:前端小智
來源:medium
點贊再看,養成習慣

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。html

Vue 新手常常問的一個常見問題。能夠將字符串、數組、數字和對象做爲props傳遞。可是你能把一個函數看成一個props來傳遞嗎?前端

雖然能夠將函數做爲props傳遞,但這種方式很差。相反,Vue 有一個專門爲解決這問題而設計的功能,接下來,咱們來看看。vue

向組件傳入函數

獲取一個函數或方法並將其做爲一個prop傳遞給子組件相對比較簡單。實際上,它與傳遞任何其餘變量方式徹底相同:git

<template>
  <ChildComponent :function="myFunction" />
</template>

export default {
  methods: {
    myFunction() {
      // ...
    }
  }
};

正如前面所說,在Vue中永遠都不要作這樣的事情。github

爲何?Vue有更好的東西。面試

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】數組

React vs Vue

若是使用過 React,就會習慣傳遞函數方式。瀏覽器

在React中,咱們能夠將一個函數從父組件傳遞給子組件,以便子組件可以向上與父組件通訊。props 和 data 向下流動,函數調用向上流動。微信

然而,Vue有一種不一樣的機制來實現子到父通訊方式,Vue 使用事件。ide

這與 DOM 的工做方式相同-與React相比,Vue 的方式與瀏覽器的一致性更高。 元素能夠發出事件,而且能夠監聽這些事件。

所以,儘管在Vue中能夠把函數做爲prop傳遞,但它被認爲是一種反模式。

使用事件

事件是咱們與 Vue 中的父組件通訊的方式。

這裏有一個簡短的例子來講明事件是如何工做的。

首先,咱們將建立子組件,該子組件在建立時會發出一個事件:

// ChildComponent
export default {
  created() {
    this.$emit('created');
  }
}

在父組件中,咱們監聽該事件:

<template>
  <ChildComponent @created="handleCreate" />
</template>

export default {
  methods: {
    handleCreate() {
      console.log('Child has been created.');
    }
  }
};

事件能夠作的事情還有不少,而這僅僅是皮毛。強烈建議查看官方的Vue文檔來了解更多關信息,絕對值得一讀。

可是事件並不能徹底解決咱們全部的問題。

從子組件訪問父組件的做用域裏數據

在許多狀況下,咱們試圖解決的問題是訪問來自不一樣做用域的數據。

父組件有一個做用域,子組件有另外一個做用域。

一般,咱們但願從父組件訪問子組件中的值,或者從子組件訪問父組件中的值。Vue阻止咱們直接這樣作,這是一件好事。

它使咱們的組件更加具備封裝性,並提升了它們的可重用性。這使咱們的代碼更簡潔,並從長遠來看避免了許多使人頭痛的問題。

可是有時候咱們可能會試圖經過函數來繞過這個問題。

從父類獲取值

若是但願子組件訪問父組件的方法,那麼將方法直接做爲 prop 傳遞彷佛簡單明瞭。

在父組件中咱們會這樣作:

<!-- Parent -->
<template>
  <ChildComponent :method="parentMethod" />
</template>

// Parent
export default {
  methods: {
    parentMethod() {
      // ...
    }
  }
}

在咱們的子組件中,使用傳入的方法:

// Child
export default {
  props: {
    method: { type: Function },
  },
  mounted() {
    // Use the parent function directly here
    this.method();
  }
}

這樣作會有什麼問題?

這並非徹底錯誤的,可是在這種狀況下使用事件會更好。

而後,當須要時,子組件不會調用該函數,而只是發出一個事件。而後父組件將接收該事件,調用該函數,拼裝將更新傳遞給子組件的 prop。

這是達到一樣效果的更好的方法。

在其餘狀況下,咱們可能想要從子元素中獲取一個值到父元素中,咱們爲此使用了函數。

例如,你可能正在這樣作。父函數接受子函數的值並對其進行處理:

<!-- Parent -->
<template>
  <ChildComponent :method="parentMethod" />
</template>


// Parent
export default {
  methods: {
    parentMethod(valueFromChild) {
      // Do something with the value
      console.log('From the child:', valueFromChild);
    }
  }
}

在子組件中調用傳入的方法並將子組件的值做爲方法的參數傳入:

// Child
export default {
  props: {
    method: { type: Function },
  },
  data() {
    return { value: 'I am the child.' };
  },
  mounted() {
    // Pass a value to the parent through the function
    this.method(this.value);
  }
}

這也不是徹底錯誤的,這樣作是可行的。

只是這不是在Vue中的最佳方式。相反,事件更適合解決這個問題。咱們可使用事件來實現徹底相同的事情

<!-- Parent -->
<template>
  <ChildComponent @send-message="handleSendMessage" />
</template>

// Parent
export default {
  methods: {
    handleSendMessage(event, value) {
      // Our event handler gets the event, as well as any
      // arguments the child passes to the event
      console.log('From the child:', value);
    }
  }
}

在子組件中,咱們發出事件:

// Child
export default {
  props: {
    method: { type: Function },
  },
  data() {
    return { value: 'I am the child.' };
  },
  mounted() {
    // Instead of calling the method we emit an event
    this.$emit('send-message', this.value);
  }
}

事件在Vue中很是有用,但它們也不能100%地解決咱們的問題。有時,咱們須要以不一樣的方式從父級訪問子級的做用域。

爲此,咱們使用做用域插槽!

使用做用域插槽

做用域插槽是一個更高級的主題,可是它們也很是有用。事實上,我認爲它們是Vue提供的最強大的功能之一。

它們弱化了子做用域和父做用域之間的界限。可是它以一種很是乾淨的方式完成,使得咱們的組件像之前同樣可組合。

若是你想了解更多關於做用域插槽是如何工做的,能夠先看看官方文檔,或者咱們下回講解。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

來源:https://stackoverflow.com/que...


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索