前置说明:借鉴来源
1.单向数据流:只能父组件向子组件传递信息,子组件不能向父组件传递信息
2.在组件中使用从props传来的数据可以直接用this.xxx来获取
3.数据验证:在HTML中绝对不允许使用驼峰,因为HTML会把大写全部转化为小写。在props中可以用驼峰或短横线,在template和data、this.xxx中只能使用驼峰,这是因为在vue中短横线会被误认为减号,会报错。即在HTML中使用短横线,在vue中使用驼峰
4.props中数据类型为引用类型Array或Object时,采用默认值要使用函数返回值的形式;额外说明:除根实例中data,其余组件中data要用函数返回值形式
父子传值:使用props传递数据
在父组件中声明msg,传值给子组件中:
<div id="app">
我是父组件
<child-component :msg="fatherMsg"></child-component>
</div>
<script>
var app = new Vue({
el: '#app',
components: {
'child-component': {
// 从父组件和本身data传入的数据在methods、template中都可以使用
props: ['msg'],
data: function(){
return {
count:1
}
},
template: '<div id="child">{{msg}}</div>',
}
}
})
</script>
子父传值:使用vm.$emit()
子组件向父组件传递信息的步骤:
- 在父组件里写入自定义事件名,事件名后面跟着的是要执行的方法
- 子组件通过$emit向父组件传递信息,第一个参数是自定义的事件名,后面是要传递的参数,可以接无限个
<div id="app">
我的账户余额为:{{count}}
<child-component @xxx="changeCount"></child-component>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
count: 2000
},
methods: {
changeCount: function (value) {
this.count = value
}
},
components: {
'child-component': {
// 注意这里template一定要有DOM元素包裹
template: `<div>
<button @click="handleIncrease">+1000</button>
<button @click="handleReduce">-1000</button>
</div>
`,
data:function(){
return {
count: 2000
}
},
methods: {
handleIncrease: function () {
this.count += 1000 // 这里的this.count是组件里面的count
this.$emit('xxx',this.count) // emit表示向父组件通信,第一个参数是自定义事件的名称,后面是要传入的值,可以写无限个
},
handleReduce: function () {
this.count -= 1000
this.$emit('xxx',this.count)
}
}
}
}
})
</script>
非父子传值:采用bus作为中介
非父组件之间的通信需要一个bus作为中介
在父组件的新建一个bus: new Vue()
对象,写法在实例前面声明: Vue.prototype.bus = new Vue(); 在当前组件中直接this.bus即可,在子组件中使用
然后在A组件内用this.$parent.bus.$emit('事件名',参数)
Vue.component('a-component',{
template: `
<div>
<input type="text" v-model="text">
</div>`,
data:function () {
return {
text: '我是A组件'
}
},
watch:{ // 在这里监听,可实时改变
//watch的用法,key代表要监听的数据,后面接操作
text: function () {
this.bus.$emit('xxx',this.text) // 这里设置自定义事件传值
}
}
})
在B组件内,在对应的钩子事件中用this.$parent.bus.$on('事件名',参数)
Vue.component('b-component',{
template: '<div>我是b组件---{{textb}}</div>',
data:function () {
return {
textb: 'bbbbb'
}
},
created: function () {
var _this = this
this.bus.$on('xxx',function (value) { // 这里是接收兄弟组件中的事件名,value为传过来的值
// alert('created')
_this.textb = value
})
}
})
另一种写法:
<div id="app">
<a-component ref="a"></a-component>
<b-component ref="b"></b-component>
</div>
<script>
Vue.prototype.bus = new Vue();
var app = new Vue({
el: '#app',
data: {
count: 2000
},
methods: {
changeCount: function (value) {
this.count = value
}
},
components: {
'b-component': {
template: '<div>我是b组件---{{text}}</div>',
data: function () {
return {
text: 'bbbbb'
}
},
created: function () {
var _this = this
this.bus.$on('xxx', function (value) {
// alert('created')
_this.text = value
})
}
},
'a-component': {
template: `
<div>
<input type="text" v-model="text">
</div>`,
data: function () {
return {
text: '我是A组件'
}
},
watch: {
//watch的用法,key代表要监听的数据,后面接操作
text: function () {
this.bus.$emit('xxx', this.text)
}
}
}
}
})