vue组件的数据通信方式很多,本篇着重讲props/$emit,神助是v-model/.sync语法糖。
TL;DR
props/
e
m
i
t
是
父
子
组
件
最
常
用
的
通
信
方
式
,
而
v
−
m
o
d
e
l
、
.
s
y
n
c
只
是
其
语
法
糖
子
组
件
只
是
单
一
的
修
改
某
个
父
组
件
值
的
话
,
表
单
类
组
件
使
用
v
−
m
o
d
e
l
语
法
糖
子
组
件
只
是
单
一
的
修
改
某
个
父
组
件
值
的
话
,
非
表
单
类
组
件
使
用
s
y
n
c
语
法
糖
复
杂
逻
辑
还
是
老
老
实
实
p
r
o
p
s
/
emit是父子组件最常用的通信方式,而v-model、.sync只是其语法糖 子组件只是单一的修改某个父组件值的话,表单类组件使用v-model语法糖 子组件只是单一的修改某个父组件值的话,非表单类组件使用sync语法糖 复杂逻辑还是老老实实props/
emit是父子组件最常用的通信方式,而v−model、.sync只是其语法糖子组件只是单一的修改某个父组件值的话,表单类组件使用v−model语法糖子组件只是单一的修改某个父组件值的话,非表单类组件使用sync语法糖复杂逻辑还是老老实实props/emit
其实语法糖只是在父组件用的时候更加方便,而子组件该咋样还是咋样。
props/
e
m
i
t
子
组
件
想
要
显
示
父
组
件
的
数
据
,
就
p
r
o
p
s
。
子
组
件
想
要
改
变
父
组
件
的
数
据
,
就
emit 子组件想要显示父组件的数据,就props。 子组件想要改变父组件的数据,就
emit子组件想要显示父组件的数据,就props。子组件想要改变父组件的数据,就emit。
留意的点:
子组件props里定义的属性名和父组件里的一一对应,注意父组件使用属性的时候用羊肉串格式
父组件的监听事件名和子组件的触发事件名必须一模一样
子组件触发事件的时候,传过来的参数,父组件可以用$event接收
v-model语法糖
v-model是属性value和事件input的语法糖。
没有语法糖的时候,这样写
用v-model的话,父组件就可以少了监听事件,用起来更加方便
v-model的语法糖有其局限性:
适用于:触发事件返回的值 正是 属性要改的值,一般是单一属性。比如触发事件返回的值正好就是提title的新值
更多逻辑的话,就不适用了
更适用于:表单类的组件,因为属性和事件默认是value和input
当然特定情况下,可以修改v-model的默认属性,但可读性就不是很好。
export default {
name:'ListItem',
model:{
prop:'title',
input:'changeTitle'
}
}
复制代码
.sync语法糖
.sync这个语法糖,同样适用于触发事件返回的值 正是 属性要改的值,可读性要强一些,可以用于非表单类的组件。 .sync语法糖默认是 属性xxx和事件update:xxx
没有语法糖的时候,这样写
用.sync的话,父组件仍然可以少监听事件,用起来更加方便
sync的语法糖有其局限性:
适用于:触发事件返回的值 正是 属性要改的值,一般是单一属性。比如触发事件返回的值正好就是提title的新值
更多逻辑的话,就不适用了
更适用于:非表单类的组件
总结
props/
e
m
i
t
是
父
子
组
件
最
常
用
的
通
信
方
式
,
而
v
−
m
o
d
e
l
、
.
s
y
n
c
只
是
其
语
法
糖
子
组
件
只
是
单
一
的
修
改
某
个
父
组
件
值
的
话
,
表
单
类
组
件
使
用
v
−
m
o
d
e
l
语
法
糖
子
组
件
只
是
单
一
的
修
改
某
个
父
组
件
值
的
话
,
非
表
单
类
组
件
使
用
s
y
n
c
语
法
糖
复
杂
逻
辑
还
是
老
老
实
实
p
r
o
p
s
/
emit是父子组件最常用的通信方式,而v-model、.sync只是其语法糖 子组件只是单一的修改某个父组件值的话,表单类组件使用v-model语法糖 子组件只是单一的修改某个父组件值的话,非表单类组件使用sync语法糖 复杂逻辑还是老老实实props/
emit是父子组件最常用的通信方式,而v−model、.sync只是其语法糖子组件只是单一的修改某个父组件值的话,表单类组件使用v−model语法糖子组件只是单一的修改某个父组件值的话,非表单类组件使用sync语法糖复杂逻辑还是老老实实props/emit
其实语法糖只是在父组件用的时候更加方便,而子组件该咋样还是咋样。
代码
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>
复制代码
v-model代码
没有简写时候的代码
<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>
复制代码
.sync的代码
没有简写的时候
<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 不胜感激 !