vue3组件传值方式汇总

1.props(父传子)

需要使用defineProps方法接受父组件传递来的数据,defineProps是v3提供的方法,不需要要引入,直接使用。

父组件:
<template>
  <div class="father">
      <CHILD01 msg="Vite Vue" />
  </div>
</template>

<script setup lang="ts">
import CHILD01 from './components/CHILD01.vue'
</script>
子组件:
//ts
<template>
  <h1>{{props.msg}}</h1>
</template>

<script setup lang="ts">
interface IPROPS  {
    msg?:string
}
const props:IPROPS = defineProps(['msg'])
</script>

//js
<template>
  <h1>{{props.msg}}</h1>//或者直接msg 不用写props
</template>

<script setup>
 const props = defineProps(['msg'])
</script>

2.自定义事件

 1.子组件

需要使用defineEmits方法触发自定义事件,defineProps是v3提供的方法,不需要要引入,直接使用。

<template>
 <button  @click="handler">点我触发自定义事件</button>
</template>

<script setup lang="ts">
const $emit =defineEmits(['xxx'])
const handler=()=>{
 $emit('xxx','传来的数据1','传来的数据2')
</script>
父组件:
<template>
  <div class="father">
      <CHILD01 @xxx="handle" />
  </div>
</template>
<script setup lang="ts">
import CHILD01 from './components/CHILD01.vue'
const handle=(params1:string,params2:string)=>{
console.log(params1,params2)
}
</script>

<style scoped>
.father {
width: 1000px;
height: 400px;
background-color: red;
margin: 0 auto;
}
</style>

3.全局数据总线(任意组件)

需要安装插件mitt:mitt - npm 

src\bus.js

//引入mitt插件:mitt一个方法,方法执行会返回bus对象
import mitt from 'mitt';
const $bus = mitt();
export default $bus;

组件1:
<template>
  <div class="child01">
    <h4>子组件01</h4>
    <button @click="handler">点我给child02传值</button>
  </div>
</template>

<script setup lang="ts">
import $bus from "../bus";
const handler = () => {
  $bus.emit("car", { car: "奔驰" });
};
</script>

<style scoped>
.child01 {
  width: 400px;
  height: 100px;
  background-color: skyblue;
  margin: 0 auto;
}
</style>
组件2:
<template>
  <div class="child02">
    <h4>子组件02</h4>
    <span>{{ states.car }}</span>
  </div>
</template>

<script setup lang="ts">
import $bus from "../bus"; //组合式API函数
import { onMounted, reactive } from "vue";
const states=reactive({
  car:''
})
//组件挂载完毕的时候,当前组件绑定一个事件,接受将来兄弟组件传递的数据
onMounted(
  () => {
    $bus.on("car", (car: string) => {
      states.car=car
    });
  }
  //第一个参数:即为事件类型第二个参数:即为事件回调
);
</script>

<style scoped>
.child02 {
  width: 400px;
  height: 100px;
  background-color: purple;
  margin: 0 auto;
}
/* .read-the-docs {
  color: #888;
} */
</style>

4.v-model(父子)

1.绑定一个v-model

父组件
<template>
  <div class="father">
    <h1>v-model:{{ money }}{{ pageNo }}--{{ pageSize}}</h1>
    <input type="text" v-model="info">
     <!-- <CHILD01 :modelValue="money" @update:modelValue="handler"></CHILD01> -->
     <!--
      v-model组件身上使用
      第一:相当有给子组件传递props[ modelValue] = 10000
      第二:相当于给子组件绑定自定义事件update : modelValue-->
     <CHILD01 v-model="money"></CHILD01>
    <!-- 绑定多个v-model  -->
     <CHILD02 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></CHILD02>>
  </div>
</template>
<script setup lang="ts">
import CHILD01 from './components/CHILD01.vue' 
import CHILD02 from './components/CHILD02.vue' 
import {ref} from 'vue'
//v-model指令:收集表单数据,数据双向绑定 
// v-model也可以实现组件之间的通信,实现父子组件数据同步的业务
//父亲给子组件数据props
//子组件给父组件数据·自定义事件//引入子组件
let info = ref('');
//父组件的数据钱数
let money = ref (10000);
// const handler =(num:number) => {
//   //接受子组件数值 
//   money.value=num
// }
let pageNo=ref(0)
let pageSize=ref(3)
</script>

<style scoped>
.father {
width: 1000px;
height: 400px;
background-color: red;
margin: 0 auto;
}
</style>
子组件01
<template>
  <div class="child01">
    <h4>子组件01</h4>
    <div>钱:{{ modelValue }}</div>
    <button @click="handle">父子数据同步</button>
  </div>
</template>

<script setup lang="ts">
interface IPROPS  {
  modelValue:string
}
let props:IPROPS = defineProps(['modelValue'])
let $emit = defineEmits( [ 'update:modelValue' ]);
const handle =() => {
  // console.log(props)
  $emit('update:modelValue',props.modelValue + 1000);
}
</script>
<style scoped>
.child01 {
  width: 400px;
  height: 100px;
  background-color: skyblue;
  /* margin: 0 auto; */
}
</style>

2.绑定一个v-model 

子组件02
<template>
  <div class="child02">
    <h4>子组件02绑定多个v-model</h4>
    <button @click="$emit('update:pageNo',pageNo+1)">pageNo{{ pageNo }}</button>
    <button @click="$emit('update:pageSize',pageSize+1)">pageSize{{pageSize  }}</button>
    <span> </span>
  </div>
</template>

<script setup lang="ts">
defineProps(["pageNo", "pageSize"]);
let $emit = defineEmits([ 'update:pageNo' , 'update:pageSize'])
</script>
<style scoped>
.child02 {
  width: 400px;
  height: 100px;
  background-color: purple;
  margin: 0 auto;
}
/* .read-the-docs {
  color: #888;
} */
</style>

5.useAttrs 

父组件
<template>
  <div class="father">
    <H1>父组件</H1>
    <!-- <el-button type="primary" size="small" :icon="Edit">Primary</el-button>  -->
    <CHILD01
      type="primary"
      size="small"
      :icon="Edit"
      title="编辑按钮"
      @click="handle"
    ></CHILD01>
  </div>
</template>
<script setup lang="ts">
import CHILD01 from "./components/CHILD01.vue";
import { Edit } from "@element-plus/icons-vue";
const handle = () => {};
</script>

<style scoped>
.father {
  width: 1000px;
  height: 400px;
  background-color: red;
  margin: 0 auto;
}
</style>
子组件 
<template>
  <div class="child01">
    <h4>子组件01</h4>
    <el-button :="$attrs">Primary</el-button>
  </div>
</template>

<script setup lang="ts">
//接受父组件传递过来数据
// defineProps(["type ", "size", "icon"]);
//引入useAttrs方法:获取组件标签身上属性与事件 包括函数和自定义事件
import { useAttrs } from "vue";
//此方法执行会返回一个对象
let $attrs = useAttrs();
//万一用props接受title
let props = defineProps(["title"]);
// props 与useAttrs方法都可以获取父组件传递过来的属性与属性值
//但是props接受了,usekttrs方法就获取不到了
console.log($attrs);
</script>
<style scoped>
.child01 {
  width: 400px;
  height: 100px;
  background-color: skyblue;
  /* margin: 0 auto; */
}
</style>

会发现没有title了 

6.ref与$parent 

父组件
<template>
  <div class="father">
    <h1>父组件:{{ money }}</h1>
    <button @click="handle">找组件1借100</button>
    <hr />

    <CHILD01 ref="son"></CHILD01>
    <hr />
    <CHILD02 ref="dau"></CHILD02>
  </div>
</template>

<script setup lang="ts">
import CHILD01 from "./components/CHILD01.vue";
import CHILD02 from "./components/CHILD02.vue";
// ref:可以获取真实的DOM节点,可以获取到子组件实例vC
// $parent:可以在子组件内部获取到父组件的实例
import { ref } from "vue";
//父组件钱数
let money = ref(100000000);
let son = ref();
let dau = ref();

const handle = () => {
  money.value += 100;
  son.value.money += 100;//获取子组件的值
  son.value.ddd();
};
//对外暴露
defineExpose({ money });
</script>

<style scoped>
.father {
  width: 1000px;
  height: 400px;
  background-color: red;
  margin: 0 auto;
}
</style>
组件1 
<template>
  <div class="child01">
    <h4>子组件01</h4>
    <hr />
    <span>
      {{ money }}
    </span>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
let money = ref(666);
const ddd = () => {
  console.log("122");
};
//对外暴露
defineExpose({ money, ddd });//暴露数据给父组件

//父组件钱数
</script>
<style scoped>
.child01 {
  width: 400px;
  height: 100px;
  background-color: skyblue;
  /* margin: 0 auto; */
}
</style>
组件2
<template>
  <div class="child02">
    <h4>子组件02 {{ money }}</h4>
    <hr />
    <button @click="handle($parent)">点我父组件给我传100</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"; //儿子钱数
let money = ref(666);
const handle = ($parent) => {
  money.value += 100;
  $parent.money -= 100;//获取父组件的数据,子给父传值
};
</script>

<style scoped>
.child02 {
  width: 400px;
  height: 100px;
  background-color: purple;
  /* margin: 0 auto; */
}
/* .read-the-docs {
  color: #888;
} */
</style>

7.provide与inject 

父组件

<template>
  <div class="father">
    <h1>父组件{{ car }}</h1>
    <hr />
    <button @click="handle">点我改车</button>
    <CHILD01 ref="son"></CHILD01>

    <!-- <CHILD02 ref="dau"></CHILD02> -->
  </div>
</template>

<script setup lang="ts">
import CHILD01 from "./components/CHILD01.vue";
// import CHILD02 from "./components/CHILD02.vue";
//vue3提供provide(提供)与inject(注入),可以实现隔辈组件传递数据
import { ref, provide } from "vue";
let car = ref("法拉利");
//祖先组件给后代组件提供数据
//两个参数:第一个参数就是提供的数据key//第二个参数:祖先组件提供数据
provide("TOKEN", car);
const handle = () => {
  car.value = "bench";
};
</script>

<style scoped>
.father {
  width: 1000px;
  height: 400px;
  background-color: red;
  margin: 0 auto;
}
</style>

子组件

<template>
  <div class="child01">
    <h4>子组件01{{ car }}</h4>
    <CHILD02></CHILD02>
  </div>
</template>

<script setup lang="ts">
import CHILD02 from "../components/CHILD02.vue";
import { inject } from "vue";
let car = inject("TOKEN");
console.log(car);
</script>
<style scoped>
.child01 {
  width: 400px;
  height: 100px;
  background-color: skyblue;
  /* margin: 0 auto; */
}
</style>

孙子组件

<template>
  <div class="child02">
    <h4>子组件02:{{ car }}</h4>
    <button @click="handle">点我改车</button>
  </div>
</template>

<script setup lang="ts">
type car = object;
import { inject } from "vue";
let car = inject("TOKEN");
const handle = () => {
  car.value = "zixingche";
};
</script>
<style scoped>
.child02 {
  width: 400px;
  height: 100px;
  background-color: purple;
  /* margin: 0 auto; */
}
/* .read-the-docs {
  color: #888;
} */
</style>

 8.pinia

 见另一篇文章:vue3pinia使用-CSDN博客
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3中,组件传值方式和使用方法如下: 1. Props:父组件通过props向子组件传递数据。 ```html <!-- Parent Component --> <template> <ChildComponent :message="message" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, data() { return { message: 'Hello from parent' }; } }; </script> <!-- Child Component --> <template> <div>{{ message }}</div> </template> <script> export default { props: ['message'] }; </script> ``` 2. Emit:子组件通过emit向父组件传递数据。 ```html <!-- Parent Component --> <template> <ChildComponent @messageUpdated="handleMessageUpdated" /> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, methods: { handleMessageUpdated(message) { console.log(message); } } }; </script> <!-- Child Component --> <template> <button @click="updateMessage">Update Message</button> </template> <script> export default { methods: { updateMessage() { this.$emit('messageUpdated', 'Hello from child'); } } }; </script> ``` 3. Provide/Inject:祖先组件通过provide提供数据,后代组件通过inject来注入数据。 ```html <!-- Ancestor Component --> <template> <div> <ChildComponent /> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, provide() { return { message: 'Hello from ancestor' }; } }; </script> <!-- Child Component --> <template> <div>{{ message }}</div> </template> <script> export default { inject: ['message'] }; </script> ``` 4. Refs:父组件可以通过$refs来访问子组件,从而调用子组件的方法或获取子组件的数据。 ```html <!-- Parent Component --> <template> <div> <ChildComponent ref="childComponent" /> <button @click="getChildMessage">Get Child Message</button> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent }, methods: { getChildMessage() { const message = this.$refs.childComponent.message; console.log(message); } } }; </script> <!-- Child Component --> <template> <div>{{ message }}</div> </template> <script> export default { data() { return { message: 'Hello from child' }; } }; </script> ``` 这些是Vue 3中常用的组件传值方式和使用方法。根据具体情况,选择适合的方式来实现组件之间的数据传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值