Vuejs--父子组件之间的通信

528 阅读6分钟

存在数据通信的原因

首先,我们知道,组件有自己的data。他只能访问自己data中的数据,而不能访问其他组件或实例中的数据,但是往往我们需要进行一些数据传递。从父组件传给子组件,比如说最外层的根组件进行了数据请求,但是里面的数据有一些是属于子组件展示的,我们就需要将父组件请求来的数据,传递给子组件。

父组件通过props向子组件传递数据

怎么传递呢?在我看来,就是分为简简单单的两步。

  1. 首先通过自定义属性,向子组件传递数据
    自定义属性的意思是你自己给这个组件元素定义一个它本身不具有的属性并且设置值,那么这个属性以及属性值已经被传递到这个子组件里面了。另外就是自带的属性都有v-bind指令,自定义属性其实也有v-bind指令。正是由于此,导致属性值可以是父组件的数据而不局限于字符串了。所以我们可以把父组件的数据传递给子组件。(换言之,如果没有使用v-bind指令,那么自定义属性全是字符串)
  2. 在子组件中声明父组件传递过来的数据
    仅仅传入组件还不够,如果你想使用这些属性(其实完全可以当变量对待,属性名==变量名,属性值==变量值),那你要给她一个身份,也就是你要对她进行声明,声明的方式是option选项中的props。
    props的形式有两种。

props的形式

例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
</head>
<body>
    <div id="app">
        <cpn :title="title"></cpn>//通过自定义属性向子组件传递数据
    </div>
    <script>
        const app = new Vue({
            el:"#app",
            data:{
                title:"我是猪"
            },
            components:{
                cpn:{
                    template:`<div><h2>{{title}}</h2></div>`,//直接就可以像data中的数据一样使用传过来的数据
                    props:["title"]//子组件通过props这个option声明这个属性或者说数据,这里使用数组形式
                }
            }
        })
    </script>
</body>
</html>
  1. props是数组
    声明形式: props:["title"]注意这里是字符串的形式,至于为什么是变量名的字符串而不是变量名我也不太清楚是为啥
  2. props是对象
    对象的形式更全面因为它可以做更多的事情:
  • 对属性的传入值进行类型限制 例如:type:Array

  • 给属性设置默认值 例如:default:"abc"

  • 规定属性是否一定要传值 例如:required:bool值

props:{ data1:Number,//data1必须是Number类型 data2:[Number,String]//data2必须是这两者之一 data3:{ type:Number, required:true,//意思是是不是必须传值,true是,false否 default:100//默认值 } }

### 注意事项
- 主要说一下type可以设置的类型:  
1.String2.Number3.Boolean4.Function5.Array6.Object  
- default设置默认值的时候,如果值是一个Object/Array的话,需要通过function的形式,return{}/[]

data4{ default(){ return {} } }

 ## props声明的数据和data的数据之间有什么区别?
### 不同点
1. 来源不同,props的数据由父级组件传进来,data的数据是来自于自己  
2. 正因为props是由父组件传入的,或者说是父组件决定的。如果你再通过子组件改变它的值的话,那么就会特别的混乱。并且解析的时候会抛出警告,并提出建议。就是在data中定义数据并且让props中的属性初始化它。你随便改这些data,因为它是你子组件本身的东西。不会造成刚刚那种混乱的情况。
### 相同点
除了来源不同之外,数据的用法完全一致。能使用的地点完全一致。   


## 单向数据流  
主要是说父组件数据的更改会导致传给子组件数据的变化,反之不会。但是如果传递的是引用类型的数据,比如数组,对象等等。这是会一同变化的。  
举个例子:`<div id="ele"><component :mytext="text">	</component>	</div>`  
如果父组件的text数据改变,则会导致子组件的mytext数据也改变,这也是动态的prop。但是如果mytext在子组件里面做了改变。是不会引起父组件text数据的改变的。  
props的数据传进去,可以把他作为初始值赋给子组件的data内的属性。然后我们后续只用操作这个data数据即可。  
举个例子:
``` ## props中的驼峰标识 其实这是一个很简单的问题,HTML有一个很明显的特征就是它对大小写不敏感。浏览器解析HTML代码的时候会把所有的大写字母转为小写。那么当我们在props中声明一个包含大写字母的属性的时候比如 `props:["myTitle"]`,然后父组件再向子组件传入这个数据 ``,这样是不会生效的。 ### 原因 是因为``,你传给的自定义属性其实是mytitle,而不是myTitle.所以在props中应该声明mytitle,而不是myTitle. 而变量名一般在命名的时候都有大写字母。也就是我们非要使用myTitle的形式,那么在父传子的时候应该怎么处理呢? 使用驼峰标识:``,个人觉得可以理解成转义,**就是变量中如果有大写字母全部转成`-+小写字母`的形式。** # 子组件向父组件传递信息 子组件向父组件传递信息通常是使用自定义事件的方式。 example: ``` Document

{{total}}

//父组件监听该事件。