1、給組件添加屬性
像原始的html元素都有自己的一些屬性,而我們自己創建的組件,也可以通過prop來添加自己的屬性。這樣別人在使用你創建的組件的時候就可以傳遞不同的參數了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button_list v-bind:books="books"> </button_list>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//組件
Vue.component('button_list',{
//給組件添加屬性 propertys 關鍵字
props:['books'],
template:`
<table>
<tr>
<th>序號</th>
<th>標題</th>
</tr>
<tr v-for="(book,index) in books">
<td>{{index+1}}</td>
<td>{{book.title}}</td>
</tr>
</table>
`, //button_list中封裝的內容模板就是這句
data:function(){ //這裏的data寫法不同於new vue中的data
return { //這裏需要{}
count:0
}
}
})
new Vue({
el:"#app",
data:{
books:[
{'title':"python","id":1},
{'title':"java","id":2},
{'title':"php","id":3},
]
}
})
</script>
2、單一根元素
如果自定義的組件中,會出現很多html元素,那麼根元素必須只能有一個,其餘的元素必須包含在這個根元素中。比如以下是一個組件中的代碼,會報錯:
3、子組件事件和傳遞事件到父組件
子組件中添加事件跟之前的方式是一樣的,然後如果發生某個事件後想要通知父組件,那麼可以使用this.$emit函數來實現。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button_list v-for="book in books" v-bind:book="book" @check_change="checks"></button_list>
<div v-for="cbook in component_book">
{{cbook.title}}
</div>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//組件
Vue.component('button_list',{
//給組件添加屬性 propertys 關鍵字
props:['book'],
template:`
<div>
<span>{{book.title}}</span>
<input type="checkbox" @click="Oncheck">
</div>
`, //button_list中封裝的內容模板就是這句
methods:{
Oncheck:function(){
this.$emit('check_change', this.book)
}
}
})
new Vue({
el:"#app",
data:{
books:[
{'title':"python","id":1},
{'title':"java","id":2},
{'title':"php","id":3},
],
component_book:[],
},
methods:{
checks:function(book){
console.log(book)
var index=this.component_book.indexOf(book) //indexOf 返回的是book的下標
if(index >= 0){
this.component_book.splice(index,1) //刪除一個下標爲index的元素
}else{
this.component_book.push(book)
}
}
}
})
</script>
4、自定義組件v-model
一個組件上的v-model默認會利用名爲value的prop(屬性)和名爲input的事件,但是像單選框、複選框等類型的輸入控件可能會將value特性用於不同的目的。這時候我們可以在定義組件的時候,通過設置model選項可以用來實現不同的處理方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<stepper v-model:value="goods_count"></stepper>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//計步器
Vue.component('stepper',{
//給組件添加屬性 propertys 關鍵字
props:['count'],
model:{ //代表什麼情況下觸發這個v-model的行爲
event:'count_change',
prop:'count'
},
template:`
<div>
<button @click="sub">-</button>
<span>{{count}}</span>
<button @click="add">+</button>
</div>
`, //button_list中封裝的內容模板就是這句
methods:{
sub:function(){
this.$emit('count_change', this.count-1)
},
add:function(){
this.$emit('count_change', this.count+1)
}
}
})
new Vue({
el:"#app",
data:{
goods_count:0,
},
})
</script>
其中的props定義的屬性分別是給外面調用組件的時候使用的。model中定義的prop:'count’是告訴後面使用v-model的時候,要修改哪個屬性;event:'count-chang’是告訴v-model,後面觸發哪個事件的時候要修改屬性。
5、插槽
我們定義完一個組件後,可能在使用的時候還需要往這個組件中插入新的元素或者文本。這時候就可以使用插槽來實現。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<new_link v-bind:url="url">
個人中心
</new_link>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//計步器
Vue.component('new_link',{
//給組件添加屬性 propertys 關鍵字
props:['url'],
template:`
<a v-bind:href="url">
<slot></slot>
</a>
`,
})
new Vue({
el:"#app",
data:{
url:"https://www.baidu.com",
},
})
</script>
當組件渲染的時候,將會被替換爲“個人中心”。插槽內可以包含任何模板代碼,包括HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<new_link v-bind:url="url">
個人中心
{{name}}
<template v-slot:header>這是header</template>
<template v-slot:main>這是main</template>
<div></div>
</new_link>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//計步器
Vue.component('new_link',{
//給組件添加屬性 propertys 關鍵字
props:['url'],
template:`
<a v-bind:href="url">
<div>
<slot></slot>
</div>
<div>
<slot name="main"></slot>
</div>
<div>
<slot name="header"></slot>
</div>
</a>
`,
data:function(){
return {
name:"zzz",
}
}
})
new Vue({
el:"#app",
data:{
url:"https://www.baidu.com",
},
})
</script>
如果沒有包含一個元素,則該組件起始標籤和結束標籤之間的任何內容都會被拋棄。
6、生命週期函數
生命週期函數代表的是Vue實例,或者是Vue組件,在網頁中各個生命階段所執行的函數。生命週期函數可以分爲創建階段和運行期間以及銷燬期間。
- 其中創建期間的函數有beforeCreate、created、beforeMount、mounted;
- 運行期間的函數有beforeUpdate、updated;
- 銷燬期間有beforeDestroy、destroyed。
以下是官方文檔給到的一張圖,從這種圖中我們可以瞭解到每個部分執行的函數。
創建期間:
beforeCreate:
Vue或者組件剛剛實例化,data、methods都還沒有被創建。
created:
此時data和methods已經被創建,可以使用了。模板還沒有被編譯。
beforeMount:
created的下一階段。此時模板已經被編譯了,但是並沒有被掛在到網頁中。
mounted:
模板代碼已經被加載到網頁中了。此時創建期間所有事情都已經準備好了,網頁開始運行了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p id="username">{{username}}</p>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('content',{
template:`
<div>
<slot name="header" :navs="navs"></slot>
</div>
<div>
<slot name="footer" :navs="navs"></slot>
</div>
`,
data:function(){
return {
navs:["1","2","3"]
}
}
}),
new Vue({
el:"#app",
data:{
username:"yyy"
},
methods:{
demo:function(){
return "hello"
}
},
//beforeCreate:Vue或者組件剛剛實例化,data、methods都還沒有被創建
beforeCreate(){
// console.log(this.username);
// console.log(this.demo);
// console.log(123);
// console.log("----------------------");
},
//此時data和methods已經被創建,可以使用了。模板還沒有被編譯。
created(){
// console.log(this.username);
// console.log(this.demo);
// console.log(123);
// console.log("----------------------");
},
// created的下一階段。此時模板已經被編譯了,但是並沒有被掛在到網頁中。
beforeMount(){
//console.log(document.getElementById('username').innerText)
},
mounted(){
console.log(document.getElementById('username').innerText) //獲取文本信息
}
})
</script>
運行期間:
beforeUpdate:
在網頁網頁運行期間,data中的數據可能會進行更新。在這個階段,數據只是在data中更新了,但是並沒有在模板中進行更新,因此網頁中顯示的還是之前的。
updated:
數據在data中更新了,也在網頁中更新了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p id="username">{{username}}</p>
<!-- v-model雙向綁定,修改username的值 -->
<input type="text" v-model="username">
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('content',{
template:`
`,
data:function(){
return {
}
}
}),
new Vue({
el:"#app",
data:{
username:"yyy"
},
methods:{
demo:function(){
return "hello world"
}
},
mounted(){
// console.log(document.getElementById('username').innerText) //獲取文本信息
},
// 數據在data中更新了,也在網頁中更新了
update(){
console.log(document.getElementById('username').innerText)
}
})
</script>
銷燬期間:
beforeDestroy:
Vue實例或者是組件在被銷燬之前執行的函數。在這一個函數中Vue或者組件中所有的屬性都是可以使用的。
destroyed:
Vue實例或者是組件被銷燬後執行的。此時Vue實例上所有東西都會解綁,所有事件都會被移除,所有子元素都會被銷燬。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p id="username">{{username}}</p>
<!-- v-model雙向綁定,修改username的值 -->
<input type="text" v-model="username">
<error-view v-bind:message="message" v-if="message"></error-view>
<button @click="message=' ' ">點擊</button>
</div>
</body>
</html>
<!--vue引入 必須聯網-->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
Vue.component('error-view',{
props:['message'],
template:`
<p style="color:red">{{message}}</p>
`,
methods:{
},
data:function(){
return {
}
},
beforeDestroy(){
console.log('hello')
},
}),
new Vue({
el:"#app",
data:{
username:"yyyyyyyyyy",
message:"錯誤信息",
},
methods:{
demo:function(){
return "hello world"
}
},
mounted(){
// console.log(document.getElementById('username').innerText) //獲取文本信息
},
// 數據在data中更新了,也在網頁中更新了
update(){
console.log(document.getElementById('username').innerText)
}
})
</script>