组件传值

组件传值是组件中的重要知识点,一般分为父组件向子组件传值、父组件向子组件传递方法以及子组件向父组件传值。

父组件向子组件传值

本节讲解父组件向子组件传数据,需先声明组件,代码如下。

<div id="app" v-cloak>
    <com1></com1>
</div>

<script>
    var com1 = {
        template: '<h1>组件传值</h1>'
    };

    var vm = new Vue({
        el: '#app',
        data: {
            // 父组件的msg传到子组件com1中
            msg: 'Hello World'
        },
        methods: {},
        components: {
            com1
        }
    });
</script>
html

代码解析如下。

在 vm 实例中声明 com1 私有组件,我们可以把 vm 实例对象看成父组件,同时把 com1 看成子组件,需求是把 vm 实例 data 中的 msg 属性传递给子组件 com1。

父组件向子组件传值需要两步。

  1. 把数据通过 v-bind 自定义属性传递给子组件。

  2. 子组件中使用 props 接收自定义属性,代码如下。

视图层代码如下。

<div id="app" v-cloak>
  <!-- 使用v-bind绑定自定义属性,属性值就是传递的数据 -->
  <com1 :sendmsg="msg"></com1>
</div>
html

Vue 实例代码如下。

<script>
  var com1 = {
    template: '<h1>组件传值 -- {{ sendmsg }}</h1>',
    // 使用props接收自定义属性中的数据
    props: ['sendmsg']
  };

  var vm = new Vue({
    el: '#app',
    data: {
      // 父组件的msg传到子组件com1中
      msg: 'Hello World'
    },
    methods: {},
    components: {
      com1
    }
  });
</script>
html

代码解析如下。

  • 使用 v-bind 绑定自定义属性,属性值就是传递的数据。

  • 使用 props 接收组件自定义属性中的数据。

扩展

子组件中接收数据的方法有两种:一种是数组形式,一种是对象形式。以对象形式接收数据的代码如下。

<script>
  var com1 = {
    template: '<h1>组件传值 -- {{ sendmsg }}</h1>',
    // 使用 props 接收自定义属性中的数据
    props: {
      // 对象形式
      sendmsg: {
        // 传递的数据类型
        type: String
      }
    }
  };
</script>
html

代码解析如下。

使用对象形式须注意接收的数据类型。

父组件向子组件传递方法

案例需求:在父组件中定义 show 方法,在子组件中定义按钮,单击子组件中的按钮,调用父组件中的 show 方法,基础代码如下。

视图层代码如下。

<div id="app" v-cloak>
    <!-- 视图层显示 com1 组件 -->
    <com1></com1>
</div>

<!-- com1 组件的 HTML 代码 -->
<template id="temp">
    <div>
        <input type="button" value="子组件中的按钮">
    </div>
</template>
html

Vue 实例代码如下。

<script>
    // com1 组件
    var com1 = {
        template: '#temp',
        data() {
            return {
                c_msg: '子组件内容'
            }
        },
        methods: {}
    }

    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'Hello World'
        },
        methods: {
            // 父组件中的 show 方法
            show() {
                console.log('父组件中的方法');
            }
        },
        components: {
            com1
        }
    })
</script>
html

要实现父组件向子组件传递方法,同样需要两个步骤。

  • 把父组件中的 show 方法,通过 v-on 自定义事件传递给子组件。

  • 在子组件中通过 this.$emit() 触发父组件中的方法,代码如下。

视图层代码如下。

<div id="app" v-cloak>
  <com1 @sendfn="show"></com1>
</div>

<template id="temp">
  <div>
    <input type="button" value="子组件中的按钮" @click="c_show">
  </div>
</template>
html

子组件代码如下。

<script>
  // com1 组件
  var com1 = {
    template: '#temp',
    data() {
      return {
        c_msg: '子组件内容'
      }
    },
    methods: {
      // 子组件定义自己的 c_show 方法,实际触发的是父组件传过来的方法
      c_show() {
        this.$emit('sendfn')
      }
    }
  }

  var vm = new Vue({
    el: '#app',
    data: {
      msg: 'Hello World'
    },
    methods: {
      // 父组件中的 show 方法
      show() {
        console.log('父组件中的方法')
      }
    },
    components: {
      com1
    }
  })
</script>
html

代码解析如下。

  • 通过 v-on 事件绑定把父组件方法传递给子组件。

  • 子组件通过 “this.$emit()” 触发父组件中的方法。

子组件向父组件传值

子组件向父组件传值有一个前提条件,即需要掌握上一节的知识点 “父组件向子组件传递方法” 。

把子组件数据传给父组件,有两个步骤。

  1. 在子组件中,this.$emit() 从第二个参数开始就是要传递的数据。

  2. 在父组件的方法中接收传递过来的数据,代码如下。

<div id="app" v-cloak>
  <com1 @sendfn="show"></com1>
</div>

<template id="temp">
  <div>
    <input type="button" value="子组件中的按钮" @click="c_show">
  </div>
</template>

<script>
  // com1 组件
  var com1 = {
    template: '#temp',
    data() {
      return {
        c_msg: '子组件内容'
      }
    },
    methods: {
      c_show() {
        // 1. this.$emit() 中从第二个参数开始就是要传递的数据,这里是把 c_msg 传递给父组件
        this.$emit('sendfn', this.c_msg)
      }
    }
  }

  var vm = new Vue({
    el: '#app',
    data: {
      msg: 'Hello World'
    },
    methods: {
      // 2. 使用形参接收子组件传递过来的数据
      show(data) {
        console.log('父组件中的方法---' + data) // 结果为“子组件内容”
      }
    },
    components: {
      com1
    }
  })
</script>
html

代码解析如下。

重点分为两个步骤。

  1. 在 this.$emit() 方法中传递数据。

  2. 在父组件方法中接收数据。

案例:子组件向父组件传递列表,父组件渲染列表,代码如下。

视图层代码如下。

<div id="app" v-cloak>
  <com1 @sendfn="show"></com1>
  <ul>
    <li v-for="(item, i) in list" :key="item.id">
      {{ item.id }}--{{ item.name }}
    </li>
  </ul>
</div>

<template id="temp">
  <div>
    <h1 @click="c_show">子组件</h1>
  </div>
</template>
html

逻辑代码如下。

<script>
  var com1 = {
    template: '#temp',
    data() {
      return {
        c_msg: '子组件内容',

        // 1. 在子组件中创建列表
        c_list: [{
            id: 1,
            name: 'Vue'
          },
          {
            id: 2,
            name: 'PHP'
          },
          {
            id: 3,
            name: 'JAVA'
          }
        ]
      }
    },
    methods: {
      c_show() {
        // 2. 把 this.c_list 传递给父组件
        this.$emit('sendfn', this.c_list)
      }
    }
  }

  var vm = new Vue({
    el: '#app',
    data: {
      msg: 'Hello World',
      list: []
    },
    methods: {
      // 3. 在父组件中接收子组件传递的数据
      show(data) {
        console.log('父组件中的方法----' + data)
        // 4. 把数据挂载到父组件中的 data
        this.list = data
        console.log(this.list)
      }
    },
    components: {
      com1
    }
  })
</script>
html

代码解析如下。

重点分为 5 个步骤。

  1. 在子组件中创建列表。

  2. 把 this.c_list 传递给父组件。

  3. 在父组件中接收子组件传递的数据。

  4. 把数据挂载到父组件中的 data。

  5. 使用 v-for 渲染父组件中的数据。