vue中的组件传值
出来工作有一段时间了,通过对项目不断了了解发现了一个vue的学习和项目中可谓重中之重的话题——组件传值。因为一个vue构建的项目中往往会用到非常多的公共组件,因此如何给这些组件传值就成了必须要掌握的一个技能。而在vue中组件传值无外乎分为三类:父组件->子组件,子组件->父组件,非父子关系组件传值。本文主要讨论前两种场景,文章也是出于自己的理解而写,如有不正确的地方希望大家帮忙修正。
父组件->子组件
传值方法:子组件声明 props 属性
实际开发场景会用到非常多的公共组件,而这些公共组件便是子组件,使用者为父组件。公共组件类似于一个方法,如果想起效果就需要给它传值,目前有2种传值方法,其原理都是基于 props 这个属性。
// 父组件app.vue <template> <div> <tab-bar v-bind:data="appData"> <!-- 这里的tab-bar是子组件 data这里指的是子组件会收到一个名为data的变量 appData是父组件中的变量,存放了需要发送的数据 --> <tab-bar/> </div> </template> <script> import Tabbar from "@components/TabBar" export default { data() { return { appData: "父组件发给子组件的数据" }; }, components: { Tabbar } }; </script>
// 子组件TabBar.vue <template> <div id="tabBar"> ... </div> </template> <script> export default { data() { return { ... } }, // 子组件中声明props,用于接收父组件传过来的数据 props: { // 这里的data就是父组件v-bind的data,名字必须一样 data: { type: String, default: () => "" } } } </script>
这是 props 实现父组件->子组件的一个模拟应用场景。值得一提的是,在子组件中声明的 props 内部的属性,可以看做在 data 中声明了同样名称的属性,即子组件想使用父组件传来的数据只需要 this.data 即可。
这是一个单向且动态的过程,用vue官方文档的话说:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
子组件->父组件
传值方法:this.$emit()
// 子组件Swiper.vue <template> <div id="swiper"> <button v-on:click="change">发送</button> </div> </template> <script> export default { data() { return { swiperData: "这是子组件的数据" } }, methods: { hasChange() { // change指的是父组件会收到一个方法名为change // swiperData指的是发送给父组件的数据 this.$emit("change", this.swiperData) } } } </script>
// 父组件App.vue <template> <div id="app"> <!-- 父组件使用v-on监听 这里的change必须要和子组件emit的第一个参数一样 --> <swiper v-on:change="fn" /> </div> </template> <script> import Swiper from "@components/Swiper" export default { data() { return { ... }; }, methods: { fn(data) { console.log(data); // 这里的data就是子组件传来的数据 } } }; </script>
v-model的使用
最开始接触的时候只了解它能实现双向数据绑定,但是不知道它还能用来组件之间传值。
v-model 实际上是简写了 v-bind 和 v-on,可以看成语法糖,其常用于 input,select 等表单控件。
<input type="text" v-model="data"> <!-- 等价于 --> <input type="text" :value="data" @input="data=$event.target.value">
也就是说,v-model 会默认绑定一个叫 value 的变量,同时也会监听表单控件的变化,例如 input 的输入事件,select 的 change 事件等。
// 父组件App.vue <template> <div id="app"> <a-tree v-model="data" /> </div> </template> <script> import ATree from "@components/ATree" export default { data() { return { data: "父组件中的数据" }; }, methods: { fn(data) { console.log(data); // 这里的data就是子组件传来的数据 } } }; </script>
// 子组件ATree.vue <template> <div id="atree"> <select name="atree" @change="hasChange"> <option value="0">AAA</option> <option value="1">BBB</option> <option value="2">CCC</option> </select> </div> </template> <script> export default { data() { return { aTreeData: "这是子组件的数据" } }, props: { value: { type: String, default: () => "" } }, methods: { hasChange() { // change指的是父组件会收到一个变量名为msg // aTreeData指的是发送给父组件的数据 this.$emit("change", this.aTreeData) } } } </script>
可以看出,v-model 不光可以实现双向数据绑定,同样也可以实现父子组件直接的双向数据传递,可以说是一举两得。
具体的 v-model 使用这里就不介绍了,大家可以参考官方文档

浙公网安备 33010602011771号