todolist之基本结构——父子组件传参
开始编写代码
准备代码
打开之前的创建的 DetailView.vue 文件,加入以下代码:
<script>
import {
defineComponent,
ref
} from 'vue'
export default defineComponent({
name: 'Detail',
setup() {
return {
}
},
})
</script>
<style>
</style>
在 components 文件夹下新建 child 文件夹,再新建 Child.vue 文件,在其中加入以下代码:
<template>
<div>
<h1>这是child组件</h1>
</div>
</template>
<script>
import {
defineComponent,
ref
} from 'vue'
export default defineComponent({
name: 'Child',
setup() {
return {
}
},
})
</script>
<style>
</style>
父组件引入子组件(DetailView.vue)
<template>
<div>
<h1>这是DetailView组件</h1>
<child></child>
</div>
</template>
<script>
import child from '../components/child/Child.vue'
export default defineComponent({
components: {
child
},
})
</script>
效果
父组件向子组件传值代码(DetailView.vue)
将父组件的数据传递给子组件:通过在子组件的标签上动态绑定属性的方式实现(v-bind)
<template>
<div>
<h1>这是DetailView组件</h1>
<child :msg='msg'></child>
</div>
</template>
<script>
import {
defineComponent,
ref
} from 'vue'
import child from '../components/child/Child.vue'
export default defineComponent({
name: 'Detail',
components: {
child
},
setup() {
let msg = ref('这是父组件的数据')
return {
msg
}
},
})
</script>
子组件接收父组件传递过来的数据(props)(Child.vue)
<script>
import {
defineComponent,
ref
} from 'vue'
export default defineComponent({
name: 'Child',
// 接收父组件传递过来的参数
// props接收的数据不能直接修改
props: {
msg: {
// 数据类型校验
type: String
}
},
setup(props) {
console.log(props);
return {
}
},
})
</script>
效果
代码
console.log(props.msg);
效果
代码
<template>
<div>
<h1>这是child组件</h1>
父组件传递过来的数据:{{msg}}
</div>
</template>
效果
type(数据类型校验)
在子组件中规定了传过来的数据是String类型:
type: String
那么父组件中就不能传其他类型的数据,在父组件中修改代码:
let msg = ref(10)
会发现:
警告:[Vue warn]: Invalid prop: type check failed for prop "msg". Expected String with value "10", got Number with value 10.
翻译:[Vue warn]:无效属性:属性“msg”的类型检查失败。应为值为“10”的字符串,获得值为10的数字。
required
required:判断数据是否是必须传过来,默认为 false。
将代码修改成:
<template> <div> <h1>这是DetailView组件</h1> <child></child> </div> </template>
会发现:
加上代码(Child.vue):
props: { msg: { // 数据类型校验 type: String, // 是否必传 默认是 false required: true } },
会发现:
警告:[Vue warn]: Missing required prop: "msg"
翻译:[Vue warn]:缺少必需的属性:“msg”
default
default:设置默认值,如果父组件的值没有传递过来并且子组件设置了default,那么子组件会去找默认值
用之前的代码:
<child></child>
加上代码(Child.vue):
props: { msg: { // 数据类型校验 type: String, // 是否必传 默认是 false // required: true // 设置默认值 default: '默认值' } },
会发现:
子组件传递参数给父组件
开始前可以看看这篇文章
子组件通过分发事件(emit)的方式向父组件传递数据
代码(Child.vue)
<template>
<div>
<button @click="send">传值给父组件</button>
</div>
</template>
setup(props, ctx) {
let childMsg = ref('我是子组件的数据')
console.log(props.msg);
let send = () => {
// 通过ctx.emit分发事件
// emit方法 第一个参数是事件名称 第二个参数是传递的数据
ctx.emit('send', childMsg.value)
}
return {
childMsg,
send
}
},
父组件接收子组件传递过来的数据
父组件通过在子组件的标签上绑定自定义事件实现接收子组件传过来的数据
代码(DetailView.vue)
<template>
<div>
<child :msg='msg' @send='send'></child>
</div>
</template>
setup() {
let msg = ref('这是父组件的数据')
let send = (val) => {
console.log(val);
}
return {
msg,
send
}
},
效果
补充
onMounted
分发事件还可以通过 onMounted 实现,页面一加载就会分发事件
代码(Child.vue)
import {
defineComponent,
ref,
onMounted
} from 'vue'
setup(props, ctx) {
let childMsg = ref('我是子组件的数据')
onMounted(() => {
ctx.emit('send', childMsg.value)
})
},
效果
emit
emit 传递多个参数有两种方式
方式一(数组)代码
onMounted(() => {
ctx.emit('send', [childMsg.value, childNum.value])
})
效果
方式二(对象)代码
onMounted(() => {
ctx.emit('send', {
msg: childMsg.value,
num: childNum.value
})
})
效果
视频学习地址