Vue元件與元件間通訊
阿新 • • 發佈:2019-02-05
元件的用法
註冊之後才能使用,註冊分區域性註冊和全域性註冊
元件和Vue例項類似,基本可以使用其所有內容(data,computed,methods,filters,watch)
與Vue例項不同,data是函式,輸入需要return
全域性註冊
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
<script>
Vue.component('component', {
template: `<div>Hello World</div>`
})
new Vue({
el: '#app'
})
</script>
</body>
</html>
區域性註冊
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<my-component></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js" ></script>
<script>
var component = {
template: `<div>Hello World</div>`
}
new Vue({
el: '#app',
components: {
'my-component' : component
}
})
</script>
</body>
</html>
使用props傳遞資料
元件不僅僅是要把模板的內容進行復用,更主要的是元件間要進行通訊。通常父元件的模板中包含子元件,父元件要正向的向子元件傳遞資料或引數,子元件接收到後根據引數的不同來渲染不同的內容或執行操作。這個正向傳遞資料的過程,就是通過props來實現的。
單向資料流
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<my-component :name="auctor" :test="888"></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script>
var component = {
template: `<div>Hello World {{msg}} {{showNum}} {{showNum2}}</div>`,
props: {
name: String,
testNumber: {
type: Number,
default: 666
},
test: {
type: Number,
validator: function(val) { // 自定義驗證函式
return val < 10
}
}
},
data() {
return {
msg: this.name,
showNum: this.testNumber,
showNum2: this.test
}
}
}
new Vue({
el: '#app',
components: {
'my-component': component
},
data() {
return {
auctor: 'Chengyu.Wang'
}
}
})
</script>
</body>
</html>
其中 props中的內容是有資料型別驗證的
1. String
2. Number
3. Boolean
4. Object
5. Array
6. Function
7. Symbol
// props 的具體寫法
props: {
dataA: String, // 只能為字串
dataB: [String,Number], // 能為字串與數字
dataC: {
type: Boolean, // 型別
default: true // 預設值
},
dataD: {
type: Number,
required: true // 是否為必傳
},
dataE: {
type: Array, // 如果資料是陣列或者物件,預設值必須是一個函式來返回
default: function () {
return []
}
},
dataF: {
validator: function(val){ // 自定義驗證函式
return val > 10
}
}
}
元件間的通訊
父子間的元件通訊
子元件使用 $emit(eventName,data) 觸發事件
父元件使用 v-on:=’methodName’ 來監聽事件冒泡,從而獲取子元件的上傳的資料
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<my-component :name="auctor" v-on:reserve='handleReserveName'></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script>
var component = {
template: `<div @click="reverseString">Hello World {{msg}} </div>`,
props: {
name: String
},
data() {
return {
msg: this.name
}
},
methods: {
reverseString: function() {
this.msg = this.msg.split('').reverse().join('')
this.$emit('reserve', this.msg)
}
}
}
new Vue({
el: '#app',
components: {
'my-component': component
},
data() {
return {
auctor: 'Chengyu.Wang'
}
},
methods: {
handleReserveName: function(val) {
console.log(val)
window.alert(val)
}
}
})
</script>
</body>
</html>
父子元件雙向繫結
使用 watch 來對監聽props,從而對屬性重新賦值
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
This is Father num: {{num}}
<button @click="handleFatherAdd">father add</button>
<my-component :num="num" v-on:add='handleAdd'></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script>
var component = {
template: `<div>This is child Num: {{shu}} <button @click="handleAdd">child add</button></div>`,
props: {
num: Number
},
data() {
return {
shu: this.num
}
},
// watch 部分是核心程式碼,可以註釋試試效果
watch: {
num: function(val) {
this.shu = val
}
},
methods: {
handleAdd: function() {
this.shu++
this.$emit('add', this.shu)
}
}
}
new Vue({
el: '#app',
components: {
'my-component': component
},
data() {
return {
num: 666
}
},
methods: {
handleAdd: function(val) {
this.num = val
},
handleFatherAdd: function() {
this.num++
}
}
})
</script>
</body>
</html>
非父子元件之間的通訊
非父子關係的兩個元件之間也需要通訊。在簡單的場景下,可以使用一個空的 Vue 例項作為事件匯流排:
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
{{msg}}
<my-component></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script>
var middle = new Vue()
var component = {
template: `<button @click="handle">點我</button>`,
methods: {
handle: function() {
middle.$emit('handleAAA', Math.random().toString(35).substr(2, 50))
}
}
}
new Vue({
el: '#app',
components: {
'my-component': component
},
data() {
return {
msg: 'AAA'
}
},
mounted() {
var _this = this
middle.$on('handleAAA', function(val) {
_this.msg = val
})
}
})
</script>
</body>
</html>
元件的高階用法
遞迴元件
<!DOCTYPE html>
<html>
<head>
<title>show</title>
<meta charset="utf-8">
</head>
<body>
<div id="app">
<my-component :count="5"></my-component>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script>
var middle = new Vue()
var component = {
template: `<div><my-component :count='count-1' v-if="count > 0"></my-component>{{count}}</div>`,
props: {
count: Number
},
name: 'myComponent' // 核心程式碼
}
new Vue({
el: '#app',
components: {
'my-component': component
},
data() {
return {}
}
})
</script>
</body>
</html>