組件之間的傳值
組件是一個單獨功能模塊的封裝,有屬於自己的data和methods,一個組件的 data 選項必須是一個函數
為什么必須是函數:因為只有當data是函數時,不同實例調用同一個組件時才會開辟新空間,互不干擾
data() {
return {
count: 0
}
}
父子組件區分
<div id="app">
<cpn> </cpn>
<cpn1></cpn1>
</div>
<script>
//子組件
const childCpn = Vue.extend({
template: `
<div>
<h3>我是局部組件,也是子組件</h3>
</div>
` })
// 父組件
const parentCpn = Vue.extend({
template: `
<div>
<h2>我是局部組件,也是父組件</h2>
<!-- 使用子組件 -->
<cpn1></cpn1>
</div>
`,
components:{
cpn1: childCpn //在父組件中注冊子組件
}
})
let app = new Vue({
el:"#app",
data:{ },
components:{
cpn : parentCpn,
cpn1 : childCpn //若想在實例中使用子組件也需要在實例中注冊
},
})
</script>
父傳子
Prop 是可以在組件上注冊的一些自定義屬性,prop值可以是屬性也可以是方法,最終都會出現在子組件的實例上供子組件直接調用
一個組件默認可以擁有任意數量的 prop,任何值都可以傳遞給任何 prop ,在組件實例中可以直接訪問這個值,就像訪問 data 中的值一樣
<body>
<!--vue實例需要一個根組件div-->
<div id="app">
<ul>
<!--使用組件-->
<tokyo v-for="item in names " :first-name="item"></tokyo>
</ul>
</div>
<script type="text/javascript">
//注冊組件
Vue.component('tokyo',{
props:['firstName'], //屬性
template:'<li>名字:<h3>{{firstName}}</h3></li>' //模板
})
//vue實例
const app = new Vue({
el:'#app',
data:{
names:['lixiang','wanzi'],
}
})
</script>
</body>
命名方式:
組件名:組件名如果是多個單詞時,首字母大寫或者加橫線都可以。MyComponentName 或my-component-name
若使用首字母大寫的方式注冊,使用時兩種方式都可prop參數:camelCase (駝峰命名法) 的 prop 名需要使用其等價的 kebab-case (短橫線分隔命名) 命名,在子組件內部命名方式不變,綁定父組件屬性時要改駝峰命名
為短橫線連接
語法
父傳子分離寫法
<!--父組件模板-->
<div id="app">
<!--使用子組件,v-bind綁定父組件屬性給子組件props屬性-->
<cpn v-bind:ctitle="title" :cname="names" ></cpn>
</div>
<!--子組件模板-->
<template id="cpnTemplate">
<div>
<h3>{{ctitle}}</h3>
<ul>
<li v-for="item in cname"> <p>{{item}}</p> </li>
</ul>
</div>
</template>
<script>
//注冊子組件
const cpn ={
template:"#cpnTemplate",
props:['cname','ctitle'],
data(){
return{}
},
methods:{
}
}
//注冊父組件
let app = new Vue({
el:"#app",
data:{
names:['丸子','莉香','三上'],
title:'hello'
},
components:{
// cpn:cpn
cpn //標簽名和組件名相同時可簡寫為cpn
}
})
</script>
vue-cli項目組件寫法
1、定義組件
<template>
<div>
<h3>{{ctitle}}</h3>
<ul>
<li v-for="item in cname"> <p>{{item}}</p> </li>
</ul>
</div>
</template>
<script>
export default {
name: "tokyoLoveStory",
components: {},
mixins: [],
props:['cname','ctitle'],
data(){
return{}
},
methods:{
}
};
</script>
2、使用組件
<template>
<!--使用組件時,需變駝峰為短橫線-->
<tokyo-love-story v-bind:ctitle="title" :cname="names"></tokyo-love-story>
</template>
<script>
import tokyoLoveStory from 'xxx/tokyoLoveStory'
export default{
data(){
names:['丸子','莉香','三上'],
title:'hello'
} ,
components:{
tokyoLoveStory
},
methods:{
...
},
...
}
</script>
props另一種書寫形式:
props:{
cname:'',
ctitle:'',
//基礎類型
propA:Number,
//多個可能的類型
propB:[String,Number],
//必填的字符串
propC:{
type:Number,
required:true
},
//帶有默認值的字符串
propD:{
type:Number,
default:100
},
//對象或數組默認值必須是一個函數,返回值是[]或{}
propE:{
type:Object,
default: function () {
return [];
}
}
子組件向父元素傳值
想要子組件的數據傳遞給父元素,需要自定義觸發事件,實現數據的傳值。
子組件可以通過調用內建的 $emit 方法並傳入事件名稱來觸發一個事件
<body>
<!--vue實例需要一個根組件div-->
<div id="app">
<ul>
<!--使用組件,綁定props屬性,子組件的觸發事件調用父元素方法達到傳遞參數的目的-->
<tokyo v-for="item in names "
:first-name="item"
:parentMethod="parentMethod"
@emitevent="emitName">
</tokyo>
</ul>
<h3>選中的姓名是:{{chooseName}}</h3>
</div>
<script type="text/javascript">
<!--注冊組件-->
Vue.component('tokyo',{
props:['firstName'],
template:'<li>名字:<h3>{{firstName}}</h3> ' +
' <button @click="chooseEvent(firstName)">點擊傳遞姓名</button></li>',
methods:{
chooseEvent(firstName){
console.log(firstName);
//觸發父元素中emitevent事件,並傳遞firstName參數給該事件
this.$emit('emitevent',firstName);
}
parent(){
this.parentMethod() //parentMethod()在子組件實例中,可直接調用
}
}
})
const app = new Vue({
el:'#app',
data:{
names:['莉香','丸子','三上','里美'],
chooseName:''
},
methods:{
//父元素被觸發的事件,name為子組件傳遞過來的參數,賦給父元素的data:{}中的屬性
emitName(name){
console.log("被觸發事件");
this.chooseName = name;
},
parentMethod(){
console.log("parentMethod")
}
}
})
</script>
</body>