一、注冊組件步驟
1.Vue.extend():
- 調用
Vue.extend()
創建的是一個組件構造器 - 通常在創建組件構造器時,傳入
template
代表自定義的組件模板 - 該模板就是要顯式的HTML代碼。
2.Vue.component():
- 調用
Vue.component()
將組件構造器注冊成一個組件,並給它起一個組件的標簽名稱 - 需要傳遞兩個參數:1.注冊組件的標簽名 2.組件構造器
3.組件必須掛載在Vue的實例下,否則不會生效
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
// 1.創建組件構造器對象
const cpnC = Vue.extend({
template: `
<div>
<h2>標題</h2>
<p>內容111</p>
</div>`
})
// 2.注冊組件
Vue.component('my-cpn', cpnC) //全局注冊 ,全局組件可以在多個vue實例中使用
const app = new Vue({
el: "#app",
data: {
},
//局部組件, 只能在指定的vue實例中使用
components: {
cpn: cpnC
}
})
</script>
</html>
二、注冊組件的語法糖
省略
Vue.extend()
,直接使用對象代替
<script>
// 全局注冊
Vue.component('cpn1', {
template: `
<div>
<h2>標題1</h2>
<p>內容111</p>
</div>`
})
const app = new Vue({
el: "#app",
data: {
},
// 局部注冊
components: {
cpn2: {
template: `
<div>
<h2>標題2</h2>
<p>內容222</p>
</div>`
}
}
})
</script>
三、模板分離的寫法
1.通過script標簽
<!-- script標簽,類型必須是text/x-template -->
<script type="text/x-template" id="cpn">
<div>
<h2>標題1</h2>
<p>內容111</p>
</div>
</script>
Vue.component('cpn', {
template: '#cpn'
})
2.通過template標簽
<template id="cpn">
<div>
<h2>標題2</h2>
<p>內容222</p>
</div>
</template>
Vue.component('cpn', {
template: '#cpn'
})
四、組件存放數據
組件對象也可以通過data屬性存放數據,但data必須是一個函數,而且需要返回一個對象,對象內部存放數據。
<template id="cpn">
<div>
<h2>{{title}}</h2>
<h2>標題2</h2>
<p>內容222</p>
</div>
</template>
Vue.component('cpn', {
template: '#cpn',
data() {
return {
title: 'abc'
}
}
})
為什么必須是函數?
每個組件實例的函數會返回一個單獨的對象,每個對象之間不會相互影響,反而言之,返回同一個對象 會造成組件之間相互影響
五、父子組件通信
子組件不能引用父組件或者Vue實例中的數據,但實際開發中需要將數據從父組件傳遞給子組件,或者子組件發送給父組件。
比如: 服務器返回的數據有一部分是要給子組件展示的,這個時候就需要父傳子了。
- 通過props向子組件傳遞數據
- 通過事件向父組件發送消息
- 父組件向子組件傳遞數據
1.1首先在父組件中注冊子組件,
1.2在子組件中通過props定義變量接收,
1.3通過綁定屬性的形式將值傳遞給子組件<cpn :cmovies="movies" :cmessage="message"></cpn>
1.4子組件中就可以使用傳遞過來的值了。
<body>
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
{{cmovies}}
<h2>{{cmessage}}</h2>
</div>
</template>
</body>
<script src="../js/vue.js"></script>
<script>
// 父傳子 props
const cpn = {
template: '#cpn',
// props: ['cmovies', 'cmessage']
props: {
cmessage: {
// 類型限制
type: String,
// 默認值
default: '我很好',
required: true
},
cmovies: {
type: Array,
default() {
return ['aaa', 'bbb']
}
}
}
}
const app = new Vue({
el: "#app",
data: {
message: "你好啊",
movies: ['海王', '海賊王', '海爾兄弟']
},
components: {
cpn
}
})
</script>
注:> 類型是對象或者是數組時,默認值必須是一個函數
v-bind屬性綁定時,不支持駝峰命名,例如(cInfo需改為c-info)。
- 子組件向父組件傳遞數據
2.1在子組件中通過
$emit
發射自定義事件
2.2在父組件中監聽自定義事件
<!-- 子組件 -->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<!-- 父組件 -->
<div id="app">
<cpn @item-click="cpnClick"></cpn>
</div>
<script>
// 子組件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{ id: 'aaa', name: '熱門推薦' },
{ id: 'bbb', name: '手機數碼' },
{ id: 'ccc', name: '家用電器' },
{ id: 'ddd', name: '電腦辦公' },
]
}
},
methods: {
btnClick(item) {
// 子組件發射事件
this.$emit('item-click', item)
}
}
}
const app = new Vue({
el: "#app",
methods: {
cpnClick(item) {
console.log('cpnClick', item)
}
},
components: {
cpn
}
})
六、父子組件直接訪問
1.父組件通過$children
直接訪問子組件
在父組件中通過
$children
獲取的是一個vue組件數組,可以調用里面的方法
2.父組件通過$refs
直接訪問子組件
默認返回的是一個空對象,需要在應用子組件的地方加上
ref="xxx"
<!-- 父組件 -->
<div id="app">
<cpn></cpn>
<cpn ref="aaa"></cpn>
<button @click="btnClick">點擊</button>
</div>
<!-- 子組件 -->
<template id="cpn">
<div>
子組件
</div>
</template>
</body>
<script src="../js/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {
}
},
methods: {
showMessage() {
console.log('showMessage111')
},
}
}
const app = new Vue({
el: "#app",
methods: {
btnClick() {
// console.log(this.$children);
// this.$children[0].showMessage();
// refs 對象類型,
console.log(this.$refs.aaa);
}
},
components: {
cpn
}
})
</script>
- 子組件通過
$parent
訪問父組件,使用較少
4.訪問根組件$root
vue實例。