vue3中?provide?和?inject?用法及原理
前言:
在父子組件傳遞數(shù)據(jù)時,通常使用的是 props 和 emit,父傳子時,使用的是 props,如果是父組件傳孫組件時,就需要先傳給子組件,子組件再傳給孫組件,如果多個子組件或多個孫組件使用時,就需要傳很多次,會很麻煩。
像這種情況,可以使用 provide 和 inject 解決這種問題,不論組件嵌套多深,父組件都可以為所有子組件或?qū)O組件提供數(shù)據(jù),父組件使用 provide 提供數(shù)據(jù),子組件或?qū)O組件 inject 注入數(shù)據(jù)。同時兄弟組件之間傳值更方便。
一、Vue2 的 provide / inject 使用
provide :是一個對象,里面是屬性和值。如:
provide:{
info:"值"
}
如果 provide 需要使用 data 內(nèi)的數(shù)據(jù)時,這樣寫就會報錯。訪問組件實例 property 時,需要將 provide 轉(zhuǎn)換為返回對象的函數(shù)。
provide(){
return{
info: this.msg
}
}
inject :是一個字符串數(shù)組。如:
inject: [ 'info' ]
接收上邊 provide 提供的 info 數(shù)據(jù),也可以是一個對象,該對象包含 from 和 default 屬性,from 是可用做的注入內(nèi)容中搜索用的 key,default 屬性是指定默認值。
在 vue2 中 project / inject 應用:
//父組件
export default{
provide:{
info:"提供數(shù)據(jù)"
}
}
//子組件
export default{
inject:['info'],
mounted(){
console.log("接收數(shù)據(jù):", this.info) // 接收數(shù)據(jù):提供數(shù)據(jù)
}
}
provide / inject 類似于消息的訂閱和發(fā)布。provide 提供或發(fā)送數(shù)據(jù), inject 接收數(shù)據(jù)。
二、Vue3 的 provide / inject 使用
在組合式 API 中使用 provide/inject,兩個只能在 setup 期間調(diào)用,使用之前,必須從 vue 顯示導入 provide/inject 方法。
provide 函數(shù)接收兩個參數(shù):
provide( name,value )
name:定義提供property的name。value:property的值。
使用時:
import { provide } from "vue"
export default {
setup(){
provide('info',"值")
}
}
inject 函數(shù)有兩個參數(shù):
inject(name,default)
name:接收provide提供的屬性名。default:設置默認值,可以不寫,是可選參數(shù)。
使用時:
import { inject } from "vue"
export default {
setup(){
inject('info',"設置默認值")
}
}
完整實例1:provide/inject實例
//父組件代碼
<script>
import { provide } from "vue"
export default {
setup(){
provide('info',"值")
}
}
</script>
//子組件 代碼
<template>
{{info}}
</template>
<script>
import { inject } from "vue"
export default {
setup(){
const info = inject('info')
return{
info
}
}
}
</script>
三、添加響應性
為了給 provide/inject 添加響應性,使用 ref 或 reactive 。
完整實例2:provide/inject 響應式
//父組件代碼
<template>
<div>
info:{{info}}
<InjectCom ></InjectCom>
</div>
</template>
<script>
import InjectCom from "./InjectCom"
import { provide,readonly,ref } from "vue"
export default {
setup(){
let info = ref("今天你學習了嗎?")
setTimeout(()=>{
info.value = "不找借口,立馬學習"
},2000)
provide('info',info)
return{
info
}
},
components:{
InjectCom
}
}
</script>
// InjectCom 子組件代碼
<template>
{{info}}
</template>
<script>
import { inject } from "vue"
export default {
setup(){
const info = inject('info')
setTimeout(()=>{
info.value = "更新"
},2000)
return{
info
}
}
}
</script>
上述示例,在父組件或子組件都會修改 info 的值。
provide / inject 類似于消息的訂閱和發(fā)布,遵循 vue 當中的單項數(shù)據(jù)流,什么意思呢?就是數(shù)據(jù)在哪,修改只能在哪,不能在數(shù)據(jù)傳遞處修改數(shù)據(jù),容易造成狀態(tài)不可預測。
在訂閱組件內(nèi)修改值的時候,可以被正常修改,如果其他組件也使用該值的時候,狀態(tài)容易造成混亂,所以需要在源頭上規(guī)避問題。
readonly 只讀函數(shù),使用之前需要引入,如果給變量加上 readonly 屬性,則該數(shù)據(jù)只能讀取,無法改變,被修改時會發(fā)出警告,但不會改變值。
使用方法:
import { readonly } from "vue"
let info = readonly('只讀info值')
setTimout(()=>{
info="更新info" //兩秒后更新info的值
},2000)
運行兩秒后,瀏覽器發(fā)出警告,提示 info 值不可修改。
所以我們就給provide發(fā)射出去的數(shù)據(jù),添加一個只讀屬性,避免發(fā)射出去的數(shù)據(jù)被修改。
完整實例2的 provide 處添加 readonly 。
provide('info', readonly(info))
在子組件修改值的時候,會有一個只讀提醒。
修改值的時候,還是需要在 provide 發(fā)布數(shù)據(jù)的組件內(nèi)修改數(shù)據(jù),所以會在組件內(nèi)添加修改方法,同時也發(fā)布出去,在子組件處調(diào)用就可以了。
如:
//發(fā)布
let info = ref("今天你學習了嗎?")
const changeInfo = (val)=>{
info.value = val
}
provide('info',readonly(info))
provide('changeInfo',changeInfo)
//訂閱
const chang = inject('changeInfo')
chang('沖向前端工程師')
完整示例3:修改數(shù)據(jù)
// 父組件代碼
<template>
<div>
info:{{info}}
<InjectCom ></InjectCom>
</div>
</template>
<script>
import InjectCom from "./InjectCom"
import { provide,readonly,ref } from "vue"
export default {
setup(){
let info = ref("今天你學習了嗎?")
const changeInfo = (val)=>{
info.value = val
}
provide('info',readonly(info))
provide('changeInfo',changeInfo)
return{
info
}
},
components:{
InjectCom
}
}
</script>
//InjectCom 子組件代碼
<template>
<div>
<button @click="chang('沖向前端工程師')">更新值</button>
</div>
</template>
<script>
import { inject } from "vue"
export default {
setup(){
const info = inject('info')
const chang = inject('changeInfo')
return{
info,
chang
}
}
}
</script>
到此這篇關于vue3中 provide 和 inject 用法及原理的文章就介紹到這了,更多相關 vue3 中provide 和 inject 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue+springboot前后端分離實現(xiàn)單點登錄跨域問題解決方法
這篇文章主要介紹了vue+springboot前后端分離實現(xiàn)單點登錄跨域問題的解決方法,需要的朋友可以參考下2018-01-01
詳解Vue-Cli 異步加載數(shù)據(jù)的一些注意點
本篇文章主要介紹了詳解Vue-Cli 異步加載數(shù)據(jù)的一些注意點,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
Vue+Vant實現(xiàn)7天日歷展示并在切換日期時實時變換功能
本文介紹了如何利用Vue和Vant框架結(jié)合moment.js插件來實現(xiàn)一個7天日歷展示功能,在這個功能中,用戶可以在切換日期時看到界面的實時變化,此外,文章還提供了代碼實現(xiàn)和效果測試的詳細步驟,幫助開發(fā)者能夠順利完成類似的項目開發(fā)2024-10-10

