1、父传子
- 父组件的
setup
函数里面定义响应式数据prop
,并return
出来 - 父组件的模板中通过
:prop="prop"
传递变量给子组件 - 子组件 通过
props
接收,可以直接在子组件模板中使用 - 子组件从父组件获取的值是只读的,不能直接修改
父传子:父组件传值
<template>
<div>
<p>我是父组件</p>
<button @click="fn">按钮</button>
<!-- 使用子组件 -->
<Son :msg="msg"></Son>
</div>
</template>
<script>
// 导入子组件
import Son from './components/Son.vue'
import { ref } from 'vue'
export default {
// 注册子组件
components: {
Son
},
setup () {
// 设置父传子的值
const msg = ref('')
const fn = () => {
msg.value = '这是父组件传给子组件的'
}
return { msg, fn }
}
}
</script>
父传子:子组件收值
<template>
<div>
<p>我是子组件----{{ msg }}</p>
</div>
</template>
<script>
export default {
// 通过 props 接收父组件传过来的值(可以直接在模板中使用)
// props 也可以是对象接收
props: ['msg'],
setup () {
return {}
}
}
</script>
2、子传父
- 父组件绑定自定义事件 :@自定义事件名=“事件处理函数”
- 子组件在
setup
函数中,在特定时间通过context.emit('自定义事件名',实参)
触发父组件的自定义函数 - 父组件收到子组件传递过来的信号后,进行相应处理
子传父:子组件传值
<template>
<div>
<p>我是子组件</p>
<button @click="fn">按钮</button>
</div>
</template>
<script>
export default {
// 里面是子传父的事件名,传多个值一定要写,不然会有警告
emits:['sonHandler']
// 子传父
setup (props, context) { // context 这里也可以解构
const fn = () => {
context.emit('sonHandler', '这是子组件传给父组件的')
}
return { fn }
}
}
</script>
子传父:父组件收值
<template>
<div>
<p>我是父组件---{{ message }}</p>
<!-- 使用子组件 Son -->
<Son @sonHandler="sonHandlerFn"></Son>
</div>
</template>
<script>
// 导入子组件
import Son from './components/Son.vue'
import { ref } from 'vue'
export default {
// 注册子组件
components: {
Son
},
setup () {
const message = ref('')
const sonHandlerFn = (payload) => {
message.value = payload
}
return { sonHandlerFn, message }
}
}
</script>
3、跨组件传值(依赖注入 provide
和 inject
)
- 父组件利用
provide(键,值)
提供数据 - 子孙组件利用
inject(键)
获取数据(子孙后代, 都可以拿到这个数据)
父传子:父组件
provide
<template>
<div>
<p>我是父组件:{{ root }}</p>
<!-- 使用子组件 -->
<Son></Son>
</div>
</template>
<script>
// 导入子组件 Son
import Son from './components/Son.vue'
import { ref, provide } from 'vue'
export default {
// 注册子组件 Son
components: {
Son
},
setup () {
// 准备要传给其他组件的值
const root = ref('金元宝')
provide('rootMsg', root)
return { root }
}
}
</script>
父传子:子组件
inject
<template>
<div>
<p>我是子组件</p>
<p>传家宝:{{ s }}</p>
<Sun>我是孙组件</Sun>
</div>
</template>
<script>
import { inject } from 'vue'
// 导入子组件 Sun
import Sun from './Sun.vue'
export default {
// 注册子组件 Sun
components: {
Sun
},
setup () {
// 通过 inject 接收 父组件传过来的值(父传子)
const s = inject('rootMsg')
return { s }
}
}
</script>
父传孙:孙组件
inject
<template>
<div>
<p>我是孙子组件</p>
<p>传家宝:{{ s }}</p>
</div>
</template>
<script>
import { inject } from 'vue'
export default {
// 通过 inject 接收父组件传过来的值 (父传孙)
setup () {
const s = inject('rootMsg')
return { s }
}
}
</script>
4、v-model
双向传值
- 父传子
- 父组件在模板中通过
v-model="prop"
传递值给子组件 - 子组件通过
props
对象接收一个对象,固定值modelValue:{}
- 在子组件的模板中 使用
modelValue
- 父组件在模板中通过
- 子传父
- 子组件在特定时期,通过
context.emit('update:modelValue',实参)
,更新父组件的prop
- 子组件在特定时期,通过
父组件:父传子
<template>
<div>
<p>我是父组件==={{count}}</p>
<button @click="fn">按钮</button>
<!-- 使用子组件 -->
<Son v-model="count"></Son>
</div>
</template>
<script>
// 导入子组件
import Son from './components/Son.vue'
import { ref } from 'vue'
export default {
// 注册子组件
components: {
Son
},
setup () {
// 准备父传子的值
const count = ref(0)
const fn = () => {
count.value++
}
return { fn, count }
}
}
</script>
子组件:子传父
<template>
<div>
<p>我是子组件==={{modelValue}}</p>
<button @click="fn">按钮</button>
</div>
</template>
<script>
export default {
// 接收父传子的值
props: {
modelValue: { // modelValue 为固定关键字
type: Number,
default: 0
}
},
setup (props, { emit }) {//解构过的
// 子改变父传过来的值
const fn = () => {
emit('update:modelValue', 20)
}
return { fn }
}
}
</script>