Vue.js-----轻量高效的MVVM框架(九、组件利用Props传递数据)

来源:互联网 发布:辐射4 捏脸数据 编辑:程序博客网 时间:2024/05/17 05:18

#使用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//注册组件child02Vue.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//注册组件myMessage03Vue.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>
复制代码