一、子组件需要修改props的值 在某些场景下,我们需要在子组件中修改props传进来的值,但是如果我们直接去修改props时,就会报错, Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. 提示我们使用data或者computed来拷贝props的值1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 //child.vue <template> <div> 子组件的内容:{{count}} <button @click="increment">增加</button> </div> </template> <script> export default { props:{ count:Number }, methods:{ increment(){ this.count++ } } } </script> //parent.vue <template> <div> 父组件的内容:{{parentCount}} <hr/> <child :count="parentCount"></child> </div> </template> <script> import child from '@/components/testCount' export default { components:{ child }, data(){ return{ parentCount:10 } } } </script>
使用data的值修改props的值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 //child.vue <template> <div> 子组件的内容:{{childCount}} <button @click="increment">增加</button> </div> </template> <script> export default { props:{ count:Number }, data(){ return{ childCount:this.count } }, methods:{ increment(){ this.childCount++ } } } </script> //parent.vue <template> <div> 父组件的内容:{{parentCount}} <hr/> <child :count="parentCount"></child> </div> </template> <script> import child from '@/components/testCount' export default { components:{ child }, data(){ return{ parentCount:10 } } } </script>
二、使用data和props实现组件双向绑定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 //child.vue <template> <div v-show="childIsShow"> 子组件内容 <button @click="close">X</button> </div> </template> <script> export default { props: { isShow: { type: Boolean, default: false } }, data() { return { childIsShow: this.isShow }; }, watch: { childIsShow(val) { this.$emit("changeShow", val); }, isShow(val) { this.childIsShow = val; } }, methods: { close() { this.childIsShow = false; } } }; </script> <style scoped> </style> //parent.vue <template> <div> 父组件的内容:{{showChild}} <div> <button @click="toggle">切换</button> </div> <hr> <child :isShow="showChild" @changeShow="handleChangeShow"></child> </div> </template> <script> import child from "@/components/testCount"; export default { components: { child }, data() { return { showChild: false }; }, methods: { toggle() { this.showChild = !this.showChild; }, handleChangeShow(val) { this.showChild = val; } } }; </script>
三、使用computed和props实现组件双向绑定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 //child.vue <template> <div v-show="childIsShow"> 子组件内容 <button @click="close">X</button> </div> </template> <script> export default { props: { isShow: { type: Boolean, default: false } }, computed:{ childIsShow:{ get:function(){ return this.isShow }, set:function(){ this.$emit('changeShow',!this.isShow) } } }, methods: { close() { this.childIsShow = false; } } }; </script> <style scoped> </style> <template> <div> 父组件的内容:{{showChild}} <div> <button @click="toggle">切换</button> </div> <hr> <child :isShow="showChild" @changeShow="handleChangeShow"></child> </div> </template> <script> import child from "@/components/testCount"; export default { components: { child }, data() { return { showChild: false }; }, methods: { toggle() { this.showChild = !this.showChild; }, handleChangeShow(val) { this.showChild = val; } } }; </script>
四、使用v-model实现组件双向绑定 前面两种方法使用data或者computed虽然实现了组件的双向绑定,但是在使用组件的是使用,必须用自定义事件来接收,显得不够优雅,而使用v-model的方式就显得非常简洁了。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 //child.vue <template> <div v-show="value"> 子组件内容 <button @click="close">X</button> </div> </template> <script> export default { props: { value: { type: Boolean, default: false } }, methods: { close() { this.$emit("input",!this.value) } } }; </script> <style scoped> </style> //parent.vue <template> <div> 父组件的内容:{{showChild}} <div> <button @click="toggle">切换</button> </div> <hr> <child v-model="showChild"></child> </div> </template> <script> import child from "@/components/testCount"; export default { components: { child }, data() { return { showChild: false }; }, methods: { toggle() { this.showChild = !this.showChild; }, handleChangeShow(val) { this.showChild = val; } } }; </script>