组件通信

1、父组件向子组件传递数据

在组件中,使用选项props来声明需要从父级接收到的数据。

props的值有两种方式:

方式一:字符串数组,数组中的字符串就是传递时的名称。

方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。

1、 props传字符串数组

props: ['cmovies', 'cmessage']
  <div id="app">
    <div>
      <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
    </div>
  </div>

  <template id="cpn">
    <div>
      <ul>
        <li v-for="items in cmovies">{{items}}</li>
      </ul>
      <h2>{{cmessage}}</h2>
    </div>
  </template>

  <script src="../js/vue.js"></script>

  <script>
    //父传子:props
    const cpn = {
      template: '#cpn',
      //这样数组的写法定义也可以
      props: ['cmovies', 'cmessage']
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello',
        movies: ['111', '222', '333', '444']
      },
      components: {
        cpn
      }
    })
  </script>

组件通信

2、 props传对象

1、类型限制 

props: {
        //1、类型限制
        //指定cmovies必须是数组类型
        cmovies: Array,
        //指定cmessage必须是String类型
        cmessage: String
    };

2、提供一些默认值以及必传值 

require为true的意思是别人用cpn这个组件的时候,必须传cmessage这个数据<cpn :cmessage="message"></cpn>,不传就报错
 required: true

props: {
        //2、提供一些默认值以及必传值
        cmessage: {
          //指定cmessage必须是String类型
          type: String,
          //指定cmessage的默认值
          default: '默认值',
          //require为true的意思是别人用cpn这个组件的时候,必须传cmessage这个数据<cpn :cmessage="message"></cpn>,不传就报错
          required: true
        }
    };

当类型是对象或者数组时,默认值必须是一个函数

cmovies: {
          type: Array,
          //default: ['默认值']//vue2.5.2以下可以
          //但是2.5.17以上会报错这是因为当类型是对象或者数组时,默认值必须是一个函数
          default() {
            return ['默认值'];
          }
          //validator可以自己做验证
        }

数据验证都支持那些数据类型:

组件通信

还可以自定义验证函数

组件通信

传对象的几种形式:

组件通信

 

具体例子如下:

  <div id="app">
    <div>
      <cpn v-bind:cmovies="movies" :cmessage="message"></cpn>
    </div>
  </div>


  <template id="cpn">
    <div>
      <ul>
        <li v-for="items in cmovies">{{items}}</li>
      </ul>
      <h2>{{cmessage}}</h2>
    </div>
  </template>

  <script src="../js/vue.js"></script>

  <script>
    //父传子:props
    const cpn = {
      template: '#cpn',
      //props: ['cmovies', 'cmessage'],这样数组的写法定义也可以
      props: {
        //2、提供一些默认值以及必传值
        cmessage: {
          //指定cmessage必须是String类型
          type: String,
          //指定cmessage的默认值
          default: '默认值',
          //require为true的意思是别人用cpn这个组件的时候,必须传cmessage这个数据<cpn :cmessage="message"></cpn>,不传就报错
          required: true
        },
        cmovies: {
          type: Array,
          //default: ['默认值']//vue2.5.2以下可以
          //但是2.5.17以上会报错这是因为当类型是对象或者数组时,默认值必须是一个函数
          default() {
            return ['默认值'];
          }
          //validator可以自己做验证
        }
      }
    };
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello',
        movies: ['111', '222', '333', '444']
      },
      components: {
        cpn
      }
    })
  </script>

组件通信

3、props中的驼峰标识

v-bind不支持驼峰,所以不要写cInfo,如果非要写cInfo,那绑定的时候用:c-info="info"不是:cInfo="info",如下面的childMyMessage

 <div id="app">
    <cpn :cinfo="info" :child-my-message="message"></cpn>
  </div>


  <!-- 定义子组件模板的时候最外层必须有一个根,所以必须要用div包起来-->
  <template id="cpn">
    <div>
      <ul>
        <li v-for="(value,key,index) in cinfo">{{value}}-{{key}}-{{index}}</li>
      </ul>
      <p>{{childMyMessage}}</p>
    </div>
  </template>

  <script src="../js/vue.js"></script>

  <script>

    const cpn = {
      template: '#cpn',
      props: {
        //注意 v-bind不支持驼峰,所以不要写cInfo,如果非要写cInfo,那绑定的时候用:c-info="info"不是:cInfo="info",,如下面的childMyMessage
        cinfo: {
          typeof: Object,
          default() {
            return {};
          }
        },
        childMyMessage: {
          typeof: String,
          default() {
            return "default;"
          }
        }
      }
    }

    const app = new Vue({
      el: '#app',
      data: {
        info: {
          name: 'Doe',
          age: 19,
          height: 1.65
        },
        message: 'hello'
      },
      components: {
        cpn
      }
    })
  </script>

组件通信

2、子组件向父组件传递数据

这个时候,我们需要使用自定义事件来完成。

自定义事件的流程

1、在子组件中,通过$emit()来触发事件。

$emit发射一个事件,事件的名称叫itemClick,发射事件的同时传递一个参数item。这个时候父组件需要监听这个事件
          this.$emit('itemclick', item)

<!--子组件模板-->
  <template id="cpn">
    <div>
      <button v-for="item in categories" @click="itemclick(item)">{{item.name}}</button>
    </div>
  </template>
  <script>
    //子组件
    const cpn = {
      template: '#cpn',
      data() {
        return {
          categories: [
            { id: 'aaa', name: '热门推荐' },
            { id: 'bbb', name: '手机数码' },
            { id: 'ccc', name: '家用家电' },
            { id: 'ddd', name: '电脑办公' }
          ]
        }
      },
      methods: {
        itemclick(item) {
          //要把点击了谁传递给父组件
          //1、$emit发射一个事件,事件的名称叫itemClick,发射事件的同时传递一个参数item。这个时候父组件需要监听这个事件
          this.$emit('itemclick', item)
        }
      }
    }
  </script>

 2、在父组件中,通过v-on来监听子组件事件

<!-- 

      v-on:itemClick用来监听子组件发射的itemClick事件

         因为这个事件不是浏览器的事件,所以不加括号不会传event,传的是发射事件的参数item

    -->

    <cpn @itemclick="cpnclick"></cpn>

<!--父组件模板-->
  <div id="app">
    <!-- 
      2、v-on:itemClick用来监听子组件发射的itemClick事件
         因为这个事件不是浏览器的事件,所以不加括号不会传event,传的是发射事件的参数item
    -->
    <cpn @itemclick="cpnclick"></cpn>
  </div>
  <script>
    //父组件
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello'
      },
      components: {
        cpn
      },
      methods: {
        cpnclick(item) {
          console.log(item)
        }
      }
    })
  </script>

 

总代码

<body>
  <!--父组件模板-->
  <div id="app">
    <!-- 
      2、v-on:itemClick用来监听子组件发射的itemClick事件
         因为这个事件不是浏览器的事件,所以不加括号不会传event,传的是发射事件的参数item
    -->
    <cpn @itemclick="cpnclick"></cpn>
  </div>
  <!--子组件模板-->
  <template id="cpn">
    <div>
      <button v-for="item in categories" @click="itemclick(item)">{{item.name}}</button>
    </div>
  </template>

  <script src="../js/vue.js"></script>

  <script>
    //子组件
    const cpn = {
      template: '#cpn',
      data() {
        return {
          categories: [
            { id: 'aaa', name: '热门推荐' },
            { id: 'bbb', name: '手机数码' },
            { id: 'ccc', name: '家用家电' },
            { id: 'ddd', name: '电脑办公' }
          ]
        }
      },
      methods: {
        itemclick(item) {
          //要把点击了谁传递给父组件
          //1、$emit发射一个事件,事件的名称叫itemClick,发射事件的同时传递一个参数item。这个时候父组件需要监听这个事件
          this.$emit('itemclick', item)
        }
      }
    }
    //父组件
    const app = new Vue({
      el: '#app',
      data: {
        message: 'hello'
      },
      components: {
        cpn
      },
      methods: {
        cpnclick(item) {
          console.log(item)
        }
      }
    })
  </script>

</body>

组件通信

 

 

 

 

上一篇:海康威视前端实习电话面


下一篇:Vue 父子组件的通信传参(props、$emit)