VUE入门到实战--Vue组件参数校验和非props特性,给组件绑定原生事件

1、组件参数校验

1、当父组件向子组件属性传值的时候,我们的子组件可以对传递来的值进行校验。

2、props可以传递动态的或者静态的props,但是不管是静态的或者动态的我们就希望使用v-bind:来表示后面引号中的内容是个JS表达式,而不是字符串。

3、传入一个对象的所有属性:如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind(取代 v-bind:prop-name)。例如,对于一个给定的对象 post

post: {
  id: 1,
  title: 'My Journey with Vue'
}

下面的模板:

<blog-post v-bind="post"></blog-post>

等价于:

<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

4、子组件校验父组件传来的值的时候,两个步骤:(1)接收 校验。这个时候props就单纯的使用数组来接收了,使用对象的方式来既接收又校验

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>组件的参数校验</title>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="root">
        <child :content="hello world"></child>
    </div>
    <script>
        Vue.component('child',{
            props:{
                //content: Number, //数字类型(简单校验)
                //content: String, //字符串类型(简单校验)
                //content: [ Number, String ]//数字或者字符串类型(简单校验)
                content: {//(复杂校验)
                    type: String,                                //类型为String   
                    required: true,                              //属性必传
                    default: 'default value',                    //当属性不必传的时候,父组件没有传,使用默认值
                    validator: function(value) {                 //自定义校验器
                        return (value.length > 5);//校验字符串长度大于5,返回true,否则返回false,校验不成功
                    }
                }
            },
            template: "<div>{{content}}</div>"
        })
        var vm = new Vue({
            el: '#root',
        })
    </script>
</body>
</html>

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

2、非props属性

1、什么是props属性?之前我们写的时候,父组件传值的时候,我们同时在子组件中去声明了所要接收的参数。这样形成了一传一接的效果,对应上了,这种就是props属性。

2、props属性的特点:

(1)子组件在真正的DOM上是不会显示传递的属性的。就是说在上面的例子中,我们的父组件是 <child :content="hello world"></child>这样的,但是在真正的DOM中是这样的:<div>hello world</div>。所以说content=“hello world”这个属性是不会显示的

(2)只有是props属性,我们才能在子组件中的模板当中使用插值法,在上面的额例子中,就是可以通过content或者this.content这样的方法去拿到content中的内容。

3、什么是非props属性?父组件向子组件传递了属性,但是子组件没有props来接收

4、非props属性的特点和props属性的特点有点相反:

(1)首先我们无法使用插值法,或者无法使用content和this.content来显示content的内容。

(2)在真正的DOM中,content=“hello world”这个属性会显示在DOM元素上。就是这样:<div content=“hello world”>hello world</div>

3、给组件绑定原生事件

我们下面使用3个例子来展示什么是自定义事件,原生事件,和组件绑定原生事件

1、原生事件:

<body>
    <div id="root">
        <child></child>
    </div>
    <script>
        Vue.component('child',{
            template: "<div @click='handleClick'>hello world<div>", //1、这里在html标签上绑定的事件为原生事件
            methods: {
                handleClick: function() {//2、处理原生事件
                    alert('click');
                }
            }
        });
        var vm = new Vue({
            el: "#root",
        })
    </script>
</body>

2、自定义事件:

<body>
    <div id="root">
        <child @change="handleClick"></child> <!--2、直接写在组件上的事件是自定义事件,实质是一种监听-->
    </div>
    <script>
        Vue.component('child',{
            template: "<div @click='handleClick'>hello world</div>", 
            methods: {
                handleClick: function() {
                    this.$emit('change'); //1、子组件向外触发事件
                }
            }
        });
        var vm = new Vue({
            el: "#root",
            methods: {
                handleClick: function() {//3、实例当中处理自定义事件
                    alert('click');
                }
            }
        })
    </script>
</body>

3、在组件上绑定原生事件

<body>
    <div id="root">
        <child @click.native="handleClick"></child> <!--1、直接在事件后面添加.native,变自定义事件为原生事件-->
    </div>
    <script>
        Vue.component('child',{
            template: "<div>hello world</div>",  
        });
        var vm = new Vue({
            el: "#root",
            methods: {
                handleClick: function() {//2、处理绑定在组件上的原生事件
                    alert('click');
                }
            }
        })
    </script>
</body>

4、.sync修饰符

1、最早的版本:最开始学的时候,双向绑定就是父组件给子组件传值,子组件通过this.$emit触发事件给父组件

<body>
    <div id="app">
        <div>{{bar}}</div>
        <my-comp :foo="bar" @add="handleAdd"></my-comp>
    </div>
    <script>
        Vue.component('my-comp',{
            template: '<div @click="increment">点我+1</div>',
            props:['foo'],
            data:function(){
                return {
                    copyFoo:this.foo
                }
            },
            methods:{
                increment:function(){
                    this.$emit('add',++this.copyFoo);
                }
            }
        })
        var vm = new Vue({
            el: "#app",
            data:{
                bar:0
            },
            methods:{
                handleAdd:function(foo){
                    this.bar=foo;
                }
            }
        })
    </script>
</body>

2、后来我们可以使用v-model,修改一下默认的value和input事件

<body>
    <div id="app">
        <div>{{bar}}</div>
        <my-comp v-model="bar"></my-comp>  <!--1、写法的不同-->
    </div>
    <script>
        Vue.component('my-comp',{
            model:{                        <!--2、第二处不同-->
                prop:'foo',
                event:'update:foo'
            },
            template: '<div @click="increment">点我+1</div>',
            props:['foo'],
            data:function(){
                return {
                    copyFoo:this.foo
                }
            },
            methods:{
                increment:function(){
                    this.$emit('update:foo',++this.copyFoo);
                }
            }
        })
        var vm = new Vue({
            el: "#app",
            data:{
                bar:0
            },
        })
    </script>
</body>

3、.sync修饰符

<body>
    <div id="app">
            <div>{{bar}}</div>
            <my-comp :foo.sync="bar"></my-comp>   <!--1、使用,sync就只有写法的不同-->
        </div>
        <script>
            Vue.component('my-comp', {
                template: '<div @click="increment">点我+1</div>',
                props: ['foo'],
                data: function() {
                    return {copyFoo: this.foo}
                },
                
                methods: {
                    increment: function() {
                        this.$emit('update:foo', ++this.copyFoo);
                    }
                }
            });
            new Vue({
                el: '#app',
                data: {bar: 0}
            });
        </script>
            
</body>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值