最近在学习Vue,昨天的一个小项目中我遇到了一个需求:首页点击注册,注册为弹框组件,决定它显隐的是父组件data里的registerVisible值,我尝试在注册这个组件里点击提交按钮后,改变registerVisible的值为false,发现报错:
1 [Vue warn]: 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. Prop being mutated: "result" (found in component )
通过搜索了解到:
以前在Vue1.x中利用props
的twoWay
和.sync
绑定修饰符就可以实现props的双向绑定功能,但是在Vue2中抛弃了此功能,组件内不能修改props的值,同时修改的值也不会同步到组件外层,即调用组件方不知道组件内部当前的状态是什么,子组件修改父组件传过来的prop值的话就会报以上错误。
所以props双向绑定需要自己来实现,这里我用一个checkbox选择按钮的选取状态来举例:
需求:
点击checkbox 选择/取消 状态切换 不点击checkbox 也可通过子组件按钮来切换选取状态 步骤如下 1.在组件内的data对象中创建一个props属性的副本 1 2 3 4 5 6 7 8 9 10 11 12 Vue.component("togglebtn" , { template: "<button @click='change'>{{myChoose?'取消':'选择'}}</button>" , data: function ( ) { return { myChoose: this .choose }; }, props: [ "choose" ], ...... });
2.创建针对props属性的watch来同步组件外对props的修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Vue.component("togglebtn" , { template: "<button @click='change'>{{myChoose?'取消':'选择'}}</button>" , data: function ( ) { return { myChoose: this .choose }; }, props: [ "choose" ], watch: { choose(val) { this .myChoose = val; }, ...... }
3.创建针对props副本的watch,通知到组件外 1 2 3 4 5 6 < div id="app"> < input id="checkbox" type="checkbox" checked="checked" @click="change"> < br/> < togglebtn :choose="choose" @on-choose-change="onChooseChange" /> < /div>
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 Vue.component("togglebtn" , { template: "<button @click='change'>{{myChoose?'取消':'选择'}}</button>" , data: function ( ) { return { myChoose: this .choose }; }, props: [ "choose" ], watch: { choose(val) { this .myChoose = val; }, myChoose(val){ this .$emit("on-choose-change" ,val); } }, methods: { change() { this .myChoose = !this .myChoose; } } });
完整代码如下 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 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Document</title > </head > <body > <div id ="app" > <input id ="checkbox" type ="checkbox" checked ="checked" @click ="change" > <br /> <togglebtn :choose ="choose" @on-choose-change ="onChooseChange" /> </div > <script src ="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js" > </script > <script > Vue.component("togglebtn" , { template: "<button @click ='change' > {{myChoose?'取消':'选择'}} </button > ", data: function () { return { myChoose: this .choose }; }, props: [ "choose" ], watch: { choose(val) { this .myChoose = val; document .getElementById('checkbox' ).checked = val }, myChoose(val){ this .$emit("on-choose-change" ,val); } }, methods: { change() { this .myChoose = !this .myChoose; } } }); new Vue({ el: "#app" , data: function () { return { choose: true } }, methods: { change() { this .choose = !this .choose; }, onChooseChange(val){ this .choose=val; } } }); </script > </body > </html >
最后更新时间:2020-06-30 23:59:02 当前页访问次数 10