美文网首页PythonVue
Vue中最重要的角色组件详解

Vue中最重要的角色组件详解

作者: 缺月楼 | 来源:发表于2019-06-22 00:09 被阅读15次

    可复用性的组件详解

    使用组件的原因

    作用:提高代码的复用性

    组件的使用方法

    • 全局注册
    <div id="app">
            <my-componet></my-componet>
        </div>
        <!-- 对应的内容<div id="app"><div>我是一个全局组件</div></div> -->
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
        <script>
            // Vue.component(tag, {
            //     template: '<div></div>'
            // })
            // 注册组件 第一个参数 标签名 第二个是要渲染的魔板
            Vue.component('my-componet', {
                template: '<div>我是一个全局组件</div>'
            })
            var app = new Vue({
                el: '#app',
                data: {
    
                }
            })
        </script>
    
    • 优点:所有的Vue实例都可以用
    • 缺点:权限太大,容错率降低
    • 局部注册
    <div id="app" style="border:2px solid red ">
            <!-- 全局组件 -->
            <my-componet></my-componet>
            <!-- 局部组件  -->
            <app-componet></app-componet>
        </div>
        <!-- 对照试验 全局组件和局部组件 -->
        <div id="bpp" style="border:2px solid green;margin-top:5px; ">
            <!-- 全局组件 -->
            <my-componet></my-componet>
            <!-- app局部组件    只能在所注册的实例中使用   这里不会显示 -->
            <app-componet></app-componet>
        </div>
        <!-- 对应的内容<div id="app"><div>我是一个全局组件</div></div> -->
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
        <script>
            // Vue.component(tag, {
            //     template: '<div></div>'
            // })
            // 注册全局组件 第一个参数 标签名 第二个是要渲染的魔板
            Vue.component('my-componet', {
                template: '<div>我是一个全局组件</div>'
            })
            var app = new Vue({
                el: '#app',
                // 局部组件 
                components: {
                    'app-componet': {
                        template: '<div>我是app局部注册的一个组件组件</div>'
                    }
                },
                data: {
    
                }
    
            })
            var bpp = new Vue({
                el: '#bpp',
                data: {
    
                }
            })
        </script>
    
    • 注意
      vue组件的模板在某些情况下会受到html标签的限制,比如 <table>中只能还
      <tr> , <td>这些元素,所以直接在table中使用组件是无效的,此时可以使用is属性来挂载组件
    <table>
         <tbody is="my-component"></tbody>
    </table>
    

    组件使用的小技巧

      1. 推荐使用小写字母加­进行命名(必须) child, my­componnet命名组件
      1. template中的内容必须被一个DOM元素包括 ,也可以嵌套
      1. 在组件的定义中,除了template之外的其他选项—data,computed,methods
      1. data必须是一个方法data:function(){}
        小实践:
    <div id="app">
            <!-- 推荐使用小写字母加­进行命名(必须) -->
            <my-component></my-component>
            <!-- 点击任何一个 都会执行 可用组件方式解决  -->
            <button @click="plus">{{count}}</button>
            <button @click="plus">{{count}}</button>
    
            <hr><br>
            <!-- 组件方式解决 及 data必须是一个方法实践  两次点击的按钮 对象是不一致的 -->
            <btn-component></btn-component>
            <btn-component></btn-component>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    count: 1
                },
                   //组件 
                components: {
                    'my-component': {
                        // `template`中的内容必须被一个`DOM元`素包括 ,也可以嵌套
                        template: '<div><span>组件小技巧</span></div>'
                    },
    
                    'btn-component': {
                        template: '<button @click="count++">{{count}}</button>',
                        // 组件中的data`必须是一个方法
                        data: function() {
                            return {
                                count: 0
                            }
                        }
                    }
                },
                methods: {
                    plus: function() {
                        return this.count++
                    }
                }
    
            })
        </script>
    

    使用props传递数据 父亲向儿子传递数据

    1. 在组件中使用props来从父亲组件接收参数,注意,在props中定义的属性,都可以在组件中直接使用
      2. propps来自父级,而组件中data return的数据就是组件自己的数据,两种情况作用域就是组件本身,可以在template,computed,methods中直接使用
    2. props的值有两种,一种是字符串数组,一种是对象,本节先只讲数组
    3. 可以使用v-­bind动态绑定父组件来的内容
      先看个小栗子:
    
     在父组件里向子组件传递消息:
        <div id="app" style="border:2px solid green;height:200px;">
            <h5 style="text-align:center">我是父组件</h5>
            <child-component msg="我是来自父组件的内容"></child-component>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
        <script>
            // 一个父组件 
            var app = new Vue({
                el: '#app',
                // 定义一个子组件
                components: {
                    'child-component': {
                        // 在组件中使用props来从父亲组件接收参数,
                        props: ['msg'],
                        // 注意,在props中定义的属性,都可以在 组件中直接使用
                        template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                    }
                },
            })
        </script>
    

    可以使用v-­bind动态绑定父组件来的内容:小栗子

     在父组件里向子组件传递消息:
        <div id="app" style="border:2px solid green;height:400px;">
            <h5 style="text-align:center">我是父组件</h5>
            <child-component msg="我是来自父组件的内容"></child-component>
            <br>
            <hr>使用v-bind进行数据动态绑定 把input中的msg传递给子组件
            <input type="text" v-model="parentmsg">
            <bind-component :msg="parentmsg"></bind-component>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
        <script>
            // 一个父组件 
            var app = new Vue({
                el: '#app',
               //父组件定义的内容
                data: {
                    parentmsg: '今晚的月亮真圆啊'
                },
                // 定义一个子组件
                components: {
                    'child-component': {
                        // 在组件中使用props来从父亲组件接收参数,
                        props: ['msg'],
                        // 注意,在props中定义的属性,都可以在 组件中直接使用
                        template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                    },
                    'bind-component': {
                        // 在组件中使用props来从父亲组件接收参数,
                        props: ['msg'],
                        // 注意,在props中定义的属性,都可以在 组件中直接使用
                        template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                    }
                },
            })
        </script>
    

    使用不使用v-bind的区别 :

     在父组件里向子组件传递消息:
        <div id="app" style="border:2px solid green;height:400px;">
            <h5 style="text-align:center">我是父组件</h5>
            <child-component msg="我是来自父组件的内容"></child-component>
            <hr><br>
            <!-- v-bing 对照试验 传递数组  -->
            v-bind对照试验 传递数组
            <!-- msg.length 是7 -->
            <child-component msg="[3,6,7]"></child-component>
            <!-- 使用v-bind可以识别为数组     msg.length 是3 -->
            <child-component :msg="[3,6,7]"></child-component>
            <br>
            <hr>使用v-bind进行数据动态绑定 把input中的msg传递给子组件
            <input type="text" v-model="parentmsg">
            <bind-component :msg="parentmsg"></bind-component>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
        <script>
            // 一个父组件 
            var app = new Vue({
                el: '#app',
                data: {
                    parentmsg: '今晚的月亮真圆啊'
                },
                // 定义一个子组件
                components: {
                    'child-component': {
                        // 在组件中使用props来从父亲组件接收参数,
                        props: ['msg'],
                        // 注意,在props中定义的属性,都可以在 组件中直接使用
                        template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                    },
                    'bind-component': {
                        // 在组件中使用props来从父亲组件接收参数,
                        props: ['msg'],
                        // 注意,在props中定义的属性,都可以在 组件中直接使用
                        template: '<div style="border:2px solid red;height:70px;">{{msg}}</div>'
                    }
                },
            })
        </script>
    

    单向数据流

    解释 : 通过 props 传递数据 是单向的了, 也就是父组件数据变化时会传递给子组
    件,但是反过来不行。
    目的 :是尽可能将父子组件解耦,避免子组件无意中修改了父组件的状态。
    应用场景: 业务中会经常遇到两种需要改变 prop的情况

    一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域
    下可以随意使用和修改。这种情况可以在组件 data内再声明一个数据,引用父组件的 prop

    • 步骤一:注册组件
    • 步骤二:将父组件的数据传递进来,并在子组件中用props接收
    • 步骤三:将传递进来的数据通过初始值保存起来
      小栗子:
     <div id="app" style="border:2px solid green;height:400px;">
            <my-component msg="我是父组件传递的数据"></my-component>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    
        <script>
            // 步骤一:注册组件
            Vue.component('my-component', {
                // 步骤二: 将父组件的数据传递进来, 并在子组件中用props接收
                props: ['msg'],
                template: ' <div>{{count}}</div>',
                data: function() {
                    return {
                        // 步骤三: 将传递进来的数据通过初始值保存起来
                        // <!-- props的值可以通过this.xxx  直接进行获取-->
                        count: this.msg
                    }
                },
            })
            var app = new Vue({
                el: '#app',
                data: {
    
                }
            })
        </script>
    

    另一种情况就是 prop 作为需要被转变的原始值传入。这种情况用计算属性就可以了

    步骤一:注册组件
    步骤二:将父组件的数据传递进来,并在子组件中用props接收
    步骤三:将传递进来的数据通过计算属性进行重新计算
    小栗子:

     <div id="app" style="border:2px solid green;height:400px;">
            <my-component msg="我是父组件传递的数据"></my-component>
            <hr> <br>
            <!-- 需求 :通过input中输入的数据动态改变div的宽度 -->
            <!-- 传递的数据仅仅是一个数据  需要计算属性重新计算拼接 -->
            <input type="text" v-model="width">
            <width-component :width="width"></width-component>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    
        <script>
            //  场景一 步骤一:注册组件
            Vue.component('my-component', {
                    // 步骤二: 将父组件的数据传递进来, 并在子组件中用props接收
                    props: ['msg'],
                    template: ' <div>{{count}}</div>',
                    data: function() {
                        return {
                            // 步骤三: 将传递进来的数据通过初始值保存起来
                            // <!-- props的值可以通过this.xxx  直接进行获取-->
                            count: this.msg
                        }
                    },
                })
                //  场景二 步骤一:注册组件
            Vue.component('width-component', {
                // 步骤二: 将父组件的数据传递进来, 并在子组件中用props接收
                props: ['width'],
                template: ' <div :style="style"></div>',
                data: function() {
                    return {
    
                    }
                },
                computed: {
                    style: function() {
                        // return 出来的就是直接拼接好的style
                        return {
                            width: this.width + 'px',
                            background: 'red',
                            height: '300px'
                        }
                    }
                }
            })
            var app = new Vue({
                el: '#app',
                data: {
                    width: 0
                }
            })
        </script>
    

    数据验证

    vue组件中camelCased(驼峰式) 命名与kebab­case(短横线命名)
    • html中, myMessagemymessage 是一致的,,因此在组件中的html
      中使用必须使用kebab­case(短横线)命名方式。在html中不允许使用驼
      峰!!!!!! (谨记)
    • 在组件中, 父组件给子组件传递数据必须用短横线。在template中,必
      须使用驼峰命名方式,若为短横线的命名方式。则会直接保错。
    • 在组件的data中,用this.XXX引用时,只能是驼峰命名方式。若为短横线
      的命名方式,则会报错。
      小栗子:
     <div id="app" style="border:2px solid green;height:400px;">
            <!-- 会报错   Unknown custom element: myComponent  在组件中的`html`中使用必须使用`kebab­case`(短横线)命名方式。在`html`中不允许使用驼峰!!-->
            <myComponent myMsg='lalalalal'></myComponent>
            <!-- 正确方式 在组件中, 父组件给子组件传递数据必须用短横线。-->
            <my-component my-msg='lalalalal'></my-component>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    
        <script>
            Vue.component('myComponent', {
                    props: ['myMsg'],
                    //    在template中, 必须使用驼峰命名方式, 若为短横线的命名方式。 则会直接保错。
                    template: ' <div>{{abc}}</div>',
                    data: function() {
                        return {
                            // 在组件的data中,用this.XXX引用时,只能是驼峰命名方式。若为短横线的命名方式, 则会报错。
                            // abc: this.my - msg
                            // 正确的写法
                            abc: this.myMsg
                        }
                    },
                })
            var app = new Vue({
                el: '#app',
                data: {
                    a: '100',
                    b: '666',
                    c: true
    
                }
            })
        </script>
    

    验证的 type 类型可以是:

    String
    Number
    Boolean
    Object
    Array
    Function
    栗子:

     <div id="app" style="border:2px solid green;height:400px;">
            <input type="text" v-model='d'>
            <br>
            <type-component :a='a' :b='b' :c='c' :d='d' :e='e' :f='f' :g='g'></type-component>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    
        <script>
                // 数组验证
            Vue.component('typeComponent', {
                // 约定值的类型
                props: {
                    a: String,
                    b: [String, Number],
                    // 必须是布尔类型 默认值是true typr required default
                    c: {
                        type: Boolean,
                        default: true
                    },
                    d: {
                        type: Number,
                        // 必选项为true 必须传值进行渲染
                        required: true
                    },
                    // 不向子组件传递 就会取默认值 default
                    e: {
                        type: Array,
                        default: function() {
                            return ['666e', 333]
                        }
                    },
                    //自定义验证函数
                    f: {
                        validator: function(value) {
                            return value > 10
                        }
                    },
                    //验证选项必须为function
                    g: {
                        type: Function
                    }
                },
                template: ' <div>{{a}}-----{{b}} -----{{c}}----{{d}} ------{{e[0]}}----{{f}} -----{{g}}</div>',
                data: function() {
                    return {}
                },
            })
            var app = new Vue({
                el: '#app',
                // 与上面的props中的选项对应 
                data: {
                    a: '100a',
                    // String或者是Number
                    b: '666b',
                    // 默认值为true
                    c: '',
                    // Missing required prop: "d"
                    d: 66622,
                    // 数组
                    e: [],
                    //自定义验证函数 value > 10 就是 88 > 10  就会渲染
                    f: 88,
                    // 验证类型为function
                    g: console.log("我是一个函数")
    
                }
            })
        </script>
    

    相关文章

      网友评论

        本文标题:Vue中最重要的角色组件详解

        本文链接:https://www.haomeiwen.com/subject/xofpqctx.html