ref实现父子组件之间通信

在此我们必须先明确知道什么是ref, ref 是 reference 引用 DOM操作进行父子通信,在vuejs 里面作者不建议进行DOM操作,把DOM操作都换成指令。
平时我们收集数据是通过v-model来的吧,举个简单的例子

<body>
    <div id="box">
        用户名:<input type="text" v-model="username">
        <hr>
        邮箱:<input type="text" v-model="email">
        <button id="btn" @click="saveMesg">查看数据</button>
    </div>

<script type="text/javascript">
        var vm = new Vue({
                    el: '#box',
                    data:{
                        username:'',
                        email:''
                    },
                    methods:{
                        saveMesg:function () {
                            console.log(this.email);
                            console.log(this.username);
                        }
                    },
                    components:{

                     }
                })
</script>

这样点击显示用户信息就能显示出输入框相应的数据,但能否不用v-model操作呢?是可以的,只要写成这样

 <div id="box">
        用户名:<input type="text" ref="username">
        <hr>
        邮箱:<input type="text" ref="email">
        <button id="btn" @click="saveMesg">查看数据</button>
    </div>

同时将方法改成

  methods:{
                        saveMesg:function () {
                            // console.log(this.email);
                            console.log(this.$refs);
                        }

这个this.refs包含了使用ref的dom结构 ![this.refs.png](https://upload-images.jianshu.io/upload_images/19871099-1b369d6d07704c57.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
我们可以通过这种方式获得输入框的值

 var vm = new Vue({
                    el: '#box',
                    data:{
                        username:'',
                        email:''
                    },
                    methods:{
                        saveMesg:function () {
                            // console.log(this.email);
                            var eamil=this.$refs.email.value;
                            var username=this.$refs.username.value;//找到值
                        }
                    },
                    components:{

                     }
                })

所以我们也就可以利用拿到了这个值做父子通信了。

<body>
    <div id="box">
        <p>父组件</p>
        <button @click="clickhandler">点我显示子组件信息</button>
        <p>显示子组件信息{{username}}</p>
        <son ref="username"></son>
    </div>

<script type="text/javascript">

    var son={
        data:function(){
          return  {sonMsg:''}
        },
        template:`<div>用户名:<input type="text" v-model="sonMsg"></div>`
    }
        var vm = new Vue({
                    el: '#box',
                    data:{
                        username:'',

                    },
                    methods:{
                        clickhandler:function(){
                            console.log(this.$refs.username.sonMsg);//子组件的实例
                        }
                    },
                    components:{
                        son
                     }
                })
</script>
</body>

经过很多次实验,不知道为什么很多都是undefined,所以只能将ref绑定在调用的时候,输入框还是要用v-model来监听数据的,只是找对应的值的时候比较复杂。

methods:{
                        clickhandler:function(){
                            this.username=this.$refs.username.sonMsg
                            // console.log(this.$refs.username.sonMsg);//子组件的实例
                        }
                    },
监听到子组件信息.png

,子组件如何给父组件传递信息呢?
那我们依旧还是利用事件的传递,在子组件添加一个按钮,点击后绑定一个事件

var son={
        methods:{
            clickHandle:function () {
                //子组件也提供了一个获取父组件
                console.log(this.$parent);
            }  
        },
        data:function(){
          return  {sonMsg:''}
        },
        template:`<div>用户名:<input type="text" v-model="sonMsg">
<button @click="clickHandle">儿子给父亲传递信息 </button>
</div>`
    }

点击按钮我们就可以看到打印的内容
,我们也可以拿到跟组件


el.png

我们可以在父组件定义一个回调函数,用于接受子组件传递过来的数据

  var vm = new Vue({
                    el: '#box',
                    data:{
                        username:'',
                        sonMsg:''
                    },
                    methods:{
                        sonCallBack:function(data){
                           this.sonMsg=data
                        },
                        clickhandler:function(){
                            this.username=this.$refs.username.sonMsg
                            // console.log(this.$refs.username.sonMsg);//子组件的实例
                        }

                    },
                    components:{
                        son
                     }
                })

子组件在负责把数据发送给父组件

 var son={
        methods:{
            clickHandle:function () {
                //子组件也提供了一个获取父组件
                // console.log(this.$parent);
                this.$parent.sonCallBack('来自子组件的数据哦',this.sonMsg)
            }  
        },
        data:function(){
          return  {sonMsg:''}
        },
        template:`<div>用户名:<input type="text" v-model="sonMsg">
<button @click="clickHandle">儿子给父亲传递信息 </button>
</div>`
    }

最后一起显示在页面上

<div id="box">
        <p>父组件</p>
        <button @click="clickhandler">点我显示子组件信息</button>
        <p>显示子组件信息{{username}}</p>
        <son ref="username"></son>
        <h1>子组件给父组件消息:{{sonMsg}}</h1>
    </div>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容