这是我参与更文挑战的第9天,活动详情查看: 更文挑战
一、组件间的通信
组件实例的作用域是孤立的;这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。但是父子组件之间需要通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。
在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。如下图所示:
二、 Prop — 父组件传递数据给子组件
prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props 选项声明 “prop”:
Vue.component('child', {
// 声明 props
props: ['message'],
// 就像 data 一样,prop 可以用在模板内
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>'
})
复制代码
2.1 简单的传值
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component message="你好"></my-component>
</div>
<script src="js/vue.js"></script>
<script>
Vue.component('my-component',{
props:['message'],
template:'<h1>{{message}}</h1>'
});
new Vue({
el:'#app'
})
</script>
</body>
</html>
复制代码
注意:HTML 特性不区分大小写。当使用非字符串模版时,prop的名字形式会从 camelCase 转为 kebab-case(短横线隔开)。
2.2 父组件传值给子组件,动态绑定
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<my-component message="message"></my-component>
<template id="myComponent">
{{message}}
</template>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
message:'你好'
},
components:{
'my-component':{
template:'#myComponent',
props:['message']
}
}
})
</script>
</body>
</html>
复制代码
2.3 prop默认是单向绑定
当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<div>
<p>{{name}}</p>
<input type="text" v-model="name" />
</div>
<template id="myComponent">
{{name}}
</template>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
name:'你好'
},
components:{
'my-component':{
template:'#myComponent',
props:['name']
}
}
})
</script>
</body>
</html>
复制代码
结论:在vuejs2.0中,任何试图在组件内修改通过props传入的父组件数据都被认为是anti-pattern的。
三、自定义事件
我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件!
每个 Vue 实例都实现了事件接口(Events interface),即:
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
一个简单的官方案例帮助我们来理解:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<div>
<p>{{total}}</p>
<button-component @clicktotal="clicktotal"></buton-component>
</div>
<template id="myComponent">
<button @click="clicktotal"></button>
</template>
</div>
<script src="js/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
total:0
},
methods:{
clicktotal(){
this.total += 1
},
},
components:{
'my-component':{
template:'#myComponent',
props:['name'],
methods:{
clicktotal(){
this.$emit('clicktotal')
}
}
}
}
})
</script>
</body>
</html>
复制代码
运行结果:子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END