02-全局組件和局部組件的使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
//ES6 ``
//1創建組件構造器對象
//extend創建一個組件構造器 通常在創建組件構造器時,傳入template代表我們自定義組件的模板
//該模板就是在使用組件的地方,要顯示的HTML代碼
const cpnc = Vue.extend({
template:`
<div>
<h2>我是哈哈哈</h2>
</div>
`
})
//2.註冊組件(全局組件 ,意味着可以在多個vue的實例下面使用)
//怎麼註冊的組件纔是局部組件
Vue.component('cpn',cpnc)
const app = new Vue({
el:'#app',
data:{
message:"你好!"
},
component:{
cpn:cpnc
}
})
</script>
</body>
</html>
當我們通過調用Vue.component()註冊組件時,組件的註冊時全局的
如果我們註冊的某個組件時掛載在,某個實例中, 那麼就是一個局部組件
03父組件和子組件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script>
//1.創建第一個組件(子組件)
const cpnc1 = Vue.extend({
template:`
<div>
<h2>我是標題1</h2>
<p>哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈</p>
</div>`
})
//2創建第二個組件構造器(父組件)
const cpnc2 = Vue.extend({
template:`
<div>
<h2>我是標題2</h2>
<p>紅紅火火恍恍惚惚呵呵哈哈哈呵呵哈哈哈哈哈哈哈呵呵哈哈哈</p>
<cpn1></cpn1>
</div>`,
components:{
cpn1:cpnc1
}
})
//root組件
const app = new Vue({
el:'#app',
data:{
message:"你好!"
},
components: {
cpn2:cpnc2
}
})
</script>
</body>
</html>
組件和組件之間存在層級關係 而其中一種非常重要的關係就是父子組件的關係
父子組件的錯誤用法,以子標籤的形式在Vue實例中使用
因爲當子組件註冊到父組件的component中時Vue會編譯好父組件的模塊
該模板的內容已經決定了父組件將要渲染的HTML (相當於父組件中已經有了子組件中的內容了)
是隻能在父組件中被識別的
類似這種用法,是會被瀏覽器忽略的
組件的語法糖註冊方式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn1></cpn1>
<cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
//1.全局組件註冊的語法糖
//2.創建組件構造器
// const cpnc1 = Vue.extend()
//2.註冊組件
Vue.component('cpn1',{
template:`
<div>
<h2>我是標題1</h2>
<p>哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈</p>
</div>`
})
//註冊局部組件的語法糖
//Vue爲了簡化這個過程,提供了註冊的語法糖
//主要是省去了調用Vue.extend()步驟,而是可以直接使用一個對象來代替
const app = new Vue({
el:'#app',
data:{
message:"你好!"
},
components:{
'cpn2':{
template:`
<div>
<h2>我是標題1</h2>
<p>呵呵呵呵</p>
</div>`
}
}
})
</script>
</body>
</html>
Vue爲了簡化註冊方式,提供了語法糖
主要是省去了調用Vue.extend()的步驟,而是可以直接使用一個對象來代替
組件模板的分離寫法
剛纔,我們通過語法糖簡化了Vue組件的註冊過程,另外還有一個地方的寫法比較麻煩,就是tamplate模板寫法
如果我們能將其中的HTML代碼抽離出來,然後掛載到對應的組件上,必然結構會變得非常清晰
Vue提供了兩種方案來定義HTML模板的內容
1,使用script標籤
2,使用template標籤
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<!-- 1 script標籤-->
<!-- <script type="text/x-template" id="cpn">
<div>
<h2>我是標題哈哈哈</h2>
<p>我是內容呵呵呵</p>
</div>
</script> -->
<!-- 2.template標籤 -->
<template id="cpn">
<div>
<h2>我是標題哈哈哈</h2>
<p>呵呵呵呵呵</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script type="text/javascript">
Vue.component('cpn',{
template:'#cpn'
})
const app = new Vue({
el:'#app',
data:{
message:"你好!"
}
})
</script>
</body>
</html>
組件中的數據存放問題
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>{{title}}</h2>
<p>呵呵呵呵呵</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script type="text/javascript">
Vue.component('cpn',{
template:'#cpn',
data(){
return{
title:'avc'
}
}
})
const app = new Vue({
el:'#app',
data:{
message:"你好!"
}
})
</script>
</body>
</html>
組件中的數據存放在哪裏呢
組件對象也有一個data屬性(也可以有methods等屬性,下面我們有用到)
只是這個data屬性必須是一個函數
而且這個函數返回一個對象,對象內部保存着數據
爲什麼data是一個函數
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h2>當前計數 {{count}}</h2>
<button @click = 'btn'>+</button>
<button @click = 'btns' v-bind:disabled = "count <= 1">-</button> </button>
</div>
</template>
<script src="../js/vue.js"></script>
<script type="text/javascript">
//1註冊組件
Vue.component('cpn',{
template:'#cpn',
data(){
return {
count:0
}
},
methods:{
btn(){
this.count++
},
btns(){
this.count--
}
}
})
const app = new Vue({
el:'#app',
data:{
message:"你好!"
},
})
</script>
</body>
</html>
我們用了計算加減案例來具體說明
首先,如果不是一個函數,Vue就會直接報錯
其次,願意是在於Vue讓每個組件對象都返回一個新的對象,因爲如果是同一個對象的,組件在多次使用的時候就會受影響
父組件對子組件的傳遞
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn :mess = 'message' :cmoves = 'moves'></cpn>
</div>
<template id="tam">
<div>
<li v-for = 'item in cmoves'>{{item}}</li>
<h2>{{mess}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//2創建第二個組件構造器(父組件)
//父傳子 : props
const cpn = Vue.extend({
template: '#tam',
// props:['cmoves','mess'] //傳遞數組方式
props:{
//類型的限制
// cmoves:Array,
// mess:String,
//2提供一些默認值,以及必傳值
mess:{
type:String,
default:'aaa',
required:true
},
//類型是對象或者數組時,默認值必須是一個函數
cmoves:{
type:Array,
default(){
return {}
}//vue2.5.2以下這樣的寫法都是不會錯
}
}
})
const app = new Vue({
el:'#app',
data:{
message:"你好!",
moves :['海王','海賊王','海爾兄弟']
},
components: {
cpn
}
})
</script>
</body>
</html>
在上衣節中,我們提到了子組件是不能引用父組件或者Vue實例的
但是,在開發中,往往一些數據確實需要從上層傳遞到下層
比如在一個頁面中,我們從服務器請求到了數據
其中一部分數據,並非是我們整個頁面的大組件來展示的,而是需要下面的子組件進行展示
這個時候,並不會讓子組件再次發送一個網絡請求,而是直接讓大組件把數據傳遞給小組件
我們可以通過props向子組件傳遞數據
通過事件向父組件發送消息