vue组件的数据通信方式很多,本篇着重讲props/$emit
,神助是v-model/.sync
语法糖。
v-model
语法糖sync
语法糖props/$emit
其实语法糖只是在父组件用的时候更加方便,而子组件该咋样还是咋样。
子组件想要显示父组件的数据,就props
。 子组件想要改变父组件的数据,就$emit
。
留意的点:
$event
接收v-model是属性value和事件input的语法糖。
没有语法糖的时候,这样写
用v-model的话,父组件就可以少了监听事件,用起来更加方便
v-model的语法糖有其局限性:
value
和input
当然特定情况下,可以修改v-model的默认属性,但可读性就不是很好。
export default { name:'ListItem', model:{ prop:'title', input:'changeTitle' } } 复制代码
.sync这个语法糖,同样适用于触发事件返回的值 正是 属性要改的值,可读性要强一些,可以用于非表单类的组件。 .sync语法糖默认是 属性xxx和事件update:xxx
没有语法糖的时候,这样写
用.sync的话,父组件仍然可以少监听事件,用起来更加方便
sync的语法糖有其局限性:
v-model
语法糖sync
语法糖props/$emit
其实语法糖只是在父组件用的时候更加方便,而子组件该咋样还是咋样。
List.vue
<template lang="pug"> //- 父组件 div //- item就是传递给ListItem的数据,属性是info //- clickLike,就是监听ListItem的clickLike事件 list-item(v-for="(item,index) in list" :key="index" :info="item" v-on:clickLike="change(item,$event)") </template> <script> import ListItem from "@/components/ListItem"; export default { name: "List", components: { ListItem }, data() { return { list: [ { title: "vue3来了", collects: 20 }, { title: "怜怜来了", collects: 2000 } ] }; }, methods: { // 当clickLike事件发生的时候,执行此方法 // 这里的event是ListItem传过来的值 change(item, event) { item.collects = event; } } }; </script> 复制代码
DetailItem.vue
<template lang="pug"> //- 子组件 div h2 {{info.title}} span 喜欢数 {{info.collects}} div button(@click="addCollect") 喜欢 hr </template> <script> export default { name: "ListItem", props: { // 这里定义父组件传过来的属性 info: { type: Object, default: () => ({}) } }, methods: { addCollect() { // 触发此组件的clickLike时间,并且传一个值给父组件 this.$emit("clickLike", this.info.collects + 1); } } }; </script> 复制代码
没有简写时候的代码
<template lang="pug"> //- 父组件 div list-item(:value="title" v-on:input="change") </template> <script> import ListItem from "@/components/ListItem"; export default { name: "List", components: { ListItem }, data() { return { title: "怜怜来了" }; }, methods: { // 当clickLike事件发生的时候,执行此方法 // 这里的event是ListItem传过来的值 change(event) { this.title = event; } } }; </script> 复制代码
<template lang="pug"> //- 子组件 div {{value}} button(@click="changeTitle") 修改标题 </template> <script> export default { name: "ListItem", props: { value: { type: String, default: "" } }, methods: { changeTitle() { this.$emit("input", "换标题啦"); } } }; </script> 复制代码
简写时候的父组件代码
<template lang="pug"> //- 父组件 div list-item(v-model="title") </template> <script> import ListItem from "@/components/ListItem"; export default { name: "List", components: { ListItem }, data() { return { title: "怜怜来了" }; } }; </script> 复制代码
没有简写的时候
<template lang="pug"> //- 父组件 div list-item(:theme="title" v-on:update:theme="change") </template> <script> import ListItem from "@/components/ListItem"; export default { name: "List", components: { ListItem }, data() { return { title: "怜怜来了" }; }, methods: { // 当clickLike事件发生的时候,执行此方法 // 这里的event是ListItem传过来的值 change(event) { this.title = event; } } }; </script> 复制代码
<template lang="pug"> //- 子组件 div {{theme}} button(@click="changeTitle") 修改标题 </template> <script> export default { name: "ListItem", props: { theme: { type: String, default: "" } }, methods: { changeTitle() { this.$emit("update:theme", "换标题啦"); } } }; </script> 复制代码
简写的时候,父组件的代码
<template lang="pug"> //- 父组件 div //- list-item(:theme="title" v-on:update:theme="change") list-item(:theme.sync="title") </template> <script> import ListItem from "@/components/ListItem"; export default { name: "List", components: { ListItem }, data() { return { title: "怜怜来了" }; } // methods: { // // 当clickLike事件发生的时候,执行此方法 // // 这里的event是ListItem传过来的值 // change(event) { // this.title = event; // } // } }; </script> 复制代码
如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑
如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star: http://github.crmeb.net/u/defu 不胜感激 !
|