父组件向子组件传值
1.在子组件的 props 中以数组形式接收父组件传递过来的值;
2.父组件在使用组件时在组件属性中使用 v-bind 指令动态传值给子组件。示例如下:
<body>
<div id="app">
<div>{{tip}}</div>
<!-- 调用 tab-bar 组件并传值,注意动态传值要给属性名添加上 v-bind 指令 -->
<tab-bar :tip="tip" :pnum="12" :pflag="true" :parr="arr" :pobj="obj"></tab-bar>
<!-- 注:pnum 如果不加 : 的修饰符则 "12" 就是字符串类型了
如果 pflag 不加 : 的修饰符则 "true" 也是一个字符串类型,不是布尔值了
所以如果传递的值是数值或布尔型的值,: 的修饰符是可以改变数值的数据类型的,这点很重要
-->
</div>
<script>
// 定义一个全局组件
Vue.component('tab-bar', {
// 在 props 中以数组形式接收父组件传递过来的值
props: ['tip', "pnum", "pflag", "parr", "pobj"],
data() {
return {
msg: '这是子组件中的内容'
}
},
// 注意:模板组件中最外层必须是一个单元素
template: `<div>
<div>{{msg + "----" + tip}}</div>
<div>{{12 + pnum}}</div>
<div>{{pflag}}</div>
<div>
<li :key="index" v-for="(item, index) in parr">{{item}}</li>
</div>
<div>{{pobj.name}}</div>
<div>{{pobj.age}}</div>
<div>{{pobj.gerder}}</div>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
tip: '这是父组件中的内容',
arr: ['apple', 'orange', 'banana'],
obj: {
name: 'lisi',
age: 20,
gerder: 'male'
}
},
methods: {}
});
</script>
</body>
注:父组件可以向子组件传递任意类型的值,但是如果要动态传递值则必须使用 v-bind (语法糖为 :)的方式,不然传递的值就是字符串类型了。
子组件向父组件传值
1.在子组件中通过 $emit() 来触发父组件中的自定义事件并传值,参数1为自定义事件名,参数2为要传递给父组件的值。
2.父组件在使用子组件时通过 v-on (语法糖为 @)来定义自定义事件并监听该事件的响应,通过 $event 作为事件响应参数来接收子组件传递过来的值。
<body>
<div id="app">
<!-- 动态的为 div 中的字体大小赋值 -->
<div :style="{fontSize: fontSize + 'px'}">这是父组件中的文字,其字体大小由子组件决定</div>
<!-- 使用子组件并监听自定义事件将之绑定到 getFontSize 上 -->
<!-- 通过 $event 来接收子组件传递过来的值 -->
<!-- <container v-on:font-size="getFontSize($event)"></container> -->
<container @font-size="getFontSize"></container>
<!-- 注:以上两行的写法都是可以的,效果完全相同 -->
</div>
<script>
var container = {
data() {
return {
// 定义一个变量,这个值最终会传递给父组件
fontSize: 30
}
},
created() {
// 在 created 生命周期函数中调用向父组件传值的函数
this.setFontSize()
},
methods: {
// 此函数用于通过 $emit 自定义事件向父组件传值
setFontSize() {
// 通过 font-size 自定义事件传递一个组件中定义的 fontSize 值
this.$emit('font-size', this.fontSize)
}
},
template: `<p>这是子组件中的内容,其定义了一个 font-size={{this.fontSize}}px 的量传递给了父组件</p>`,
}
var vm = new Vue({
el: '#app',
data: {
// 定义一个变量用于接收子组件传递过来的值
fontSize: 0
},
methods: {
// 监听子组件通过自定义事件传值的事件
getFontSize(e) {
// 将接收到的值赋值给自己的 fontSize 变量
console.log(e); // 30
this.fontSize = e
}
},
components: {
// 将 container 组件注册为 app 组件的子组件
container
}
});
</script>
</body>
非父子组件间传值(如兄弟组件)
1.非父子组件间的互相传值相当于发布订阅模式;
2.通过 $emit() 去触发别的组件的自定义事件,并将组件中的值作为第二个参数传递出去;
3.通过 $on() 来监听自定义事件的触发并通过第二个参数来接收组件传递的值。
<body>
<div id="app">
<tab-addtow></tab-addtow>
<tab-addone></tab-addone>
</div>
<script>
// 提供事件中心
var hub = new Vue()
// 全局组件 A
Vue.component('tab-addtow', {
data: function () {
return {
num: 0
}
},
template: `
<div>
<div>组件A:{{num}}</div>
<button @click="addTow">点击组件A的按钮</button>
</div>
`,
methods: {
// 监听自己的按钮点击事件
addTow: function () {
// 通过 $emit 来触发别的组件自定义的 add-tow 事件并传递一个值 2
hub.$emit('add-tow', 2)
}
},
// 在 mounted 生命周期函数中监听组件中的自定义事件
mounted: function () {
// 监听自定义事件 add-one 并使用 val 来接收传递的值
hub.$on('add-one', (val) => {
console.log(val); // 1
this.num += val
})
}
})
// 全局组件 B
Vue.component('tab-addone', {
data: function () {
return {
num: 0
}
},
template: `
<div>
<div>组件B:{{num}}</div>
<button @click="addOne">点击组件B的按钮</button>
</div>
`,
methods: {
// 监听自己的按钮点击事件
addOne: function () {
// 通过 $emit 来触发别的组件中定义的 add-one 事件并传递一个值 1
hub.$emit('add-one', 1)
}
},
// 在 mounted 生命周期函数中监听组件中的自定义事件
mounted: function () {
// 监听自定义事件 add-tow 并使用 val 来接收传递过来的值
hub.$on('add-tow', (val) => {
console.log(val); // 2
this.num += val
})
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>