react都这么无情了,vue仍是那么有义,4种父子组件数据双向传递大法

本来想放张老尤的照片的,烧三根香膜拜一下的,惋惜图片和不上去,在前端这么mmp的时代,每天有那么多B事,在数据驱动的时候,你们都推崇数据的走向都是单向数据流,都是经过父组件去向子组件传递数据,仍是那句话,那来这么多B事,只要注意点就能够了,合理的运用双向绑定,不管对业务和组件开发来讲,都是一件共赢的事,装B能够,可是不能过份!前端

好了,讲重点,今天我就给你们讲讲VUE四种数据双向传递有那些用法vue

一.经过$on , $emit 来进行双向通讯

使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件vuex

这种用法,实际上是我接下来三种用法的根基bash

先来讲说$on 是用来干麻的,是用来监听的事件的,就是监听$emit里(eventName)事件的,一量$emit触发事件,则$on会接收到,则执行函数事件函数

那咱们基本数据单向传递咱们都用props来进行传递,那一旦子组件想改变props传过来的数据,咱们是不能直接改变Props里的数据,咱们仍是要改变父组件的数据,用$on和$emit是如何实现的呢ui

children组件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") {{msg}}
</template>


<script>
export default {
  props: ['msg'],
  methods: {
    changePropsValue () {
      this.$emit('changeMsg', '经过$emit触发事件了')
    }
  }
}
</script>复制代码

1.msg是经过父组件传递过来的,咱们先前可确定要在props里声明好
2.在点击的时候,咱们触发了changeMsg事件,第二个参数是,你想要传到父组件的参数this

parent组件

<template lang="pug">
  div
    demo(:msg="msg" v-on:changeMsg='onChange')
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '首次数据传递'
    }
  },
  components: {
    Demo
  },
  methods: {
    onChange (msg) {
      this.msg = msg
    }
  }
}
</script>复制代码

咱们随后把demo引入,传入子组件的msg咱们事先在data数据里面定义好,同时在demo组件上进行一个$on的监听
1.$on :(冒号)后面跟的第一个值是$emit触发的事件,也是$on所要监听的事件,一量$emit有触发,则立刻执行了onChange函数,但本质上vue仍是单向数据流的,虽然props不能改变,可是data里的数据是能够进行改变的,一但data的数据和子组件有传递关系,一旦父data数据有变更,子组件props所对应的数据则同时跟着变更spa

二.经过 v-model 来进行双父子通讯

在vue进入到2.0的时候,取消了.sync的功能,致使了一堆组件库大动脑子,基本都用了v-model去进行双向绑定,本质上v-model适用场景是用在表单上面的,可是既然能够自定义了,那就有它的灵活性设计

官方说法:

自定义事件能够用来建立自定义的表单输入组件,使用 v-model 来进行数据双向绑定。看看这个:input v-model="something"双向绑定

那语法糖则是这样的

input
v-bind:value="something"
v-on:input="something = $event.target.value"

这说明了

1.v-model里的something这个变量值在语法糖里表明的是value值,在表单上咱们能够看做是input的value值,那在其它标签能够当作一个将要传入的Props数据,那惟一不可变的是这个props的Key必须是value
2.v-on:input="something = $event.target.value"
其实v-model内置也是经过$on和$emit来进行传递的,进行了input输入事件的监听,而后拿到事件上$event.target.value最新的改变something

如今老版本的组件库,当2.0取消.sync的时候,自定义组件的时候,如何巧用v-model来进行双向通讯

children组件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") {{value}}
</template>


<script>
export default {
  props: ['value'],
  methods: {
    changePropsValue () {
      this.$emit('input', '经过$emit触发input事件了')
    }
  }
}
</script>复制代码

1.这里的value前面说过了就是v-model传过来的value ( v-bind:value="something"),可是只能用value去接收
2.这里主要巧用了一点,平时咱们改变input输入框的时候,input事件是本身主动触发的,可是,咱们也同时能够给他手动触发,咱们用$emit进行了手动触发(input)事件

parent组件

<template lang="pug">
  div
    demo(v-model ='msg')
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '首次数据传递'
    }
  },
  components: {
    Demo
  }
}
</script>复制代码

这个咱们直接用v-model像表单那样绑定就直接能够进行父子组件双向绑定了。在v-model的语法糖里封装了v-on:input 去进行监听事件

3.在2.3回归的特性.sync

回归的.sync与1.0版本的写法有所改变,改来改去,不离其实中,仍是要经过$emit去显式地触发一个更新事件;

可是相比v-model来讲语法上更加直观,更加简洁,毕镜v-model是主要给表单进行又向绑定适用的

若是再进一步往底层说,.sync仍是进行了$on进行了监听封装,跟v-model同样也一样是一种语法糖

children组件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") {{msg}}
</template>


<script>
export default {
  props: ['msg'],
  methods: {
    changePropsValue () {
      this.$emit('update:msg', '经过$emit显示触发了更新事件')
    }
  }
}
</script>复制代码

1.经过props来进行msg的数据接收
2.经过$emit来进行触发,第一个参数则是显示触发,update:msg (msg)则是你须要改变的props里从父组件里接收的值,第二个参数,仍是你要更新的值,从语意上设计的也颇有感受,有木有

parent

<template lang="pug">
  div
    demo(:msg.sync="msg")
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '首次数据传递'
    }
  },
  components: {
    Demo
  }
}
</script>复制代码

主要看demo(:msg.sync="msg") 这里直接在向子组件传递的时候仍是像1.0的时候加一个.sync,本质上仍是它会被扩展为一个自动更新父组件属性的 v-on 侦听器
(推荐用法,通常对一个模态框进行封装的时候颇有用,有了.sync不建议用v-model)

4.$parent用法

这在一些显示操做的时候,向外部暴露props和event的时候是不推荐用的,那有人要问了$$parent何时用呢,在一些本身内部逻辑操用的时候能够用一下,不用很繁琐的来进行双向来回导,节省代码和逻辑,有时候也可让人一目了然

children组件

<template lang="pug">
  .demo
    .demo-example(@click="changePropsValue") 点击按钮
</template>


<script>
export default {
  methods: {
    changePropsValue () {
      this.$parent.msg = '经过$parent显改变了更新事件'
    }
  }
}
</script>复制代码

1.子组件,经过点击按钮,显示的改变了父组件的parent.msg里面的数据

parent

<template lang="pug">
  div
    demo
    p {{msg}}
</template>

<script>
import Demo from './demo.vue'
export default {
  data () {
    return {
      msg: '第一次写入数据'
    }
  },
  components: {
    Demo
  }
}
</script>复制代码

在这种四种方法里,我仍是推荐用.sync来进行双向通讯,一量旦通讯机制深了,组件的嵌到超过3层的话,我仍是建议用vuex来进行数据的共享,否则一层一层传,再一层一层的向上导,到最后你页面会把控不住,业务代码也就不直观了

相关文章
相关标签/搜索