一、vuex 实现组件传值
父子,子子,祖孙
二、setup语法糖
<!-- 使用组件,通过 :自定义属性名="属性值" 的形式传递数据 --><!-- 属性值 是defineProps中的数据--><children :le="text" :list="list"></children>
情况一:父传子收
1、父组件传值
- 解构抛出
<template><div class="father"><h1>父组件</h1><span>{{text}}</span></div><div class="box"><children :le="text" :list="list"></children></div></template><script setup>// 引入import {reactive, toRefs,} from 'vue';// 引入组件import children from "./views/children";const data = reactive({text: '文字',list: [1, 2, 3, 4, 5]})// 解构抛出const {text, list} = toRefs(data)</script><style scoped>.father {width: 100%;height: 200px;background: red;}</style>
2、子组件
- 通过defineProps()可接收父组件传递的值;
- type属性定义接受的数据类型;
- default属性设置默认值,在当前属性没有值传入时使用;
<template><div class="box"><h1>子组件</h1><div>{{ le }}</div><div v-for="item in list">{{ item }}</div></div></template><script setup>// 引入import { defineProps } from 'vue';// 解构数据const { le, list } = defineProps({le: {type: String, // 接收的参数类型default: '默认文字', //默认值},list: {type: Array, // 接收的参数类型default: [], //默认值}})</script><style scoped>.box{width: 100%;height: 200px;background: #25A4BB;}</style>
情况二:子传父收
方法一 :defineEmits 需要点击
1、 子组件传值
- 调用defineEmits并定义要给父组件的方法,数组内可定义多个方法
- 第一个参数为要传递的事件名,第二个参数为要传递的值
<template><div class="box"><h1>子组件</h1><div>{{ le }}</div><button @click="giveFather">点击传值给父</button></div></template><script setup>// 引入defineEmitsimport { reactive, defineEmits } from 'vue';// 接收defineEmitsconst emits=defineEmits()const data = reactive({text: '文字',})function giveFather() {// 第一个参数为要传递的事件名,第二个参数为要传递的值emits('giveFather', data.text)}</script><style scoped>.box{width: 100%;height: 200px;background: #25A4BB;}</style>
2、父组件接收
- 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称)
- 等号后面的事件名称可自行定义
- 事件中通过默认参数接收使用子组件传递的值
<template><div class="father"><h1>父组件</h1><span>{{text}}</span></div><children @giveFather="receiveSon"></children></template><script setup>// 引入import {reactive, toRefs,} from 'vue';// 引入组件import children from "./views/children";const data = reactive({text: '',})function receiveSon(e) {// 通过默认参数接收使用子组件传递的值console.log(e);data.text = e}//解构数据const {text} = toRefs(data)</script><style scoped>.father {width: 100%;height: 200px;background: red;}</style>
方法二 :defineExpose
1、子组件
<template>{{ name }}</template><script setup>import { ref } from 'vue'const name = ref("张三")defineExpose({name});</script>
5、父组件
- children.value.name 必须在函数中
<template><child ref="children"></child><button @click="aaa"> 点击</button></template><script setup>import { ref } from 'vue'import child from './views/children'const children = ref(null)function aaa(){console.log(children.value.name)// "张三"// "我叫张三"}</script>
三、setup 函数方式
情况一:父传子收
方法一 利用props 刷新便可以传值
1、父组件 —通过 :自定义属性名=“属性值” 的形式传递数据
//父组件<template><div class="father"><h1>父组件</h1><span>{{text}}</span></div><div class="box"><children :le="text" :list="list"></children></div></template><script>// 引入import { reactive, toRefs, } from 'vue';// 引入组件import children from "./views/children";export default {name: 'app',// 注册组件components: {children},setup() {const data = reactive({text: '文字',list: [1, 2, 3, 4, 5]})return {// 解构抛出...toRefs(data),}}}</script><style scoped>.father{width: 100%;height: 200px;background: red;}</style>
2、 子组件接收
- props接受父传递的数据;
- type属性定义接受的数据类型;
- default属性设置默认值,在当前属性没有值传入时使用;
//子组件<template><div class="box"><h1>子组件</h1><div>{{ le }}</div><div v-for="item in list">{{ item }}</div></div></template><script>// 引入import { defineComponent } from 'vue';// 加上defineComponent()之后,可以获得vue2、vue3的自动提示---可有可无export default defineComponent({name: 'children',props: {le: {type: String, // 接收的参数类型default: '默认文字', //默认值},list: {type: Array, // 接收的参数类型default: []//默认值}},// props 是一个对象,包含父组件传递给子组件的所有数据。// context :上下文,包括 attrs 、 emit 、slots。setup(props, context) {console.log(props.le, props.list[0]);},})</script><style scoped>.box{width: 100%;height: 200px;background: #25A4BB;}</style>
方法二、 父组件中调用子组件的方法
1、父组件
<template><helloworld ref ="val"/>//在父组件中找到子组件的节点</template><script>import {reactive,ref} from "vue"import helloworld from "组件路径"export default {compoents:{helloworld},setup() {const val = ref()const p1 = reactive({name:"小宋",age:12})function btn(){//点击事件调用子组件的方法val.vlaue.receive(p1)}return{btn,val}}</script>
2、子组件
export default {name:"helloworld",setup(){//被父组件调用的方法function receive(val){console.log(val)}return{receive}}
情况二:子传父收
1、 子组件
- setup函数中ctx的emit用于传递事件给父组件
- 第一个参数为要传递的事件名,第一个参数为要传递的值
<template><div class="box"><h1>子组件</h1><button @click="giveFather">点击传值传给父</button></div></template><script>// 引入import { reactive, defineComponent } from 'vue';// 加上defineComponent()之后,可以获得vue2、vue3的自动提示export default defineComponent({name: 'child',// props 是一个对象,包含父组件传递给子组件的所有数据。// ctx :上下文,包括 attrs 、 emit 、slots。setup(props, ctx) {const data = reactive({text: '文字',})function giveFather() {// ctx中的emit用于传递事件给父组件// 第一个参数为要传递的事件名,第一个参数为要传递的值ctx.emit('giveFather', data.text)}return {// setup函数中定义事件需要抛出才能使用giveFather}},})</script><style scoped>.box{width: 100%;height: 200px;background: #25A4BB;}</style>
2、父组件接收
- 父组件中使用自定义事件接收,自定义事件名称必须与子组件传递的一致(即等号前面名称)
- 等号后面的事件名称可自行定义
- 事件中通过默认参数接收使用子组件传递的值
<template><div class="father"><h1>父组件</h1><div>{{ cont }}</div></div><div class="box"><children @giveFather="receiveSon"></children></div></template><script>// 引入import { reactive, toRefs, } from 'vue';// 引入组件import children from "./views/children";export default {name: 'app',// 注册组件components: {children},setup() {const data = reactive({cont: '',})function receiveSon(e) {// 通过默认参数接收使用子组件传递的值data.cont = e}return {// 解构抛出...toRefs(data),// 抛出事件receiveSon}},}</script><style scoped>.father{width: 100%;height: 200px;background: red;}</style>
情况三:祖传孙收
1、祖组件—-利用provide
//进入页面即刻传值<template><helloworld/></template><script>import {reactive} from "vue"import helloworld from "组件路径"export default {compoents:{helloworld},setup() {const p1 = reactive({name:"小宋",age:12})provide("p",p1)//祖传 第一个参数是子组件用来识别的参数}}//点击传值
2、子组件–inject
export default {name:"helloworld",setup(){const res = inject("p")//孙收}