美文网首页
vue组件之间的通信方式(二)

vue组件之间的通信方式(二)

作者: moofyu | 来源:发表于2020-03-19 13:54 被阅读0次

    data 和props

    • props常用于数据传递,子组件中不可以直接修改,这也是vue 单向数据流的特性
    • data在任何情况下改变,都能同步反应的view层

    怎么在子组件中改动props传递过来的数据呢?

      1. 利用data的动态性,将props数据存在data中,通过修改data数据更新视图
    props: ['msg'],
    data() {
      return { 
        myMsg: this.msg 
      }
    }
    
      1. 将props转存到计算属性computed中
    props:['msg']
    computed : {
       myMsg () {
           return this.msg;
       }
    }
    

    不过因为对象和数组是引用类型,指向同一个内存空间,所以不要通过computed来对父组件传递来的引用类型数据进行计算过滤,改变数据会影响到父组件的状态。

    $emit、$on 和 v-on

    子组件更新父组件数据

    • $on(eventName, callback) 监听事件, 第二个参数是回调函数,回调函数的参数为$emit传递的数据内容
    • $emit(eventName, [...arg]) 触发事件, 第二个参数会传递给on监听器的回调函数
    • v-on则是使用在父组件标签中的,可以对其子组件的$emit监听

    .sync 双向绑定

    v-model也是用于双向绑定的,上一节已经讲到。

    • .sync的功能是:子组件改变了 prop,会同步到父组件中所绑定。
    • 使用方式: <comp :foo.sync="bar"></comp>; 相当于:<comp :foo="bar" @update:foo="val => bar = val"></comp>
    • 当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:
      this.$emit('update:foo', newValue)

    举个栗子:

    • 父组件代码
    <template>
     <div>
       <certificate-input :p_model.sync='pname'>
       </certificate-input>
    </div>
    </template>
    import CertificateInput from '../common/CertificateInput.vue'
    export default {
        name: 'fathor',
        components: {
            CertificateInput 
        },
        data() {
          return {
                pname:""
        }     
    }
    
    • 子组件代码
    <template>
        <div>
          <input
                title="姓名"  
                v-model="name" 
                ></input>
          <span>{{address}}</span>
        </div>
    </template>
    <script>
        export default{
            name:'certificateInput',
            props:["p_model"],
    
            data(){
                return{
                    name:this.p_model,
                    address: ""
                }
            },
            watch:{
                p_model(val) { 
                    this.address = val;
                },
                name(val){
                    //设置监听,如果改变就更新 p_model
                    this.$emit('update:p_model', val)
                }
            }
        }
    </script>
    
    

    其它栗子:

    <!--常见的如饿了么组件中的:current-page.sync-->
    <el-pagination 
    layout="prev, pager, next" 
    :total="meta.total" 
    @current-change="load" 
    :current-page.sync="meta.current_page" 
    background>
    </el-pagination>
        
    <!--js部分:-->
    props: {
        meta: {
          type: Object,
          required: true,
        },
      },
    

    再如,饿了么组件Dialog:

    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
    

    与通过自定义事件(emit)从子组件向父组件中传递数据的区别?

    1. 在我们讲解sync的这一小节里, 自定义事件发生时候运行的响应表达式是:
      <son :foo="bar" v-on:update="val => bar = val"></son> 中的 "val => bar = val"
    2. 在二中的“通过自定义事件从子组件向父组件中传递数据” 里,自定义事件发生时候运行的响应表达式是:
      <Son v-on: eventYouDefined = "arg => functionYours(arg)" /> 中的 "arg => functionYours(arg)"

    对前者,表达式 val => bar = val意味着强制让父组件的数据等于子组件传递过来的数据, 这个时候,我们发现父子组件的地位是平等的。 父可以改变子(数据), 子也可以改变父(数据)

    对后者,你的functionYours是在父组件中定义的, 在这个函数里, 你可以对从子组件接受来的arg数据做任意的操作或处理, 决定权完全落在父组件中, 也就是: 父可以改变子(数据), 但子不能直接改变父(数据)!, 父中数据的变动只能由它自己决定

    相关文章

      网友评论

          本文标题:vue组件之间的通信方式(二)

          本文链接:https://www.haomeiwen.com/subject/hatlyhtx.html