1.基本用法
组件不仅仅是要把模板的内容进行复用,更重要的是组件之间要进行通讯。
通常父组件的模板中包含子组件,父组件要正向的向子组件传递数据或者参数。
这个正向传递数据的就是通过props来实现的。
props中声明的数据与组件data函数return的数据的主要区别在于props来自父级,而data组件的数据是自己的数据,作用域是组件本身。
这两种数据都可以在模板template及计算属性和方法methods中使用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component message="来自父组件的数据"></my-component> </div> <script> // var data = { // message: 'ceshi' //直接定义行不通,在app中定义也行不通,还只能在父级标签中定义,也许组件就是如此定义的 // }; Vue.component('my-component',{ props: ['message'], //接收数据,如果需要传递多个参数,那么只需要在数组中添加就可以了 template: '<div>{{ message }}</div>' //将数字带入标签里面 // data: function () { // return data; // } }); var app = new Vue({ el: "#app", }) </script> </body> </html>
需要说明的是,由于HTML特性不区分大小写,同时无视'-',所以在定义变量的时候可以比较灵活。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component message-Test="HTML不区分大小写"></my-component> <!--不区分大小,-也无法识别--> </div> <script> Vue.component('my-component',{ props: ['messageTest'], //但是在js中就不能随便添加“-” template:'<div>{{ messageTest }}</div>' }); var app = new Vue({ //app这个对象你还必须要定义,不然组件也无法使用 el: "#app", }) </script> </body> </html>
有时候传递的数据并不是直接写死,而是来自父级的动态数据,这时可以使用v-bind来动态绑定props的值。
当父组件的数据变化时,也会传递给子组件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <input type="text" v-model="parentMessage"> <my-component :message="parentMessage"></my-component> </div> <script> Vue.component('my-component',{ props: ['message'], template:'<div>{{ message }}</div>' }); var app = new Vue({ el: "#app", data: { parentMessage: '', } }) </script> </body> </html>
:xxx = “yyy”代表绑定的是一个变量,yyy是一个JS表达式,和xxx="yyy"的性值完全不同。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component :message="[1,2,3]"></my-component> <!--绑定的一个数组→ 3 <my-component message="[1,2,3]"></my-component> <!-- 当作一个字符串来处理→ 7 </div> <script> Vue.component('my-component',{ props: ['message'], template: '<div>{{ message.length }}</div>' }); var app = new Vue({ el: "#app", }) </script> </body> </html>
2.单向数据流
在Vue1的版本中采用的是双向数据流,也就是父子组件可以直接双向通讯。
业务中会经常遇到两种需要改变prop的情况:
一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域下可以随意修改。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component message="来自父组件的数据"></my-component> <!--:一般是命令--> </div> <script> Vue.component('my-component',{ props: ['message'], template: '<div>{{ newMessage }}</div>', data: function () { return { newMessage: this.message + '????' //在这里只需要维护newMessage这个变量就可以了 } } }); var app = new Vue({ // Vue定义必须放在组件后面,因为放在前面在加载的时候就没有加载组件 el: "#app", }); </script> </body> </html>
另一种情况就是prop作为需要被转变的原始值传入。这种情况用计算属性就可以了
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component width="1000" height="1000"></my-component> </div> <script> Vue.component('my-component',{ props: ["width",'height'], template: '<div style="style">组件内容</div>', computed:{ style: function () { return { this.width + 'px', height: this.height + 'px' } } } }); var app = new Vue({ el: "#app" }) </script> </body> </html>
3.数据验证
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> </head> <body> <div id="app"> </div> <script> Vue.component('my-component',{ props:{ //必须是数字类型 propA: Number, //必须是字符串和数字类型 propB: [String,Number], //布尔值,如果没有定义,默认值就是true propC: { type: Boolean, default: true, }, //数字,而且是必传 propD: { type: Number, required: true, }, //如果是数组或对象,默认值必须是一个函数来返回 propE: { type: Array, default: function () { return []; } }, //自定义一个验证函数 propF: { validator: function (value) { return value > 10; } } } }); var app = new Vue({ el: "#app" }) </script> </body> </html>
验证的type类型可以是:
String
Number
Boolean
Object
Array
Function
type也可以是一个自定义构造器,使用instanceof检测。