Vue--组件间通信

组件间通信方式

组件间通信方式有三种:

  • props  父组件向子组件传递数据
  • $emit  自定义事件(子组件向父组件传递数据)
  • slot  插槽分发内容

组件间通信要遵循以下的规则:

  • 不要在子组件中直接修改父组件传递的数据
  • 数据初始化时,应当看初始化的数据是否用于多个组件中,如果需要被用于多个组件中,则初始化在父组件中;如果只在 一个组件中使用,那就初始化在这个要使用的组件中。
  • 数据初始化在哪个组件,更新数据的方法(函数) 就应该定义在哪个组件。

props向子组件传递数据

1.在声明组件对象中使用props选项指定

const MyComponent = {
    template: `<div></div>`,
    props: 此处值有以下三种方式,
    components: {
    }
}

方式一:指定传递属性名,注意是数组形式。

props: ['id','name''salary', 'isPublished', 'commentIds', 'author', 'getEmp']

方式二:指定传递属性名和数据类型,注意是对象形式。

props: {
   id: Number,
   name: String,
   salary: Number,
   isPublished: Boolean,
   commentIds: Array,
   author: Object,
   getEmp: Function
}

方式三:指定属性名,数据类型,必要性,默认值

props: {
   name: {
      type: String,
      required: true,
      default: 'zou'
    }
...... }

2.在引用组件时,通过v-bind动态赋值

<my-component v-bind:id="2" :name="meng" :salary="9999" :is-published="true" :comment-ids="[1, 2]"
:author="{name: 'alan'}" :get-emp="getEmp" >
</my-component>

先来看看父组件的内容

;(function () {
    const template = `<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
        
        // 通过 v-bind把父组件的内容传给子组件 ,:前面的名称可以自定义,为了方便理解,一般和传递的变量名一样
        <dashboard :hobbies="hobbies" @delete_hobby="deleteHobby"></dashboard>


      </div>`

    window.AppHome = {
        template, // template: template,

        data () { // 定义父组件往子组件里传的内容
            return {
                hobbies: ['coding', '睡觉', '打豆豆', '看书'],
                
            }
        },


        components: { //Dashboard ,HomeList 作为AppHome 的子组件
            Dashboard, // Dashboard: Dashboard
            HomeList // HomeList:HomeList
        }
    }
})()

这样父组件就写好了,在来看看子组件的内容

;(function () {
    const template = `<div class="row placeholders">

    // 在子组件中使用父组件传过来的数据
      <div v-for="(hobby, index) in hobbies" :key="index" class="col-xs-6 col-sm-3 placeholder">
        <h4>{{hobby}}</h4>  
        <span class="text-muted">
          <a href="#" @click="deleteHobby(index)">删除</a>
        </span>
      </div>
    
  </div>`

    window.Dashboard = {
      // 声明当前子组件接收父组件传递的属性
        props: ['hobbies'],
        
        template // template: template
    }
})()

上面的是使用方式一的方法传值,接下来看看方式二和方式三

父组件

;(function () {
    const template = `<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
// 往子组件home-list里传值 <home-list :empList="empList" :deleteEmp="deleteEmp"></home-list> </div>` window.AppHome = { template, // template: template, data () { // 定义父组件往子组件里传的内容 return { empList: [ {id: 1, name: '小1', salary: '80001'}, {id: 2, name: '小2', salary: '80002'}, {id: 3, name: '小3', salary: '80003'}, {id: 4, name: '小4', salary: '80004'}, {id: 5, name: '小5', salary: '80005'} ] } }, components: { //Dashboard,HomeList 作为AppHome 的子组件 Dashboard, // Dashboard: Dashboard HomeList // HomeList:HomeList } } })()

子组件HomeList

;(function () {
    const template = `<div class="table-responsive">
    <table class="table table-striped">
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>工资</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>

          <!-- 这里还有一个子组件Item -->
        <Item v-for="(emp, index) in empList" :key="emp.id" :emp="emp" :deleteEmp="deleteEmp" :index="index"/>
      </tbody>
    </table>
  </div>`
    
    window.HomeList = {
<!-- 声明当前子组件接收父组件传递的属性 -->
     
        props: {
          empList: Array,
          deleteEmp: Function
        },
        template, 
        components: { <!-- 子组件Item -->
          Item 
        }
    }
})()

子组件Item

;(function () {
    const template = `<tr>
    <td>{{emp.id}}</td>
    <td>{{emp.name}}</td>
    <td>{{emp.salary}}</td>
  </tr>`

  window.Item = {
      props: {
        emp: { // 指定属性名/数据类型/是否必须 
            type: Object,
            required: true
        },
        deleteEmp: Function,
        index: Number
      },

      template
  }
})()

自定义事件

在父组件中定义事件监听函数,并引用子组件标签上 v-on 绑定事件监听。

<!-- 通过  v-on 绑定 -->
<!-- @自定义事件名=事件监听函数 -->
<!-- 在子组件 dashboard中触发 delete_hobby 事件来调用 deleteHobby函数 -->

<dashboard @delete_hobby ="deleteHobby"></dashboard>

在子组件中触发父组件的监听事件函数调用

<!-- 子组件触发事件函数调用 -->
<!-- this.$emit(自定义事件名,data) -->
this.$emit("delete_hobby",name)

注意:

自定义事件只用于子组件向父组件发送数据

隔代组件或兄弟组件间通信此种方式不合适,使用 props 

案例

父组件

<!-- 父组件,其余的代码省略-->
<!-- @自定义事件名=事件监听函数 -->
<!-- 在子组件 dashboard 中触发了 delete_hobby 事件来调用 deleteHobby 函数  -->
<dashboard @delete_hobby="deleteHobby" :hobbies="hobbies"></dashboard>

<script>
  new Vue({
        data(){
            return {
                hobbies: ["吃饭","睡觉","打豆豆"]
                }
        
        },
        methods: {
            deleteHobby(){
            }
        }
  
   })

</script>

子组件

<!-- 子组件,其余的代码省略-->
<div @click="deleteHobby(index)"></div>

<script>
  new Vue({
        data(){
            return {
                
                }
        
        },
        prrops: ["hobbies"]
        methods: {
            deleteHobby(index){
            <!-- 触发父组件 delete_hobby 事件进行删除操作-->
                this.$emit('delete_hobby',index)
                
            }
        }
  
   })

</script>

 

posted @ 2019-12-29 20:30  邹邹很busy。  阅读(248)  评论(0编辑  收藏  举报