7. 單文件組件的使用
組件有兩種:普通組件、單文件組件
普通組件的缺點:
- html代碼是作為js的字符串進行編寫,所以組裝和開發的時候不易理解,而且沒有高亮效果。
- 普通組件用在小項目中非常合適,但是復雜的大項目中,如果把更多的組件放在html文件中,那么維護成本就會變得非常昂貴。
- 普通組件只是整合了js和html,但是css代碼被剝離出去了。使用的時候的時候不好處理。
將一個組件相關的html結構,css樣式,以及交互的JavaScript代碼從html文件中剝離出來,合成一個文件,這種文件就是單文件組件,相當於一個組件具有了結構、表現和行為的完整功能,方便組件之間隨意組合以及組件的重用,這種文件的擴展名為“.vue”,比如:"Home.vue"。
-
創建組件
在組件中編輯三個標簽,編寫視圖、vm對象和css樣式代碼。
7.1 template 編寫html代碼的地方
<template>
<div id="Home">
<span @click="num--" class="sub">-</span>
<input type="text" size="1" v-model="num">
<span @click="num++" class="add">+</span>
</div>
</template>
7.2 script編寫vue.js代碼
<script>
export default {
name:"Home",
data: function(){
return {
num:0,
}
}
}
</script>
7.3 style編寫當前組件的樣式代碼
<style scoped>
.sub,.add{
border: 1px solid red;
padding: 4px 7px;
}
</style>
7.4 完成案例-點擊加減數字
創建Homes.vue
<template>
<div class="add_num">
<span @click="num++">+</span>
<input type="text" size="2" v-model="num">
<span @click="num--">-</span>
</div>
</template>
<script>
export default{
name:"AddNum",
data: function(){
return {
num: 0,
}
}
}
</script>
<style scoped>
.add_num{
font-size: 32px;
}
</style>
在App.vue組件中調用上面的組件
<template>
<div id="Home">
<span @click="num--" class="sub">-</span>
<input type="text" size="1" v-model="num">
<span @click="num++" class="add">+</span>
</div>
</template>
<script>
export default {
name:"Home",
data: function(){
return {
num:0,
}
}
}
</script>
<style scoped>
.sub,.add{
border: 1px solid red;
padding: 4px 7px;
}
</style>
在開發vue項目之前,需要手動把 App.vue的HelloWorld組件代碼以及默認的css樣式,清楚。
上面的代碼效果:
7.4 組件的嵌套
有時候開發vue項目時,頁面也可以算是一個大組件,同時頁面也可以分成多個子組件.
因為,產生了父組件調用子組件的情況.
例如,我們可以聲明一個組件,作為父組件
在components/創建一個保存子組件的目錄HomeSon
在HomeSon目錄下,可以創建當前頁面的子組件,例如,是Menu.vue
// 組件中代碼必須寫在同一個標簽中
<template>
<div id="menu">
<span>{{msg}}</span>
<div>hello</div>
</div>
</template>
<script>
export default {
name:"Menu",
data: function(){
return {
msg:"這是Menu組件里面的菜單",
}
}
}
</script>
然后,在父組件中調用上面聲明的子組件。
最后,父組件被App.vue調用.就可以看到頁面效果.
效果:
7.5 傳遞數據
父組件的數據傳遞給子組件
例如,我們希望把父組件的數據傳遞給子組件.
可以通過props屬性來進行數據傳遞.
傳遞數據三個步驟:
-
在父組件中,調用子組件的組名處,使用屬性值的方式往下傳遞數據
<Menu :mynum="num" title="home里面寫的數據"/> # 上面表示在父組件調用Menu子組件的時候傳遞了2個數據: 如果要傳遞變量[變量可以各種類型的數據],屬性名左邊必須加上冒號:,同時,屬性名是自定義的,會在子組件中使用。 如果要傳遞普通字符串數據,則不需要加上冒號:
-
在子組件中接受上面父組件傳遞的數據,需要在vm組件對象中,使用props屬性類接受。
<script> export default { name:"Menu", props:["mynum","title"], data: function(){ return { msg:"這是Menu組件里面的菜單", } } } </script> // 上面 props屬性中表示接受了兩個數據。
-
在子組件中的template中使用父組件傳遞過來的數據.
<template> <div id="menu"> <span>{{msg}},{{title}}</span> <div>hello,{{mynum}}</div> </div> </template>
效果:
步驟流程:
使用父組件傳遞數據給子組件時, 注意一下幾點:
-
傳遞數據是變量,則需要在屬性左邊添加冒號.
傳遞數據是變量,這種數據稱之為"動態數據傳遞"
傳遞數據不是變量,這種數據稱之為"靜態數據傳遞"
-
父組件中修改了數據,在子組件中會被同步修改,但是,子組件中的數據修改了,是不是影響到父組件中的數據.
這種情況,在開發時,也被稱為"單向數據流"
子組件傳遞數據給父組件
-
在子組件中,通過
this.$emit()
來調用父組件中定義的事件.<template> <div> <p>Post的子組件</p> <h2>{{fnum}}</h2> <p>data={{data}}</p> <p>fnum={{fnum}}</p> <div><input type="text" v-model="fnum"></div> </div> </template> <script> export default { name: "PostSon", // 父組件傳遞數據給子組件: 1. 在父組件中調用子組件的組件名稱標簽上面聲明屬性和傳遞值,2. 在子組件中通過props進行接收 props:["data","fnum"], // 接受父組件中傳遞過來的數據 // 子組件傳遞數據給父組件[事件的方式進行傳遞]: watch:{ fnum(){ console.log(this.fnum); // this.$emit("父元素的自定義事件","要傳遞的數據"); // 通過this.$emit()方法,子組件可以把數據傳遞給父組件 this.$emit("postparentdata",this.fnum); } } } </script> <style scoped> </style>
-
父組件中聲明一個和子組件中
this.$emit("自定義事件名稱")
對應的事件屬性。<template> <div> <h1>num={{num}}</h1> <Son data="我是付組件里面的內容" :fnum="num" @postparentdata="getsondata"></Son> </div> </template>
-
父組件中,聲明一個自定義方法,在事件被調用時,執行的。
<script> import Son from "./PostSon" export default { name: "Post", data(){ return { num: 100, } }, components:{ Son:Son, }, methods:{ getsondata(message){ console.log("父組件"+message); this.num = message; } } } </script>