使用前提:vue
首先,咱们须要明确的是,子父组件之间通信,子组件是不能直接改变父组件的值的。(父组件是大佬,小弟不能改变大佬的值,可是父组件能够改变子组件的值)函数
做用:this
经过某种方式,子组件能够”直接“改变父组件的值。spa
场景:code
控制弹框的显示与关闭。在父组件中打开子组件弹框,而后在点击子组件中的按钮关闭弹框。component
方法:blog
1. 通常咱们子父传值的处理以下:ip
注意:子组件向父组件传值时,父组件中@changeVisibleState="changeVisible"中,方法名不要加括号!!!!@changeVisibleState="changeVisible()"
input
// 父组件 <template> <div class="parent-file"> <input type="button" value="打开子组件" @click="show"> <!-- 子组件插槽 --> <child @changeVisibleState="changeVisible" :visible="childShow"/> </div> </template> <script> import child from "./child" export default { data () { return { childShow: false } }, components: { child }, methods: { show(){ this.childShow = true; }, changeVisible (val) { this.childShow = val; } } } </script>
// 子组件 <template> <div class="child-file"> <input type="button" value="点我隐身" @click="doClose" v-show="visible"> </div> </template> <script> export default { props: [ 'visible' ], methods: { doClose () { this.$emit("changeVisibleState", false) } } } </script>
2. 改进:it
这样的写法没错,可是显的比较臃肿,明明我只是要改一个值,就不能简单点?
答案是,固然是能够的。
你们确定会想,那我不能直接改变父组件的值?想v-model那样,多爽。
vue也是考虑到了这点,因此提供了一个更好的解决方案
// 父组件 // 先把方法写到行内,箭头函数的写法。 // 方法名为何是update:visible,是下面子组件的emit方法定义的。 <template> <div class="parent-file"> <input type="button" value="打开子组件" @click="show"> <!-- 子组件插槽 --> <child @update:visible="(val)=>{ childShow = val }" :visible="childShow"/> </div> </template> <script> import child from "./child" export default { data () { return { childShow: false } }, components: { child }, methods: { show(){ this.childShow = true; }, // 以简化代码 // changeVisible (val) { // this.childShow = val; // } } } </script>
// 子组件 <template> <div class="child-file"> <input type="button" value="点我隐身" @click="doClose" v-show="visible"> </div> </template> <script> export default { props: [ 'visible' ], methods: { doClose () { // 修改前代码 // this.$emit("changeVisibleState", false) // 改变写法 this.$emit("update:visible",false); } } } </script>
3. 最后:
对于 @update:visible="(val)=>{childShow = val}" :visible="childShow",vue提供了一个语法糖,将其替换成 :visible.sync = "childShow" ,这样是否是看起来简洁多了。
那么就变成了:
// 父组件 <template> <div class="parent-file"> <input type="button" value="打开子组件" @click="show"> <!-- 子组件插槽 --> <child :visible.sync = "childShow"/> </div> </template> <script> import child from "./child" export default { data () { return { childShow: false } }, components: { child }, methods: { show(){ this.childShow = true; }, // 以简化代码 // changeVisible (val) { // this.childShow = val; // } } } </script>
// 子组件 <template> <div class="child-file"> <input type="button" value="点我隐身" @click="doClose" v-show="visible"> </div> </template> <script> export default { props: [ 'visible' ], methods: { doClose () { // 修改前 // this.$emit("changeVisibleState", false) // 改变写法 // 注意:emit中的函数名,必定要以这种格式"update:props"命名,其中props就是咱们子父之间通信的值 this.$emit("update:visible", false); } } } </script>