vue3 属性传值和自定义事件(composition API属性和上下文对象)

1,385 阅读1分钟

属性传值的方式

1.组件内部 还是可以用vue2的语法,语法格式不变

//传递属性
:传给子组件的名字(自定义) = “对应定义在父组件的属性名”
//子组件中pops同样可以用对象进行属性验证
<script>
export default {
   props:["msg"], 
   setup(){}    
}
< /script>
<template>
  <div>
      {{msg}}
  </div>
</template>
    

//父组件:
    <Box :msg="n"></Box>

2.vue3组件内部组合式API setup中取属性值

//子组件
<script>
export default {
   props:["msg","count"],
   setup(props){
       let fn=()=>{console.log(props.msg,props.count)}
       //必须在组件中注册属性不然setup函数收不到数据
       return {fn}
   }    
}
< /script>
<template>
  <div>
     <p> {{msg}}</p>
      <button @click="fn">look</button>
  </div>
</template>
    
//父组件:
    <Box :msg="n" :count="200"></Box>

3.setup语法糖中获取属性值

//子组件
<script setup>
    import {defineProps} from "vue"
    //注意vue3.2之后的版本子组件中不用引入可以直接使用
    let obj=defineProps(["msg","count"])
    let fn=()=>{console.log(obj.msg,obj.count)}         
}
< /script>
<template>
  <div>
     <p> {{obj.msg}}</p>
      <button @click="fn">look</button>
  </div>
</template>
    

//父组件:
    <Box :msg="n" :count="200"></Box>

自定义事件

在vue2中组件内部接收外部数据语法

export default {
props:['msg'],
inject:['count'],//父级组件provide提供
methods:{
    fn(){
        this.$emit("xxx",传给父组件的参数)
    }
}
}

在vue3中setup函数中this不能访问

export default {
props:['msg'],
setup(props,ctx){
pops表示父组件给子组件的属性传值
ctx表示上下文对象,对象中包含vue官方提供的功能比如emit 和inject等
let fn=()=>{
        ctx.emit("xxx",传给父组件的参数)
    }
}
}
<template>
  <div class="app">
    <h1>父组件</h1>
    <box1 :msg='n' :num='x'></box1>
  </div>
</template>

<script>
import box1 from "./Box1.vue"
import {ref} from 'vue'
export default {
  components:{
    box1
  },
  setup() {
    let n = "子组件";
    let x = ref(6);
    return {n,x}
  },
};
</script>

<style lang="scss">
.app{
    width: 400px;
    height: 500px;
    background-color: blueviolet;
  }
</style>
<template>
   <div class="box1">
    <h1>{{obj.msg}}</h1>
   </div>
</template>

<script>
export default{
    props:['msg','num'],
    setup(props,ctx){
        console.log(props,6666);
        console.log(ctx,7777);
        //取出pops的所有属性作为obj对象的属性
        return {obj:{...props}}
    }
}
</script>

<style scoped>
.box1{
    width: 300px;
    height: 200px;
    background-color: gold;
}
</style>

image.png

在vue3中setup函数的语法糖,提供了defineEmits,可以用来定义事件的名字,3.2版本之后同样可以不用引入直接使用

<script setup>
vue3.2之后的版本子组件中不用引入可以直接使用
import { defineProps,defineEmits } from "vue";
let obj=defineProps(['msg'])
let emit = defineEmits();
</script>

案例

<script setup>
// 引入
import box1 from "./Box1.vue";
import { ref } from "vue";
let n = "子组件";
let x = ref(4);

let fg = (arg) => {
  x.value = arg;
};
</script>

<template>
  <div class="app">
    <h1>父组件</h1>
    <p>{{ x }}</p>
    <box1 :msg="n" @myevent="fg"></box1>
  </div>
</template>

<style scoped lang='scss'>
.app {
  width: 400px;
  height: 500px;
  background-color: blueviolet;
}
</style>
<template>
  <div class="box1">
    <h1>{{ obj.msg }}</h1>
    <p>{{ num }}</p>
    <button @click="add">让值自增</button>
  </div>
</template>

<script setup>
import { watch,ref } from "vue";
let obj = defineProps(["msg"]);
let emit = defineEmits();
let num = ref(4);
let add = () => {
  num.value++;
};
watch(num, () => {
  if (num.value == 6) {
    emit("myevent", "6ara 4ever");
  }
});
</script>

<style scoped>
.box1 {
  width: 300px;
  height: 200px;
  background-color: gold;
}
</style>

2.gif

vue3中组件使用v-model传值

vue3中一个组件中可以使用多个v-model传值,可以通过 emits 选项在组件上定义发出的事件。

//子组件
export default {
    // props 注册接受 自定义标签的 name和age 
    props:['name', 'age'],
    // emits 注册 接受自定义标签的 update:name 和 update:age 属性绑定的事件
    emits: ['update:name', 'update:age'],
    setup(props,context){
        setTimeout(() => {
          // 通过 emit 触发事件传递数据
          context.emit('update:name', 'new-name');
          context.emit('update:age', 100)
        })
    }
}
//父组件
<my-comp v-model:name="nameValue" v-model:age="ageValue" />

ps:事件名提供了自动的大小写转换,如果在子组件中触发一个以 camelCase (驼峰式命名) 命名的事件,你将可以在父组件中添加一个 kebab-case (短横线分隔命名) 的监听器。

setup语法糖案例

<script setup>
// 引入
import box1 from "./Box1.vue";
import { ref } from "vue";
let n = ref('6ara');
let x = ref(4);
</script>

<template>
  <div class="app">
    <h1>父组件</h1>
    <p>{{ x }}</p>
    <p>{{n}}</p>
    <box1 v-model:msg="n" v-model:num="x"></box1>
  </div>
</template>

<style scoped lang='scss'>
.app {
  width: 400px;
  height: 500px;
  background-color: blueviolet;
}
</style>
<template>
  <div class="box1">
    <h1>{{ obj.msg }}</h1>
    <p>{{ obj.num }}</p>
    <button @click="add">change</button>
  </div>
</template>

<script setup>
let obj = defineProps(["msg",'num']);
let emit = defineEmits();
let add=()=>{
    emit('update:msg','6ara 4ever');
    emit('update:num',6)
}
</script>

<style scoped>
.box1 {
  width: 300px;
  height: 200px;
  background-color: gold;
}
</style>

2.gif