- 阐述
- 编写计数器案例
- 子组件调用父组件事件
- 子组件向父组件传递参数
- 对传递值的校验
前面我们讲了单项数据流的概念,这节学习一下子组件如何通过事件向父组件传递参数,打破单项数据流的限制。
在单项数据流中,我们用了计数器 Counter
这个例子做了个小例子,帮助大家理解。我们先来复习一下什么是单项数据流。
通过计数器的编写,本节我们的学习目标如下:
- 子组件调用父组件事件的编写方法
- 子组件向父组件事件中传递参数的方法
- 子组件传递参数时,如何通过
emits
进行校验
直接开始我们的学习吧。
编写计数器案例DOCTYPE html>
Demo30
const app = Vue.createApp({
data() {
return {
counter: 0
}
},
template: `
willem
`
})
app.component('Counter', {
props: ['counter'],
template: `
{{counter}} 增加数量
`
})
const vm = app.mount("#app")
上面的代码,当我们在浏览器中点击增加时,是不能增加 counter
的值的,这就是Vue单向数据流的限制。
但是有时候,我们就是想在子组件里改变父组件传递过来的值,怎么办呢?
子组件调用父组件事件这时候就需要子组件调用父组件的事件,从而改变父组件里的值。
我们先在父组件里编写一个方法,叫做 handleAddCounter
。这个方法就作一件事,每执行一次,数据项里的 counter
加 1
。
methods: {
handleAddCounter() {
this.counter += 1
}
},
父组件有了这个方法,就可以改变 counter
数据行的值了,有方法后,现在问题就变成了,如何在子组件中调用这个方法了。
这时候可以先在子组件的模板 template
中编写一个 click
事件。
{{counter}} 增加数量
子组件调用的并不是父组件中的方法,而是子组件中的方法。
如果想调用父组件中的 handleAddConter
方法,这时候可以在子组件中新建一个方法handleClick
,然后用 $emit
调用父组件的响应事件 add
。
具体代码如下:
app.component('Counter', {
props: ['counter'],
methods: {
handleClick() {
this.$emit('add')
}
},
template: `
{{counter}} 增加数量
`
})
这时候的 add
是什么呢?
add
就是响应事件,在父组件的模板 template
中,添加一个 add
响应事件,然后响应事件再调用方法 handleAdCounter
。
父组件里的模板:
template: `
willem
`
这时候可以到浏览器看一下结果,你会发现当点击增加按钮的时候,数据项中的 counter
值,已经可以增加了。
只是在控制台会打印出警告。
vue.global.js:1235
[Vue warn]: Extraneous non-emits event listeners (add) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.
at
at
警告的意思是你调用的
add
方法,并没有用 emits
进行声明。
app.component('Counter', {
props: ['counter'],
emits: ['add'],
methods: {
handleClick() {
this.$emit('add')
}
},
})
声明后,控制台中的警告会消失。 这也是Vue对 子组件
调用父组件时的一种约束,就是调用前需要声明,否则就会报出警告。
DOCTYPE html>
Demo
const app = Vue.createApp({
data() {
return {
counter: 0
}
},
methods:{
handleAddCounter(){
this.counter += 1;
}
},
template: `
willem
`
})
app.component('Counter', {
props: ['counter'],
emits: ['add'],
methods: {
handleClick() {
this.$emit('add')
}
},
template: `
{{counter}} 增加数量
`
})
const vm = app.mount("#app")
子组件向父组件传递参数
当我们不是每次想加 1
的时候,比如这个值是子组件决定的,比如是 2
吧。这时候子组件需要向父组件传值,也是可以做到的,你可以在子组件中这样编写。
methods: {
handleClick() {
this.$emit('add', 2)
}
},
然后在父组件中接受这个参数 param (这个参数的名字你可以随便起)
,为了看的方便,在控制台进行打印。
methods: {
handleAddCounter(param) {
console.log(param)
this.counter += param
}
},
这时候子组件的参数就传递给了父组件,并且可以使用了。
当然你还有更好的选择,就是把所有业务逻辑都放在子组件中,然后把结果传递给父组件。
我平时更喜欢用这种方式,比如代码可以写成下面的样子。
业务逻辑写在子组件里:
methods: {
handleClick() {
this.$emit('add', this.counter + 3)
}
},
父组件直接接受结果就可以了:
methods: {
handleAddCounter(param) {
console.log(param)
this.counter = param
}
},
DOCTYPE html>
Demo30
const app = Vue.createApp({
data() {
return {
counter: 0
}
},
methods: {
handleAddCounter(param) {
console.log(param)
this.counter = param
}
},
template: `
willem
`
})
app.component('Counter', {
props: ['counter'],
emits: ['add'],
methods: {
handleClick() {
this.$emit('add', this.counter + 3)
}
},
template: `
{{counter}} 增加数量
`
})
const vm = app.mount("#app")
对传递值的校验
在子组件向父组件传递值的时候,还可以开启校验功能。
校验是通过 emits
这个选项来声明的。
比如现在我们要求传递到 add
中的值,不大于20
。
如果大于20
就进行警告。
emits: {
add: (value) => {
return value DOCTYPE html>
Demo30
const app = Vue.createApp({
data() {
return {
counter: 0
}
},
methods: {
handleAddCounter(param) {
console.log(param)
this.counter = param
}
},
template: `
willem
`
})
app.component('Counter', {
props: ['counter'],
emits: {
add: (value) => {
return value {counter}}
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?