vue3组件通信(踩坑日记)(v3.2.25)

1,666 阅读1分钟

vue3组件通信(踩坑日记)(v3.2.25)

defineProps defineEmits withDefaults 这些函数不用再导入了。

  1. defineProps 是用来接收props的。注意接收来的属性最好不要直接解构!!!

    //bad 这样使用会断开响应式
    const { count } =  defineProps({
        count: {
            type: Number,
            required: true,
        },
    }); 
    ​
    //good
    const props =  defineProps({
        count: {
            type: Number,
            required: true,
        },
    }); 
    // 这样可以保持响应式,如果需要解构的话要使用toRefs,不使用toRefs的话,也可以直接使用props.count
    const { count } = toRefs(props);
    
    1. defineProps 两种写法,第一种传统的vue写法,限制类型并且设置默认值是否必须传入等。

      const { count } =  defineProps({
          count: {
              type: Number,
              required: true,
          },
      }); 
      const { count } = toRefs(props);
      
    2. 第二种ts写法, 借助 withDefaults来设置默认值,使用ts限制类型。

      const props = withDefaults(defineProps<{ count: number }>(), {
          count: 0,
      });
      const { count } = toRefs(props);
      
  2. defineEmits是用来触发自定义函数的相当于(v2)中的this.$emit()

  3. withDefaults 是用来配置属性默认值的。

1 第一种 使用传统的自定义函数来进行通信

// 父组件
<script setup lang="ts">
import { ref } from 'vue';
import Child from './components/Child.vue';
const count = ref(0);
const changeCount = (p:number) => {
    count.value = p;
}
</script><template>
     <Child :count="count" @changeCount ="changeCount"/>
</template>
// 子组件
<script setup lang="ts">
import { toRefs } from 'vue';
// 接收参数使用
const props = defineProps({
    count: {
        type: Number,
        required: true,
    },
});
​
const { count } = toRefs(props);
// 接收事件
const emmits = defineEmits(['changeCount']);
​
const change = () => {
     emits('changeCount', count.value++);
};
</script><template>
    <h1>{{ count }}</h1>
    <button @click="change">+1</button>
</template>
​
​

2 第二种 使用update进行通信

// 父组件
...
<template>
     <Child :count="count" @update:count ="changeCount"/>
</template>
// 子组件
<script setup lang="ts">
...
// 这样来接收事件
const emmits = defineEmits(['update:count']);
​
const change = () => {
     emits('update:count', count.value++);
};
</script>
​

3 第三种 使用v-model进行通信

// 父组件 这样写 子组件是第二种update的方式
...
<template>
     <Child v-model:count="count"/>
</template>

eslint 踩坑

如果使用了eslint可能会出现报错,

  1. 解决defineProps defineEmits withDefaults不引入直接使用会报错
  2. 解决v-model:count="count"报错'v-model' directives require no argument.(vue/no-v-model-argument)
env: {
    'vue/setup-compiler-macros': true,
},
rules: {
    'vue/no-v-model-argument': 'off',
 }