props

vue2里父组件传递数据给子组件,子组件通过props来接收,而vue3里依然如此,唯一不同的是在vue2里子组件接收数据后通过this[属性]来获取数据,而vue3则通过setup传递形参接收放在一个对象里,为了方便,形参默认就写props。如下例:父组件04-props.vue这个组件里传递给了子组件navbar两个数据,分别是myname="明哥"和myage=“27”,子组件navbar通过props接收后,在setup形参里接收使用,控制台可以看到是一个对象
请添加图片描述
请添加图片描述
代码如下:

//父组件04-props.vue
<template>
  <div>父组件向子组件通信 <navbar myname="明哥" myage="27"></navbar></div>
</template>

<script>
import navbar from "./components/navbar";

export default {
  components: {
    navbar,
  },
};
</script>

//子组件navbar.vue
<template>
  <div>我是子组件navbar.vue</div>
  <div>
    <button>left</button>
    姓名:{{ myname }} 年龄:{{ myage }}
    <button>right</button>
  </div>
</template>

<script>
export default {
  props: ["myname", "myage"],
  //vue2写法
  //   mounted(){
  //     console.log("获取父组件传过来的值",this.myname)
  //   },
  setup(props) {
    console.log("props", props, props.myname, props.myage);
  },
};
</script>

emit

刚刚我们学习了父传子,现在学习一下子传父。场景如下:子组件sidebar里有很多行11111数据,默认显示,想实现当我点击left按钮时让其隐藏。可以看到setup的第二个形参aaa在控制台打印出的是一个对象,里面就有我们熟悉的emit。通过这个emit我们就能进行子传父,代码和效果如下:
请添加图片描述
请添加图片描述
请添加图片描述
我们可以在控制台看到打印的aaa如下
请添加图片描述
为了方便,我们会利用解构赋值,直接在形参上写成{emit}而不是随便写一个形参aaa,补一个常见警告吧,如下图,我的控制台报Runtime directive used on component with non-element root node.
请添加图片描述
意思是自定义指令不能放到组件上,而是要放到自有的元素上,也就是这里用到的v-show不能放在自定义组件上,而是放在原来就有的标签上,所以这里套了一层div。
请添加图片描述
回到刚刚那里,我们在vue3里通过将{emit}作为setup的第二个形参,然后通过emit(方法名,参数),就能达到和vue2里通过this.$emit(方法名,参数)相同的传数据给父组件效果。由于我们在父组件04-props.vue里通过event接收子组件传过来的方法,所以我们这里写的是emit(“event”),当然,取别的方法名也是可以的, 如下图,最后就达到了我们要的效果,点击left按钮,一行行的11111数据隐藏不见了:
请添加图片描述
请添加图片描述
完整代码如下:

//父组件04-props.vue
<template>
  <div>
    <navbar myname="明哥" myage="27" @event="change"></navbar>
    <div v-show="obj.isShow">
      <sidebar></sidebar>
    </div>
  </div>
</template>

<script>
import navbar from "./components/navbar";
import sidebar from "./components/sidebar";
import { reactive } from "vue";
export default {
  components: {
    navbar,
    sidebar,
  },
  setup() {
    const obj = reactive({
      isShow: true,
    });
    const change = () => {
      obj.isShow = !obj.isShow;
    };
    return {
      obj,
      change,
    };
  },
};
</script>

//子组件navbar.vue
<template>
  <div>我是子组件navbar.vue</div>
  <div>
    <button @click="handleShow">left</button>
    姓名:{{ myname }} 年龄:{{ myage }}
    <button>right</button>
  </div>
</template>

<script>
export default {
  props: ["myname", "myage"],
  //vue2写法
  //   mounted(){
  //     console.log("获取父组件传过来的值",this.myname)
  //   },
  setup(props, { emit }) {
    // console.log("props", props, props.myname, props.myage);

    const handleShow = () => {
      // emit就等同于this.$emit
      emit("event");
    };
    return {
      handleShow,
    };
  },
};
</script>

//子组件sidebar.vue
<template>
  <div>我是子组件sidebar.vue</div>
  <div>
    <ul>
      <li>11111</li>
      <li>11111</li>
      <li>11111</li>
      <li>11111</li>
      <li>11111</li>
      <li>11111</li>
    </ul>
  </div>
</template>

<script>
export default {
  props: ["myname", "myage"],
  //vue2写法
  //   mounted(){
  //     console.log("获取父组件传过来的值",this.myname)
  //   },
  setup(props) {
    console.log("props", props, props.myname, props.myage);
  },
};
</script>

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐