vue 十分注重於解藕(解藕的目的就是让各个组件可以单独使用),而在有些情況下父子組件需要相互傳遞data
父傳子 props :
案例假設: 父子組件為一個容器,而子組件遍歷並展示data中的數據。
此時,每次如果展示內容龐大,每次子組件都要向後台請求是效率很低的。
這個情況下通常是由父組件向後台請求,然後再傳遞給子組件
步驟:
- 先在子組件內聲明一個props選項,並為數據命名(此處命名為data,可以任意命名),還有其他數據添加*
export default {
name:'navMenu',
props:{
data:{
tpye:String
}
},
setup(props,{root}){
return {data}
}
- 在父組件中引入子組件(新增一個components選項),父子組件中找到要傳遞的數據
export default {
name: 'layout',
// 2. 在 vue 宣告使用
components: {LayoutNav},
setup(props,{root}){
const data =ref('this is a test')
return{ data }
}
- 在父子組件中放置子組件位置,並綁定數據 :data為子組件綁定的名稱,後面的為父子組件傳送的數據,此處為變量。
<template>
<div id='layout-wrap' ]">
<!--1. 將組件放置版面中--->
<LayoutNav :data="data" />
</div>
</template>
*補充 :
props的值有兩種,1.數組 2.對象
對象裡面支持多種類型 :如下代碼
Vue.component('my-compoent',{
props:{
propA: Number, //基礎匹配類型(null,匹配任何值)
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','waning','danger'].indexof(value) !==-1
}
},
}
})
子傳父 emit
假設案例 : 下圖購物頁面中分為三個組件,當用戶點擊左邊分類選項後,右邊組件展示對應內容。
此時需要將子組件中被點擊的選項,傳給父組件(最外面容器框),然後由父組件向後台請求內容並返回給右邊左鍵展示對應內容。
這個情況下通常是由子組件傳送用戶點擊內容,然後再傳遞給父組件
步驟:
假設子組件有以下數據,在子組件為組件綁定點擊事件,當某個組件被點擊時,就觸發函數。
在函數裡使用emit(此處是vue 3.0版本不需要加this,但要在setup裡新增emit),發送數據
<template>
<div>
<button v-for="(item,index) in categories" :key=index @click="btnclick(item)"> {{item.name}}</button>
</div>
</template>
<script>
export default {
setup(props,{root,emit}){
const categories=reactive([
{id:"aaaa", name:"數碼電器"},
{id:"bbbb", name:"數碼寶貝"},
{id:"cccc", name:"熱門推薦"},
{id:"dddd", name:"綜藝大熱門"},
])
const btnclick=(item)=>{
emit('itemclick',item)
}
return {
categories,
btnclick
}
}
}
- 在父組件中定義一個自訂屬性( itemclick)並用v-on綁定,接著在函數(cpnclcik)裡接收參數
<template>
<div id='layout-wrap' ">
<!--1. 將組件放置版面中--->
<LayoutNav :data="data" @itemclick="cpnclick" />
</div>
</template>
- 聲明一個函數cpnclick來接收參數
!!!注意,這裡在模板調用 @itemclick="cpnclick"的時候,cpnclick默認情況會把唯一的參數自動傳入,所以不需要寫cpnclick(item)
export default {
name: 'layout',
// 2. 在 vue 宣告使用
components: {LayoutNav},
setup(props,{root}){
const cpnclick= (item)=>{
console.log(item.name);
}
return{
cpnclick
}
}
}
以上先到此~~!