一.传递数据
1.props 传入单数据
就像 data 一样,prop 可以用在模板内,同样也可以在 vm 实例中像“this.message”这样使用
<template> <div id="app"> <h1>{{title}}</h1> <child message="hello! Prop"></child> </div> </template> <script> import Vue from 'vue'; Vue.component('child', { // 声明 props props: ['message'], template: '<span>{{ message }}</span>' }) export default { name: 'app', data: function () { return { title: '使用 Prop 传递数据' } } } </script>
<child message="hello! Prop"></child>
2.props 传入多个数据
如果在父组件的模板类添加其他元素或者字符会有:
①在最前面加入—每个子组件渲染出来都会在其前面加上
②在最后面加入—每个子组件渲染出来都会在其后面加上
③在中间加入—他前面子组件后面加上,后面的子组件后面加上
(1)1种
<template> <div id="app"> <child msg="hello!"></child> <child nihao="hello1!"></child> <child nisha="hello2!"></child> </div> </template> <script> import Vue from 'vue'; Vue.component('child', { props: ['msg','nihao','nisha'], template: '<span>{{ msg }}{{nihao}}{{nisha}}</span>', }); export default { name: 'app', data: function () { return { } } } </script>
(2)2种
template: '<span>小明,{{ msg }}{{nihao}}{{nisha}}</span>',
(3)3种
template: '<span>{{ msg }}{{nihao}}{{nisha}}小明</span>',
(4)4种
template: '<p>{{ msg }}小明 {{nihao}} {{nisha}}小林</p>',
注意:camelCased (驼峰式) 命名的 prop 需要转换为相对应的 kebab-case (短横线隔开式) 命名:
Vue.component('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
<!-- kebab-case in HTML -->
<child my-message="hello!"></child>
二.动态prop
要动态地绑定父组件的数据到子模板的 props,与绑定到任何普通的HTML特性相类似,就是用 v-bind。每当父组件的数据变化时,该变化也会传导给子组件
<template> <div id="app"> <input v-model="parentMsg"> <br> <child v-bind:my-message="parentMsg"></child> </div> </template> <script> import Vue from 'vue'; export default { name: 'app', data: function () { return { title: '使用 Prop 传递数据', parentMsg: 'Message from parent' } }, components: { child: { props: ['myMessage'], template: '<span>{{myMessage}}</span>' } } } </script>
三.表达式计算,传递值
如果想传递一个实际的 number,需要使用 v-bind
,从而让它的值被当作 JavaScript 表达式计算
<comp v-bind:some-prop="1"></comp>
<template> <div id="app"> <p>{{tle1}}:<comp total="123+456"></comp></p> <p>{{tle2}}<comp :total="123+456"></comp></p> </div> </template> <script> import Vue from 'vue'; Vue.component("comp", { props: ["total"], template: "<span>total: {{total}}</span>", }); export default { name: 'app', data: function () { return { tle1: '这里传递是字符串', tle2: '用了v-bind动态语法,传递值会通过js的表达式计算,得到个值:' } } } </script>
四.Prop类型绑定
prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。
五.prop验证
传入的数据不符合规格,Vue 会发出警告。当组件给其他人使用时,这很有用。
<template> <div id="app"> <div>name:{{dr.name}}, age:{{dr.age}}.<input v-model="telphone" /> </div> <br /><br /> <div> <span>vue自定义组件</span><br /> <child :msg_null="123+456" msg_string="adss" :msg_number="0" :msg_twoway.sync="telphone" :msg_validate="mobilephone" :msg_number2String="mobilephone" :msg_obj2json="dr" :msg_json2obj="drJson"></child> </div> </div> </template> <script> import Vue from 'vue'; Vue.component("child", { props: { msg_null: null,//基础类型检测("null"意思是任何类型都可以) msg_string: { //String类型,必须是定义过的,可以是空字符串"" type: String, required: true, }, msg_number: {//Number类型,默认值100 type: Number, default: 100, }, msg_obj: {//Object类型,返回值必须是js对象 type: Object, default: function() { return { name: "DarkRanger", age: "18", } } }, msg_twoway: { //指定这个prop为双向绑定,如果绑定类型不对将抛出一条警告 type: String, twoWay: true, }, msg_validate: { //自定义验证,必须是Number类型,验证规则:大于0 type: Number, validator: function(val) { return val > 0; } }, msg_number2string: { //将值转为String类型,在设置值之前转换值(1.0.12+) coerce: function(val) { return val + "" } }, msg_obj2json: { //js对象转JSON字符串 coerce: function(obj) { return JSON.stringify(obj); } }, msg_json2obj: {//JSON转js对象 coerce: function(val) { return JSON.parse(val); } }, }, template: '<div><b>msg_null=123+456=</b> {{msg_null}}</br> </br><b>msg_string="1":</b>{{msg_string}}</br></br><b>msg_number:</b> {{msg_number}}</br> </br><b>msg_obj:</b>{{"name-->"+msg_obj.name+", age-->"+msg_obj.age}}</br> </br><b>msg_twoway:</b><input v-model="msg_twoway"></br></br><b>msg_validate:</b>{{msg_validate}}</br> </br><b>msg_number2String:</b> {{msg_number2string}}</br></br><b>msg_obj2json:</b> {{msg_obj2json}}</br> </br><b>msg_json2obj:</b>{{"name: "+msg_json2obj.name+"; age: "+msg_json2obj.age}}</div>' }); export default { name: 'app', data: function () { return { telphone: "0356-1234567", mobilephone: 15912345678, dr: { name: "DarkRanger", age: 25 }, drJson: {"name":"DarkRanger","age":25} } } } </script>
解释:
①、msg_null:不论什么数据类型,只要能解析成功,就渲染成正确的html
②、msg_string:只能传递String类型的字符串,如果将child06中的“msg_string="this is string"”更改为“:msg_string="1+2"”,
控制台报错:
③、msg_number:如果在child06标签中没有定义值,我们将会取默认值100,现在定义了“:msg_number="99"”,如果将“:msg_number="99"”更改为“msg_number="99"”,控制台报错:
④、msg_obj:在js中我们定义的msg_obj的default属性是一个具有返回js对象的函数,这里取值的时候直接取的就是返回值,如果在child06中定义或者绑定了新的js对象,则会将msg_obj更新为新的数据。取js对象属性值的时候用{{Object.prop}}取值即可。
⑤、msg_twoway:双向数据绑定,在测试的过程中发现,即使设置“twoWay: true”,当子组件发生变化时,vue实例的数据并不会更新,还是单向的数据绑定,这里我将child06中原先的“:msg_twoway="telphone"”更改为“:msg_twoway.sync="telphone"”,保证测试能够数据双向绑定。
⑥、msg_validate:有验证规则的组件数据,这里定义的规则是当前数值必须大于0,如果将child06中的“:msg_validate="mobilephone"”更改为“:msg_validate="-1"”。控制台报错:
⑦、msg_number2string:在结果赋值之前将数值转化为字符串。
⑧、msg_obj2json:vue.js内置了JSON的两个方法,一个是JSON.parse(jsonStr)--》将JSON字符串转化为js对象,另外一个是JSON.stringify(obj)--》将js对象序列化为JSON字符串。
这里是将obj转化为json字符串,需要添加coerce属性,它是一个具有返回json字符串的函数,当然不是必须得用JSON.stringify(obj)方法,只要方法合理,能够转化为json能够识别的字符串即可。
⑨、msg_json2obj: 将json字符串转化为js对象。