深入了解组件- -- Prop

gitHub地址:https://github.com/huangpna/vue_learn/example里面的lesson08

一 Prop的大小写(camelCase vs kebab-case)

 举个例子:

HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index1</title>
</head>
<body>
    <div id="app1">
        <blog-post v-bind:post-title="msg"></blog-post>
    </div>
</body>
<script src="../js/vue.min.js"></script>
<script>
    Vue.component('blog-post',{
        props:['postTitle'],
        template:'<div>{{postTitle}}</div>'
    });
    new Vue({
        el:'#app1',
        data:{
            msg:'hello!'
        }
    })
</script>
</html>

重申一次,如果你使用字符串模板,那么这个限制就不存在了。

二 Prop的类型

举例:

props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

我们除了使用以字符串数组形式列出的prop外,你也可以以对象的形式列出prop:

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object
}

三 传递静态和动态Prop

 举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index2</title>
</head>
<body>
    <div id="app2">
        <!--静态传值-->
        <my-component title="hello"></my-component>
        <!--动态传值-->
        <my-component v-bind:title="post.title"></my-component>
    </div>
</body>
<script src="../js/vue.min.js"></script>
<script>
    Vue.component('my-component',{
        props:['title'],
        template:'<div>{{title}}</div>'
    });
    new Vue({
        el:'#app2',
        data:{
            post:{
                title:'标题'
            }
        }
    })
</script>
</html>

 在上述示例中,我们传入的值都是字符串类型的,但实际上任何类型的值都可以传给一个 prop。

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index3</title>
</head>
<body>
    <div id="app3">
        <!--传入一个数字-->
        <component-a v-bind:num="42"></component-a>
        <component-a v-bind:num="postsA.a"></component-a>       <!--用一个变量进行动态赋值-->
        <!--传入一个布尔值-->
        <component-b bool></component-b>   <!--该 prop 没有值的情况在内,都意味着 `true`-->
        <component-b v-bind:bool="false"></component-b>
        <component-b v-bind:bool="postsB.a"></component-b>
        <!--传入一个数组-->
        <component-c v-bind:arr="[221,225,220]"></component-c>
        <component-c v-bind:arr="postsC.a"></component-c>
        <!--传入一个对象-->
        <component-d v-bind:obj="{title:'标题1',content:'内容1'}"></component-d>
        <component-d v-bind:obj="postsD.a"></component-d>
        <!--传入一个对象的所有属性-->
        <component-e v-bind:obj1="postE"></component-e>
        <!--等价于-->
        <!--<component-e-->
                <!--v-bind:id="postE.id"-->
                <!--v-bind:title="postE.title"-->
                <!--v-bind:content="postE.content"-->
        <!--&gt;</component-e>-->
    </div>
</body>
<script src="../js/vue.min.js"></script>
<script>
    /**
    * 注意:即便你传入的值是静态的,我们仍然需要 `v-bind` 来告诉 Vue
    *
    * */
        var componentA = {
            props:['num'],
            template:'<div>传入的数字:{{num}}</div>'
        };
        var componentB = {
            props:{
                bool:{
                    type:Boolean,
                    default:false
                }
            },
            template:'<div>传入的一个布尔值:{{bool}}</div>'
        };
        var componentC = {
            props:['arr'],
            template:'<div>传入的一个数组:<span v-for="item in arr">{{item}}&nbsp;</span></div>'
        };
        var componentD = {
            props:['obj'],
            template:'<div>传入一个对象:<span>{{obj.title}}:{{obj.content}}</span></div>'
        };
        var componentE = {
            props:['obj1'],
            template:'<div>传入一个对象的所有属性:<span>{{obj1}}</span></div>'
        };
        new Vue({
            el:'#app3',
            data:{
                postsA:{
                    a:42
                },
                postsB:{
                    a:true
                },
                postsC:{
                    a:[226,221,228]
                },
                postsD:{
                    a:{
                        title:'标题一',
                        content:'内容一'
                    }
                },
                postE: {
                    id: 1,
                    title: 'My Journey with Vue',
                    content:'My Journey with Vue'
                }
            },
            components:{
                'component-a':componentA,
                'component-b':componentB,
                'component-c':componentC,
                'component-d':componentD,
                'component-e':componentE
            }
        })
</script>

四 单向数据流

占位

五 Prop验证

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index4</title>
</head>
<body>
    <div id="app4">
        <my-component  v-bind:prop-a="12" v-bind:prop-b="'sfsfs'" v-bind:prop-c="'sdfsf'" v-bind:prop-d="45"
                       v-bind:prop-e="{a:'a'}" v-bind:prop-f="100"></my-component>
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    /**
    * 注意:这里踩了一个非常大的坑,应该说很无语的坑,在深入了解prop的时候该报错的时候总是没有报错,最开始还以为是自己理解错了,最后看到一篇文章,才想到最初看到的vue安装时看到的如果开发是
     * 生产版本会自动所有常见错误相关的警告!----请使用开发版本
    * */
    Vue.component('my-component',{
        props:{
            // 基础类型检测 (`null` 意思是任何类型都可以)
            propA:Number,
            // 多种类型
            propB:[String, Number],
            // 必填的字符串
            propC:{
                type:String,
                required:true
            },
            // 带有默认值的数字
            propD: {
                type: Number,
                default: 100
            },
            //带有默认值的对象
            propE:{
                type:Object,
                default:function () {
                    return {message:'hello'}
                }
            },
            // 自定义验证函数
            propF:{
                validator:function (value) {
                    return value > 10
                }
            }
        },
        template:'<div><p>{{propA}}</p><p>{{propB}}</p><p>{{propC}}</p><p>{{propD}}</p><p>{{propE}}</p><p>{{propF}}</p></div>'
    });
    new Vue({
        el:'#app4'
    })
</script>
</html>

这里都是通过验证了的,能够全部输出来,而且控制台没有报错。
如果有不符合的,控制台会报错。

例如:

当propA的类型为Number时,而传入的值是一个字符串,这时控制台便会报错:

<my-component  v-bind:prop-a="csdsff"></my-component>//传入一个字符串

亦或者验证propF的值必须大于10时,而传入的值小于10,此时也会报错:

<my-component  v-bind:prop-f="1"></my-component>

但是这里要特别注意一点:这里踩了一个非常大的坑,应该说很无语的坑,在深入了解prop的时候该报错的时候总是没有报错,最开始还以为是自己理解错了,最后看到一篇文章,才想到最初看到的vue安装时如果是在开发的时候使用生产版本会自动失去所有常见错误相关的警告!

注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 datacomputed 等) 在 default 或 validator 函数中是不可用的。

六 类型检查

type 可以是下列原生构造函数中的一个:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

额外的,type 还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index5</title>
</head>
<body>
    <div id="app5">
        <ul-lik :names="text"></ul-lik>
    </div>
</body>
<script src="../js/vue.js"></script>
<script>
    function Foo(name) {
        this.name = name;
    }
    Vue.component('ul-lik', {
        props: {
            names: Foo
        },
        template: '<div>{{names.name}}</div>'
    });
    var vm = new Vue({
        el: '#app5',
        data: {
            text: new Foo('zhangsan')
        }
    });
</script>
</html>

来验证 author prop 的值是否是通过 new Foo创建的。

原文地址:https://www.cnblogs.com/1156063074hp/p/10065734.html