#使用props傳遞數據
html:傳遞普通的字符串
<h3>#使用props傳遞數據</h3> <div id="dr01"> <div>組件實例的作用域是孤立的。這意味着不能並且不應該在子組件的模板內直接引用父組件的數據。可以使用 props 把數據傳給子組件。</div> <br /> <child msg="hello, vue.js!"></child> </div>
js:
//******************************************************************** //使用props傳遞數據 //注冊組件"child" Vue.component("child", { //聲明props屬性 props: ['msg'], //props可以用在模板內 //可以用"this.msg"設置 template: '<div>msg: {{msg}}</div>' }); var dr01 = new Vue({ el: "#dr01", });
結果展示:
#camelCase vs. kebab-case
html:在html中定義或者綁定屬性的時候要符合kebab-case規則
<h3>#camelCase vs. kebab-case</h3> <div id="dr02"> <div>HTML 特性不區分大小寫。名字形式為 camelCase 的 prop 用作特性時,需要轉為 kebab-case(短橫線隔開)</div> <br /> <!-- kebab-case in html --> <child02 my-message02="Hello, this is kebab-case message!"></child02> </div>
js:在js中定義的屬性名稱如果是"camelCase"規則,則在html定義或者綁定value的時候要用"kebab-case"規則(像烤羊肉串一樣的烤串命名法)
//******************************************************************** //camelCase vs. kebab-case //注冊組件child02 Vue.component("child02", { //在js中用駝峰命名法 props: ["myMessage02"], template: "<div>myMessage02: {{myMessage02}}</div>" }); var dr02 = new Vue({ el: "#dr02", });
結果展示:
#動態Props
html:
<h3>#動態Props</h3> <div id="dr03"> <div> <input v-model="parentMsg" placeholder="please input parentMsg" /> </div> <br /> <!-- 用v-bind綁定數據parentMsg到組件中 --> <child03 v-bind:my-message03="parentMsg"></child03> <!-- 縮寫v-bind--> <child03 :my-message03="parentMsg"></child03> </div>
js:
//******************************************************************** //動態Props //注冊組件myMessage03 Vue.component("child03", { props: ['myMessage03'], template: "<div>myMessage03: {{myMessage03}}</div>" }); var dr03 = new Vue({ el: "#dr03", data: { parentMsg: "Hello, this is parentMsg!", } });
結果展示:
#字面量語法 VS 動態語法
html:如果在為vue組件prop定義或者賦值的時候用了“v-bind:”的動態語法,則會先將其轉化為js表達式,然后計算結果賦值,下面示例中,第一個傳遞的是字符串,第二個傳遞的是123+456即579的數值
<h3>#字面量語法 VS 動態語法</h3> <div id="dr04"> <!-- 這里傳遞是字符串 --> <child04 my-message04="123+456"></child04> <!-- 這里用了動態語法,傳遞的值會通過js的表達式計算,傳遞的是數字 --> <child04 :my-message04="123+456"></child04> </div>
js:
//******************************************************************** //字面量語法 VS 動態語法 Vue.component("child04", { props: ["myMessage04"], template: "<div>myMessage04: {{myMessage04}}</div>", }); var dr04 = new Vue({ el: "#dr04", });
結果展示:
#Prop類型綁定
prop 默認是單向綁定:當父組件的屬性變化時,將傳導給子組件,但是反過來不會。這是為了防止子組件無意修改了父組件的狀態——這會讓應用的數據流難以理解。不過,也可以使用 .sync
或 .once
綁定修飾符顯式地強制雙向或單次綁定:
注意:雙向綁定會把子組件的 msg
屬性同步回父組件的 parentMsg
屬性。單次綁定在建立之后不會同步之后的變化。
html:
<h3>#Prop類型綁定(單向、雙向)</h3> <div id="dr05"> <div> <div>vue實例:</div> <input v-model="name" /> </div> <br /> <div> <div>component組件(默認):</div> <child05 :my-message05="name"></child05> <div>component組件(once):</div> <child05 :my-message05.once="name"></child05> <div>component組件(sync):</div> <child05 :my-message05.sync="name"></child05> </div> </div>
js:
//******************************************************************** //Prop類型綁定 Vue.component("child05", { props: ["myMessage05"], template: '<input type="text" v-model="myMessage05" />' }); var dr05 = new Vue({ el: "#dr05", data: { name: "DarkRanger", } });
結果展示:
#Prop驗證
html:
<h3>#Prop驗證</h3> <div id="dr06"> <div> <div> name:{{dr.name}}, age:{{dr.age}}.</div> <div><input v-model="telphone" /></div> </div> <div> <child06 :msg_null="123+456" msg_string="this is string" :msg_number="99" :msg_twoway.sync="telphone" :msg_validate="mobilephone" :msg_number2String="mobilephone" :msg_obj2json="dr" :msg_json2obj="drJson"></child06> </div> </div>
js:
//******************************************************************** //Prop驗證 Vue.component("child06", { props: { //基礎類型檢測("null"意思是任何類型都可以) msg_null: null, //String類型,必須是定義過的,可以是空字符串"" msg_string: { type: String, required: true, }, //Number類型,默認值100 msg_number: { type: Number, default: 100, }, //Object類型,返回值必須是js對象 msg_obj: { type: Object, default: function() { return { name: "DarkRanger", age: "18", } } }, //指定這個prop為雙向綁定 //如果綁定類型不對將拋出一條警告 msg_twoway: { type: String, twoWay: true, }, //自定義驗證,必須是Number類型,驗證規則:大於0 msg_validate: { type: Number, validator: function(val) { return val > 0; } }, //將值轉為String類型 //在設置值之前轉換值(1.0.12+) msg_number2string: { coerce: function(val) { return val + "" } }, //js對象轉JSON字符串 msg_obj2json: { coerce: function(obj) { return JSON.stringify(obj); } }, //JSON轉js對象 msg_json2obj: { coerce: function(val) { return JSON.parse(val); } }, }, template: '<div>msg_null: {{msg_null}}</div>'
+ '<div>msg_string:{{msg_string}}</div>'
+ '<div>msg_number: {{msg_number}}</div>'
+ '<div>msg_obj:{{"name-->"+msg_obj.name+", age-->"+msg_obj.age}}</div>'
+ '<div>msg_twoway:<input v-model="msg_twoway"></div>'
+ '<div>msg_validate:{{msg_validate}}</div>'
+ '<div>msg_number2String: {{msg_number2string}}</div>'
+ '<div>msg_obj2json: {{msg_obj2json}}</div>'
+'<div>msg_json2obj:{{"name: "+msg_json2obj.name+"; age: "+msg_json2obj.age}}</div>' }); var dr06 = new Vue({ el: "#dr06", data: { telphone: "0356-1234567", mobilephone: 15912345678, dr: { name: "DarkRanger", age: 25 }, drJson: '{"name":"DarkRanger","age":25}', } })
展示結果:
解釋:
1、msg_null:不論什么數據類型,只要能解析成功,就渲染成正確的html
2、msg_string:只能傳遞String類型的字符串,如果將child06中的“msg_string="this is string"”更改為“:msg_string="1+2"”,
控制台報錯:
3、msg_number:如果在child06標簽中沒有定義值,我們將會取默認值100,現在定義了“:msg_number="99"”,如果將“:msg_number="99"”更改為“msg_number="99"”,控制台報錯:
4、msg_obj:在js中我們定義的msg_obj的default屬性是一個具有返回js對象的函數,這里取值的時候直接取的就是返回值,如果在child06中定義或者綁定了新的js對象,則會將msg_obj更新為新的數據。取js對象屬性值的時候用{{Object.prop}}取值即可。
5、msg_twoway:雙向數據綁定,在測試的過程中發現,即使設置“twoWay: true”,當子組件發生變化時,vue實例的數據並不會更新,還是單向的數據綁定,這里我將child06中原先的“:msg_twoway="telphone"”更改為“:msg_twoway.sync="telphone"”,保證測試能夠數據雙向綁定。
6、msg_validate:有驗證規則的組件數據,這里定義的規則是當前數值必須大於0,如果將child06中的“:msg_validate="mobilephone"”更改為“:msg_validate="-1"”。控制台報錯:
7、msg_number2string:在結果賦值之前將數值轉化為字符串。
8、msg_obj2json:vue.js內置了JSON的兩個方法,一個是JSON.parse(jsonStr)--》將JSON字符串轉化為js對象,另外一個是JSON.stringify(obj)--》將js對象序列化為JSON字符串。
這里是將obj轉化為json字符串,需要添加coerce屬性,它是一個具有返回json字符串的函數,當然不是必須得用JSON.stringify(obj)方法,只要方法合理,能夠轉化為json能夠識別的字符串即可。
9、msg_json2obj: 將json字符串轉化為js對象。
最后附上完整的html代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script type="text/javascript" src="js/vue.js"></script> <title>組件傳遞數據Props</title> </head> <body style="background-color: lightgray;"> <h3>#使用props傳遞數據</h3> <div id="dr01"> <div>組件實例的作用域是孤立的。這意味着不能並且不應該在子組件的模板內直接引用父組件的數據。可以使用 props 把數據傳給子組件。</div> <br /> <child msg="hello, vue.js!"></child> </div> <hr /> <h3>#camelCase vs. kebab-case</h3> <div id="dr02"> <div>HTML 特性不區分大小寫。名字形式為 camelCase 的 prop 用作特性時,需要轉為 kebab-case(短橫線隔開)</div> <br /> <!-- kebab-case in html --> <child02 my-message02="Hello, this is kebab-case message!"></child02> </div> <hr /> <h3>#動態Props</h3> <div id="dr03"> <div> <input v-model="parentMsg" placeholder="please input parentMsg" /> </div> <br /> <!-- 用v-bind綁定數據parentMsg到組件中 --> <child03 v-bind:my-message03="parentMsg"></child03> <!-- 縮寫v-bind--> <child03 :my-message03="parentMsg"></child03> </div> <hr /> <h3>#字面量語法 VS 動態語法</h3> <div id="dr04"> <!-- 這里傳遞是字符串 --> <child04 my-message04="123+456"></child04> <!-- 這里用了動態語法,傳遞的值會通過js的表達式計算,傳遞的是數字 --> <child04 :my-message04="123+456"></child04> </div> <hr /> <h3>#Prop類型綁定(單向、雙向)</h3> <div id="dr05"> <div> <div>vue實例:</div> <input v-model="name" /> </div> <br /> <div> <div>component組件(默認):</div> <child05 :my-message05="name"></child05> <div>component組件(once):</div> <child05 :my-message05.once="name"></child05> <div>component組件(sync):</div> <child05 :my-message05.sync="name"></child05> </div> </div> <h3>#Prop驗證</h3> <div id="dr06"> <div> <span>vue實例</span> <div> name:{{dr.name}}, age:{{dr.age}}. </div> <div> <input v-model="telphone" /> </div> </div> <br /> <div> <span>vue自定義組件</span> <child06 :msg_null="123+456" msg_string="this is string" :msg_number="99" :msg_twoway.sync="telphone" :msg_validate="mobilephone" :msg_number2String="mobilephone" :msg_obj2json="dr" :msg_json2obj="drJson"></child06> </div> </div> <script> //******************************************************************** //使用props傳遞數據 //注冊組件"child" Vue.component("child", { //聲明props屬性 props: ['msg'], //props可以用在模板內 //可以用"this.msg"設置 template: '<div>msg: {{msg}}</div>' }); var dr01 = new Vue({ el: "#dr01", }); //******************************************************************** //camelCase vs. kebab-case //注冊組件child02 Vue.component("child02", { //在js中用駝峰命名法 props: ["myMessage02"], template: "<div>myMessage02: {{myMessage02}}</div>" }); var dr02 = new Vue({ el: "#dr02", }); //******************************************************************** //動態Props //注冊組件myMessage03 Vue.component("child03", { props: ['myMessage03'], template: "<div>myMessage03: {{myMessage03}}</div>" }); var dr03 = new Vue({ el: "#dr03", data: { parentMsg: "Hello, this is parentMsg!", } }); //******************************************************************** //字面量語法 VS 動態語法 Vue.component("child04", { props: ["myMessage04"], template: "<div>myMessage04: {{myMessage04}}</div>", }); var dr04 = new Vue({ el: "#dr04", }); //******************************************************************** //Prop類型綁定 Vue.component("child05", { props: ["myMessage05"], template: '<input type="text" v-model="myMessage05" />' }); var dr05 = new Vue({ el: "#dr05", data: { name: "DarkRanger", } }); //******************************************************************** //Prop驗證 Vue.component("child06", { props: { //基礎類型檢測("null"意思是任何類型都可以) msg_null: null, //String類型,必須是定義過的,可以是空字符串"" msg_string: { type: String, required: true, }, //Number類型,默認值100 msg_number: { type: Number, default: 100, }, //Object類型,返回值必須是js對象 msg_obj: { type: Object, default: function() { return { name: "DarkRanger", age: "18", } } }, //指定這個prop為雙向綁定 //如果綁定類型不對將拋出一條警告 msg_twoway: { type: String, twoWay: true, }, //自定義驗證,必須是Number類型,驗證規則:大於0 msg_validate: { type: Number, validator: function(val) { return val > 0; } }, //將值轉為String類型 //在設置值之前轉換值(1.0.12+) msg_number2string: { coerce: function(val) { return val + "" } }, //js對象轉JSON字符串 msg_obj2json: { coerce: function(obj) { return JSON.stringify(obj); } }, //JSON轉js對象 msg_json2obj: { coerce: function(val) { return JSON.parse(val); } }, }, template: '<div>msg_null: {{msg_null}}</div>' + '<div>msg_string:{{msg_string}}</div>' + '<div>msg_number: {{msg_number}}</div>' + '<div>msg_obj:{{"name-->"+msg_obj.name+", age-->"+msg_obj.age}}</div>' + '<div>msg_twoway:<input v-model="msg_twoway"></div>' + '<div>msg_validate:{{msg_validate}}</div>' + '<div>msg_number2String: {{msg_number2string}}</div>' + '<div>msg_obj2json: {{msg_obj2json}}</div>' + '<div>msg_json2obj:{{"name: "+msg_json2obj.name+"; age: "+msg_json2obj.age}}</div>' }); var dr06 = new Vue({ el: "#dr06", data: { telphone: "0356-1234567", mobilephone: 15912345678, dr: { name: "DarkRanger", age: 25 }, drJson: '{"name":"DarkRanger","age":25}', } }) </script> </body> </html>