Vue教程43--父子组件的通信-父向子提供数据

101 阅读2分钟

父子组件的通信-父向子提供数据

需求理解:我们的整个页面的构成基本上就是一个大的组件,在大组件中不断进行详细的划分成中组件,部分中组件还是由不同的子组件进行组合得到的,在我们的请求数据的时候,一般是最外边的大组件,一次请求后端拿到所有的数据,然后需要进行子组件和父组件之间的通信,将父组件的数据传递给子组件。

  • 在上一个小节中,我们提到了子组件是不能引用父组件或者Vue实例的数据的
  • 但是,在开发中,往往一些数据确实需要从上层传递到下层
    • 比如在一个页面中,我们从服务器请求到了很多的数据。
    • 其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。
    • 这个时候,并不会让子组件再次发送一个网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)。
  • 如何进行父子组件间的通信呢?Vue官方提到
    • 通过props向子组件传递数据
    • 通过事件向父组件发送消息 image-20210821210211696.png
  • 在下面的代码中,我直接将Vue实例当做父组件并且其中包含子组件来简化代码
  • 真实的开发中,Vue实例和子组件的通信和父组件和子组件的通信过程是一样的

props基本用法

  • 在组件中,使用选项props来声明需要从父级接收到的数据。
  • props的值有两种方式:
    • 方式一:字符串数组,数组中的字符串就是传递时的名称
    • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等
  • 我们先来看一个最简单的props传递:

Snipaste_2021-08-21_21-25-24.png

父组件向子组件传递数据

  • 注意我们在不使用v-bind的时候,我们的数据是"movies"和"message"是以字符串的方式传递到下一层的
 <!DOCTYPE html>
 <html lang="en">
 <head>
   <meta charset="UTF-8">
   <title>Title</title>
 </head>
 <body>
 ​
 <div id="app">
   <cpn2 v-bind:cmovies="movies" :cmessage="message"></cpn2>
 </div>
 ​
 <template id="cpn">
   <div>
     <ul>
       <li v-for="item in cmovies">{{item}}</li>
     </ul>
     <p>{{cmessage}}</p>
   </div>
 </template>
 ​
 <script src="../vue.js"></script>
 ​
 <script>
   //子组件
   const cpnC2 = Vue.extend({
     template:"#cpn",
     props:["cmovies","cmessage"],
     data() {
       return {
 ​
       }
     }
   })
 ​
 ​
   //可以看作是一个默认的组件root
   const app = new Vue({
     el:"#app",
     data:{
       message:"hello world",
       movies:["海贼王","四驱兄弟","火影忍者","犬夜叉"]
     },components:{
       cpn2:cpnC2
     }
   })
 </script>
 </body>
 </html>

代码原理剖析

Snipaste_2021-08-21_21-19-30.png

效果展示:

Snipaste_2021-08-21_21-22-55.png

通过对象的方式父组件向子组件传递数据

 <!DOCTYPE html>
 <html lang="en">
 <head>
   <meta charset="UTF-8">
   <title>Title</title>
 </head>
 <body>
 ​
 <div id="app">
   <cpn2 v-bind:cmovies="movies" :cmessage="message"></cpn2>
 </div>
 ​
 <template id="cpn">
   <div>
     <ul>
       <li v-for="item in cmovies">{{item}}</li>
     </ul>
     <p>{{cmessage}}</p>
   </div>
 </template>
 ​
 <script src="../vue.js"></script>
 ​
 <script>
   //子组件
   const cpnC2 = Vue.extend({
     template:"#cpn",
     props:{
       //1.类型限制
       // cmovies:Array,
       // cmessage:String,
 ​
       //2.提供一些默认值,类型,必要性
       cmessage:{
         type:String,
         default:"aaaaa",
         required:true
       },
       
       //类型是对象或者数组的时候,默认值必须是工厂函数
       // cmovies:{
       //   type:Array,
       //   default:[]  //vue 2.5.17以后会报错
       // }
       
       cmovies:{
         type:Array,
         default(){
           return []
         }
       }
     },
     data() {
       return {
 ​
       }
     }
   })
 ​
 ​
   //可以看作是一个默认的组件root
   const app = new Vue({
     el:"#app",
     data:{
       message:"hello world",
       movies:["海贼王","四驱兄弟","火影忍者","犬夜叉"]
     },components:{
       cpn2:cpnC2
     }
   })
 </script>
 </body>
 </html>

props数据验证

  • 在前面,我们的props选项是使用一个数组。

  • 我们说过,除了数组之外,我们也可以使用对象,当需要对props进行类型等验证时,就需要对象写法了。

  • 验证都支持哪些数据类型呢?

    • String
    • Number
    • Boolean
    • Array
    • Object
    • Date
    • Function
    • Symbol

    Snipaste_2021-08-21_21-39-13.png

  • 当我们有自定义构造函数时,验证也支持自定义的类型

image-20210821214057374.png