0
点赞
收藏
分享

微信扫一扫

Vue.js子组件利用事件向父组件传输数据,以及sync修饰符和双向绑定


在Vue.js的组件中,prop是“单向绑定”的,数据只能从父组件传输到子组件。Vue文档中的说了这样做的原因:

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

用自定义事件向父组件发送数据

但是有时候的确需要由子组件从父组件获取更新的数据,这时候一个相对简单的方法就是——自定义事件。父组件监听事件,在事件的回调函数中得到数据。子组件emit事件,同时发送数据。

父组件

<template>
<div id="app">
<HelloWorld @click="clickData" />
<div> {{abc}} </div>
</div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
data() {
return {
abc: 123
}
},
methods: {
clickData (value) {
this.abc = value
}
},
};
</script>

子组件

<template>
<div class="hello">
<button @click="clickadd">按下</button>
</div>
</template>

<script>
export default {
name: 'HelloWorld',
methods: {
clickadd () {
this.$emit('click', '456')
}
}
}
</script>

按下按钮前:

Vue.js子组件利用事件向父组件传输数据,以及sync修饰符和双向绑定_双向绑定

按下按钮后:

Vue.js子组件利用事件向父组件传输数据,以及sync修饰符和双向绑定_双向绑定_02

123和456表示的是父组件中变量abc的值,子组件按下按钮时,调用了this.$emit,第一个参数表示时间名,第二个参数就可以传递想要发送到父组件的数据了。

父组件这边则在子组件的html标签上监听同名的事件(@click="clickData"),编写回调函数接收值并赋值给变量abc。

用自定义事件实现子组件prop双向绑定

更进一步,如果我们想改变传输到子组件的prop所绑定的父组件的变量,我们可以这样写:

父组件

<template>
<div id="app">
<HelloWorld :msg="abc" @update:msg="clickprop"/>
<div> {{ abc }} </div>
</div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
data() {
return {
abc: "123",
};
},
methods: {
clickprop(value) {
this.abc = value
}
},
};
</script>

子组件

<template>
<div class="hello">
<div id="demo" @click="clickadd">{{ msg }}</div>
</div>
</template>

<script>
export default {
name: 'HelloWorld',
inhertAttrs: true,
props: {
msg: {
type: String,
}
},
data: function() {
return {
}
},
methods: {
clickadd () {
this.$emit('update:msg', '456')
}
}
}
</script>

这样子组件和父组件的值会同时变化。按下上面的123之前:

Vue.js子组件利用事件向父组件传输数据,以及sync修饰符和双向绑定_自定义事件_03

按下上面的123之后:

Vue.js子组件利用事件向父组件传输数据,以及sync修饰符和双向绑定_双向绑定_04

值456首先通过emit传递到了父组件,再被赋值给了父组件变量abc,再通过子组件绑定的prop传递回父组件,最终同时变化成功。这样也算实现了“双向绑定”。

使用.sync修饰符简化双向绑定代码

代码中的事件名“update:msg”仅仅是一个名字而已,不和prop名相同也可以。但是如果我们保持与prop名相同,Vue为上面的代码提供了一个简写的形式:使用.sync操作符。使用它,事件名固定为了“update:prop名”的形式,我们也不需要自己写回调函数和绑定事件的代码了。

父组件

<template>
<div id="app">
<HelloWorld :msg.sync="abc" />
<div> {{ abc }} </div>
</div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
data() {
return {
abc: "123",
};
},
methods: {},
};
</script>

子组件

<template>
<div class="hello">
<div id="demo" @click="clickadd">{{ msg }}</div>
</div>
</template>

<script>
export default {
name: 'HelloWorld',
inhertAttrs: true,
props: {
msg: {
type: String,
}
},
data: function() {
return {
}
},
methods: {
clickadd () {
this.$emit('update:msg', '456')
}
}
}
</script>

这段代码与上一部分实现相同的效果。

可以看到,.sync修饰符仅仅起到一个简化作用而已。

举报

相关推荐

0 条评论