Vue中的元件
Vue元件化
元件的使用步驟
呼叫
Vue.extend()
建立一個元件構造器,在建立構造器時傳入需要使用的template
模板即HTML複用的程式碼。然後呼叫Vue.component()
將元件構造器註冊為一個元件,並給元件取一個標籤名稱。使用元件的標籤名在掛載的Vue
例項元素下使用即可。
-
建立元件構造器物件
//1.建立元件構造器物件 const cpnC = Vue.extend({ template: `<div> <h2>元件標題</h2> <p>元件內容</p> </div>`
-
註冊元件
//2.註冊元件 Vue.component('my-component', cpnC)
-
使用元件
<div id="app"> <my-component></my-component> </div>
效果截圖:[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-8d9QgklX-1608995452504)(C:%5CUsers%5C13536%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20201226182053795.png)]
全域性元件
全域性元件可以在多個Vue例項中使用,通過
Vue.component()
註冊的元件為全域性元件
區域性元件
在Vue例項中註冊的元件為區域性元件,只能在註冊的例項中進行使用,使用
components
來註冊元件
const cpnC = Vue.extend({
template: `<div>
<h2>元件標題</h2>
<p>元件內容</p>
</div>`
})
const app = new Vue({
el: '#app',
components: {
//元件名: 元件構造器名
cpn: cpnC
}
})
父子元件
如果想在元件中使用其它的元件,這兩個元件就為父子關係。先建立子元件,然後再建立父元件,在父元件中使用
compoents
註冊子元件就可以在template
中使用子元件
<div id="app">
<cpn-father></cpn-father>
</div>
<script src="../js/vue.js"></script>
<script>
//子元件
const cpnChild = Vue.extend({
template: `<div><h1>子元件標題</h1><p>子元件內容</p></div>`
})
//父元件
const cpnFather = Vue.extend({
//在父模板中使用子元件
template: `<div>
<h1>父元件標題</h1>
<p>父元件內容</p>
<cpn-child></cpn-child>
</div>`,
//在父元件中註冊子元件
components: {
cpnChild
}
})
const app = new Vue({
el: '#app',
components: {
//註冊父元件
cpnFather
}
})
</script>
註冊元件的語法糖
// 全域性元件註冊語法糖
Vue.component('cpn', {
template: `<div><h1>元件標題</h1></div>`
})
//區域性元件註冊語法糖
const app = new Vue({
el: '#app',
components: {
cpn: {
template: `<div><h1>元件標題</h1></div>`
}
}
})
元件模板的抽離
使用<template>
標籤並指定id
進行對模板的抽離,註冊元件時通過id
指定模板
<template id="myCpn">
<div>
<h1>元件標題</h1>
<p>元件內容</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
components: {
myCpn: {
//通過id指定模板
template: '#myCpn'
}
}
})
元件中的資料
如果想要在元件中存放資料,應該使用
data()
函式精選儲存,而不是data
屬性,讓元件建立時保證資料的封閉。
<template id="myTemplate">
<div>
<h1>{{title}}</h1>
<p>{{content}}</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
components: {
myCpn: {
template: '#myTemplate',
//在元件中使用data()函式存放資料
data() {
return {
title: "元件標題",
content: "元件內容"
}
}
}
}
})
</script>
元件的通訊
父子元件通訊需要使用兩種方法,一個是使用
props
向子元件傳遞資料,另一個是通過事件向父元件傳送訊息。
父傳子props
在子元件中使用
props
宣告需要的變數,在使用元件時使用v-bind
對引數進行繫結
<div id="app">
<!-- 通過v-bind將父元件與子元件中的變數進行繫結 -->
<cpn v-bind:c-message="message" :c-movies="movies"></cpn>
</div>
<!-- 子元件模板 -->
<template id="myTemplate">
<div>
<h1>{{cMessage}}</h1>
<ul>
<li v-for="item in cMovies">{{item}}</li>
</ul>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//子元件
const cpn = {
template: '#myTemplate',
//父傳子宣告變數
props: ['cMovies', 'cMessage']
}
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js',
movies: ["《信條》", "《你的名字》", "《讓子彈飛》", "《阿甘正傳》", "《盜夢空間》"]
},
//註冊子元件
components: {
cpn
}
})
</script>
在props
中可以使用陣列進行對變數的宣告,也可以使用物件的形式對資料進行限制或預設值。
注意:陣列型別或物件型別的預設值必須是一個default()
函式
props: {
cMessage: {
//型別
type: String,
//預設值
default: "暫無資料",
//必須傳遞,否則報錯
required: true
},
cMovies: {
type: Array,
//default函式指定預設值
default() {
return ['暫無資料']
},
required: true
}
}
子傳父$emit Events
子元件通過this.$emit('name', parms)
傳送自定義事件,父元件通過v-on
監聽子元件傳送的自定義事件來實現子元件向父元件通訊的過程。
<div id="app">
<!-- 監聽子元件傳送的事件 -->
<cpn @item-click="cpnClick"></cpn>
</div>
<template id="myTemplate">
<div>
<button v-for="item in categories"
@click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
//子元件
const cpn = {
template: '#myTemplate',
methods: {
btnClick(item) {
//傳送自定義事件
this.$emit('item-click', item);
}
},
data() {
return {
categories: [
{id: '001', name: "熱門推薦"},
{id: '002', name: "手機數碼"},
{id: '003', name: "家用家電"},
{id: '004', name: "電腦辦公"},
]
}
}
}
const app = new Vue({
el: '#app',
methods: {
cpnClick(item) {
alert("你選擇了:" + item.name);
}
},
//註冊子元件
components: {
cpn
}
})
</script>
父子元件雙向繫結
實際上是通過子元件向父元件傳送事件進而修改父元件中data
中的資料
<div id="app">
<h1>父元件</h1>
<p>num:{{num}}</p>
<p>msg:{{msg}}</p>
<hr>
<!-- 繫結資料 並且 監聽事件 -->
<cpn :message="msg"
@message-change="msgChange"></cpn>
</div>
<template id="myTemplate">
<div>
<h1>子元件</h1>
<p>message:{{dataMessage}}</p>
<input type="text" :value="dataMessage" @input="messageInput">
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
msg: "Hello world"
},
methods: {
msgChange(value) {
this.count = value;
}
},
//子元件
components: {
cpn: {
template: '#myTemplate',
//父元件傳輸資料
props: {
message: String
},
//儲存資料
data() {
return {
dataMessage: this.message
}
},
//事件
methods: {
messageInput(event) {
//子元件的雙向繫結
this.dataMessage = event.target.value;
//向父元件傳送資料
this.$emit('message-change', this.dataMessage);
}
}
}
}
})
</script>
父子元件的直接獲取
直接獲取即在父元件或子元件中直接獲取到子元件或父元件的物件,進而訪問起屬性和方法。
父元件獲取子元件
父元件可使用
$children
或$refs
獲取子元件。
this.$children
是一個數組,它包含了當前元件下所有的子元件,可通過遍歷的形式獲取需要的子元件。
this.$refs
是一個子元件物件,需要指定元件的ref
,通過$refs.xxx
獲取對應的元件,從而不需要遍歷
<div id="app">
<cpn></cpn>
<button @click="btnClick">訪問子元件</button>
</div>
<template id="myTemplate">
<div>
<h1>子元件</h1>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
btnClick() {
//訪問子元件的showMessage的方法
this.$children[0].showMessage();
}
},
//註冊子元件
components: {
cpn: {
template: '#myTemplate',
data() {
return{
message: "Hello Vue.js"
}
},
methods: {
showMessage() {
alert(this.message);
}
}
}
}
})
</script>
使用refs
<cpn ref="cpn"></cpn>
呼叫形式
this.$refs.cpn.showMessage();
子元件獲取父元件
子元件可以使用
$parent
獲取父元件。
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="myTemplate">
<div>
<h1>子元件</h1>
<button @click="btnClick">訪問父元件</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js'
},
//註冊子元件
components: {
cpn: {
template: '#myTemplate',
methods: {
btnClick() {
//訪問父元件
alert(this.$parent.message);
}
}
}
}
})
</script>