搭建項目:本項目使用vue-cli腳手架工具直接搭建
項目結構:
父子組件間傳值目錄結構
1. 父傳子
在父組件調用自組件時,給子組件綁定自定義屬性,在子組件中使用props接收,子組件內部直接當成屬性使用
父組件調用子組件:
<Son title="hello world" value="test" :city="selectCity"/>
子組件接收:
props: ['title', 'value', "city"],
app.vue
<template>
<div id="app">
<h1>hello world</h1>
<Father/>
</div>
</template>
<script>
import Father from './components/Father'
export default {
components: {
Father
}
}
</script>
<style>
</style>
father.vue
<template>
<div class="father">
<h1>父組件</h1>
<!-- 點擊相對應的button子組件中會有相對應的數據變化 -->
<nav>
<button v-for="(item, index) in cityList" :key="index"
@click="selectAction(item)">
{{item}}
</button>
</nav>
<!-- 父組件調用子組件,如果自定義屬性是變量時,則需要 :綁定屬性 -->
<Son title="hello world" value="test" :city="selectCity"/>
</div>
</template>
<script>
import Son from './Son'
export default {
components: {
Son
},
data(){
return {
cityList: ['深圳', '廣州', '上海'],
selectCity: ''
}
},
methods: {
selectAction(city){
console.log(city);
this.selectCity = city;
}
}
}
</script>
<style scoped>
.father{
border: 5px solid #ddd;
padding: 50px;
}
</style>
son.vue
<template>
<div class="son">
<h1>子組件</h1>
<p>{{title}}</p>
<p>{{value}}</p>
<!-- 根據父組件中傳過來的City值的變化,以下的數據而變化 -->
<p>推薦你去玩:</p>
<ul>
<li v-for="(item, index) in map[city]" :key="index">
{{item}}
</li>
</ul>
</div>
</template>
<script>
export default {
// 子組件中使用props接收父組件傳過來的值, props也是組件的屬性,但是實例沒有配置項,屬于外部屬性
props: ['title', 'value', "city"],
// 內部屬性
data(){
return {
map: {
'上海': ['東方明珠', '外灘', '迪斯尼'],
'深圳': ['世界之窗', '歡樂谷', '千鋒'],
'廣州': ['長隆', '廣州塔', '千鋒']
}
}
}
}
</script>
<style scoped>
.son{
border: 5px solid #999;
padding: 50px;
}
</style>
2.子傳父(兩種方式)
- 在父組件調用子組件時,給子組件綁定自定義屬性, 這個自定義屬性是一個函數。
在子組件內部使用props接收。當需要傳值給父組件時,就調用這個屬性,通過調用函數傳值給父組件。 - 在父組件調用子組件時,給子組件綁定自定義事件,事件的實現在父組件中,是一個函數。
當子組件需要傳值給父組件時,就使用this.$emit()觸發該事件,并傳參進去,那么父組件的函數就可以接收到參數了。
第一種方式:
父組件調用子組件:
<Son :onSend="handleSendAction"/>
函數實現
//函數的實現,也就是傳入子組件中的函數,參數為接收子組件傳過來的值
handleSendAction(val){
console.log('觸發了:', val);
this.arr.push(val);
}
}
子組件接收:
props: {
onSend: Function
},
子組件傳值觸發事件
<!-- 通過button按鈕的click觸發事件 -->
<button @click="btnAction">發送</button>
// 通過觸發事件,觸發父組件傳過來的函數
btnAction(){
console.log(this.value);
// 調用父組件的屬性,這個屬性是一個函數,傳入參數為子組件傳過去的值
this.onSend(this.value);
}
father.vue
<template>
<div class="father">
<h1>父組件</h1>
<p>接收到了:</p>
<ul>
<li v-for="(item,index) in arr" :key="index">
{{item}}
</li>
</ul>
<!-- 父組件調用子組件,綁定一個函數屬性,函數在methods中實現 -->
<Son :onSend="handleSendAction"/>
</div>
</template>
<script>
import Son from './Son'
export default {
components: {
Son
},
data(){
return {
arr: []
}
},
methods: {
//函數的實現,也就是傳入子組件中的函數,參數為接收子組件傳過來的值
handleSendAction(val){
console.log('觸發了:', val);
this.arr.push(val);
}
}
}
</script>
<style scoped>
.father{
border: 5px solid #ddd;
padding: 50px;
}
</style>
son.vue
<template>
<div class="son">
<h1>子組件</h1>
<input type="text" v-model.lazy="value"/>
<!-- 通過button按鈕的click觸發事件 -->
<button @click="btnAction">發送</button>
</div>
</template>
<script>
export default {
//父組件接收,該值為一個函數類型
props: {
onSend: Function //確定該值為一個函數
},
data(){
return {
value: ''
}
},
methods: {
// 通過觸發事件,觸發父組件傳過來的函數
btnAction(){
console.log(this.value);
// 調用父組件的屬性,這個屬性是一個函數,傳入參數為子組件傳過去的值
this.onSend(this.value);
}
}
}
</script>
<style scoped>
.son{
border: 5px solid #999;
padding: 50px;
}
</style>
第二中方式:
父組件調用子組件:
<Son @send="handleSendAction" />
函數實現:
handleSendAction(val, ...rest){
console.log('觸發了:', val, rest);
this.arr.push(val);
}
子組件觸發:
<button @click="btnAction">發送</button>
btnAction(){
console.log(this.value);
// 觸發組件標簽上的事件
// 自定義事件
// 參數1:自定義事件的名字
// 參數2:調用事件的參數
this.$emit('send', this.value, 1, 2, 3);
}
father.vue
<template>
<div class="father">
<h1>父組件</h1>
<p>接收到了:</p>
<ul>
<li v-for="(item,index) in arr" :key="index">
{{item}}
</li>
</ul>
<Son @send="handleSendAction" />
</div>
</template>
<script>
import Son from './Son'
export default {
components: {
Son
},
data(){
return {
arr: []
}
},
methods: {
handleSendAction(val, ...rest){
console.log('觸發了:', val, rest);
this.arr.push(val);
}
}
}
</script>
<style scoped>
.father{
border: 5px solid #ddd;
padding: 50px;
}
</style>
son.vue
<template>
<div class="son">
<h1>子組件</h1>
<input type="text" v-model.lazy="value"/>
<button @click="btnAction">發送</button>
</div>
</template>
<script>
export default {
data(){
return {
value: ''
}
},
methods: {
btnAction(){
console.log(this.value);
// 觸發組件標簽上的事件
// 自定義事件
// 參數1:自定義事件的名字
// 參數2:調用事件的參數
this.$emit('send', this.value, 1, 2, 3);
}
}
}
</script>
<style scoped>
.son{
border: 5px solid #999;
padding: 50px;
}
</style>