zoukankan      html  css  js  c++  java
  • vue基础整理-组件

    1--组件

        可以理解为页面的一部分,其具有独立的逻辑及功能或界面,同时又能与其他部分进行相应地融合,变成完整的应用。页面可以由这样一个个的组件构成,如导航栏、列表项、弹窗、侧边栏、下拉框、多选框等。页面相当于一个大的框架,将这些组件组合成一个功能更为强大的模块,组件方便被替换或删除,而不影响整个应用程序的运行。

    前端组件化的思想:

    将大的东西拆成一个个的小东西,然后完成小东西的功能,最后再将这些小东西进行组合,得到最初想要的模样,即分而治之的思想。

    使用组件的优势:

    提高开发效率;可重用;简化调试步骤;便于协同开发;提升整个项目的可维护性。

    2—vue中的组件

       Vue中的组件是一个自定义标签,vue.js的编辑器为其添加特殊功能;vue也可以扩展原生的html元素,封装可重用的代码。

       组件的基本组成:样式结构、行为逻辑、数据

    如下为单文件组件,包含了样式结构、行为逻辑、数据。

      

    3—注册组件

      全局注册:

      可以在任何模板中使用,使用前先注册。

      语法:使用Vue.component(组件名,选项对象)

      其中,Vue是构造函数,component是其下的方法

      组件名命名规则:camelCase、kebab-case

      在html中使用组件:使用kebab-case命名法

      eg. 注册:Vue.component(’my-component’,{})

         使用:<my-component></my-component>

      局部注册:

        在组件实例中通过选项对象注册,只在所注册的作用域中使用

    
    { 
    components:{
    
        组件名:选项对象
     }
    }

    4--组件间通信:

    父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。

    父组件->子组件:

    组件实例的作用域是孤立的,不能在子组件直接用父组件的数据。

    父组件向子组件传递数据时,可以在组件上使用自定义属性绑定数据,在组件中需要显示的用props声明自定义属性。

    子组件->父组件:

    子组件向父组件传递数据时,需要用到自定义事件,父组件用$on监听自定义事件,$emit触发父组件所关心的自定义事件。父组件用v-on用来监听子组件的事件是否触发了来作出相应的处理。

    组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 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>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
        <style>
        </style>
    </head>
    
    <body>
        <div id="app" class="common">
            <my-component :my-name="name" :my-age="age"></my-component>
        </div>
        <template id="myComponent">
            <div>
                子组件数据:
                <p>name:{{myName}}</p>
                <p>name:{{myAge}}</p>
            </div>
        </template>
        <script>
            new Vue({
                el:'#app',
                data:{
                    name:'kkkk',
                    age:20
                },
                components: {
                    'my-component':{
                        template:'#myComponent',
                        props:['myName','myAge']
                    }
                }
            })
        
        </script>
    </body>
    
    </html>
    
    在子组件中定义prop时,使用了camelCase命名法。由于HTML特性不区分大小写,camelCase的prop用于特性时,需要转为 kebab-case(短横线隔开)。
    例如,在prop中定义的myName,在用作特性时需要转换为my-name
    
    
    父组件访问子组件:使用$children或$refs
    子组件访问父组件:使用$parent
    子组件访问根组件:使用$root
    
    $children示例:
    
    <!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>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
        <style>
        </style>
    </head>
    <body>
        <div id="app">
            <parent-component></parent-component>    
        </div>
        <template id="parent-component">
            <div>
               <child-component1></child-component1>
                <child-component2></child-component2>
                <button @click="showChildComponentData">显示子组件数据</button>  
            </div>  
        </template>
        <template id="child-component1">
            <h2>child-component1 data: {{msg}}</h2>
        </template>
        <template id="child-component2">
             <h2>child-component2 data: {{msg}}</h2>
        </template>
        <script>
            Vue.component('parent-component', {
                template:'#parent-component',
                components: {
                    'child-component1':{
                        template:'#child-component1',
                        data:function(){
                            return {
                                msg: 'child-component1'
                            }
                        }
                    },
                    'child-component2':{
                        template:'#child-component2',
                        data:function(){
                            return {
                                msg: 'child-component2'
                            }
                        }
                    }
                },
                methods: {
                    // 在父组件中,通过this.$children可以访问子组件。
                    // this.$children是一个数组,它包含所有子组件的实例。
                    showChildComponentData: function(){
                        for(var i= 0; i < this.$children.length; i++) {
                            (this.$children[i].msg)
                        }
                    }
                }
            })
            new Vue({
                el:'#app',
            })
        
        </script>
    </body>
    
    </html>
    
    
    $refs示例:
        
    组件个数较多时,在子组件上使用v-ref指令,可以给子组件指定一个索引ID
    ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例:
    $refs 也不是响应式的,因此你不应该试图用它在模板中做数据绑定。
    <!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>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
        <style>
        </style>
    </head>
    
    <body>
        <div id="app" class="common">
            <parent-component></parent-component>    
        </div>
    
        <template id="parent-component">
             <div>
                <child-component1 ref="comp1"></child-component1>
                <child-component2 ref="comp2"></child-component2>
                <button @click="showChildComponentDataRef">显示子组件数据ref</button>  
             </div>
        </template>
        <template id="child-component1">
            <h2>child-component1 data {{msg}}</h2>
        </template>
        <template id="child-component2">
             <h2>child-component2 data {{msg}}</h2>
        </template>
        <script>
            Vue.component('parent-component', {
                template:'#parent-component',
                components: {
                    'child-component1':{
                        template:'#child-component1',
                        data:function(){
                            return {
                                msg: 'child-component1'
                            }
                        }
                    },
                    'child-component2':{
                        template:'#child-component2',
                        data:function(){
                            return {
                                msg: 'child-component2'
                            }
                        }
                    }
                },
                methods: {
                    showChildComponentDataRef: function() {
                        console.log(this.$refs,'refs')
                        alert(this.$refs.comp1.msg);
                        alert(this.$refs.comp2.msg);
                    }
                }
            })
            new Vue({
                el:'#app',
            })
        </script>
    </body>
    
    </html>
    
    
    
    在子组件中,通过this.$parent可以访问到父组件的实例,推荐 -只有组件自己能修改它的状态
    <!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>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
        <style>
        </style>
    </head>
    
    <body>
        <div id="app">
            <parent-component></parent-component>    
        </div>
    
        <template id="parent-component">
             <div>
                <child-component></child-component>
             </div>
        </template>
        <template id="child-component">
            <div>
                <h2>child-component</h2>
                <button @click="showChildComponentDataParent">显示父组件数据</button>  
            </div>
        
        </template>
    
        <script>
            Vue.component('parent-component', {
                template:'#parent-component',
                components:{
                    'child-component':{
                        template:'#child-component',
                        methods: {
                            showChildComponentDataParent() {
                                // 尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据
                                // 推荐:只有组件自己能修改它的状态
                                console.log(this.$parent)
                                alert(this.$parent.msg)
                            }
                        }
                    }
                },
                data:function(){
                    return {
                        msg:'i am parent component data'
                    }
                }    
                })
            new Vue({
                el:'#app',
            })
        
        </script>
    </body>
    
    </html>
    
    
    自定义事件:
    
    有时候我们希望触发父组件的某个事件时,可以通知到子组件;触发子组件的某个事件时,可以通知到父组件。
    Vue 实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,用法也不同。
    // 每个vue实例都是一个事件触发器:使用$on()监听事件;使用$emit()在它上面派发事件;使用$dispatch()派发事件,事件沿着父链冒泡;使用$broadcast()广播事件,事件向下传导给所有的后代
    
    // ps $dispatch()  $broadcast()  已弃用
    
    
    
    
    vue.js 组件的api来源于:prop slot  事件
    
    prop允许外部环境传递数据给组件
    事件允许组件触发外部环境的action
    slot允许外部环境插入内容到组件的视图结构内
    

      

    <!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>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
        <style>
            .red{
                background: skyblue;
            }
        </style>
    </head>
    
    <body>
        <div id="app" class="common">
            <my-component></my-component>
        </div>
        // 二者等价
        <template id="myComponent">
            <div>This is a component1!</div>
        </template>
        <-- <script type="text/x-template" id="myComponent">
            <div>This is a component2!</div>
        </script> -->
        <script>
            // Vue.component()的第1个参数是标签名称,第2个参数是一个选项对象,使用选项对象的template属性定义组件模板
           Vue.component('my-component', {
            // 模板id
               template:`#myComponent`
           })
    
            new Vue({
                el:'#app'
            })
        
        </script>
    </body>
    
    </html>
    
    template选项现在不再是HTML元素,而是一个id,Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译。如果使用<template>标签,则不需要指定type属性。
    使用<script>标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script>标签内定义的内容。
    
    ps:二者等价,选其一就可以了
        <template id="myComponent">
            <div>This is a component1!</div>
        </template>
        与
           <script type="text/x-template" id="myComponent">
            <div>This is a component2!</div>
        </script>
    

      

    5—组件中的data必须是函数

       每个组件是相互独立的,如果它们共用一个对象,在更改一个组件数据的时候,会影响其他组件。如果是函数的话,每个组件都会有自己独立的数据,相互之间不会影响。

    6—受限制的元素

       DOM模板解析:vue是在浏览器解析和标准化html后才获取模板内容,所以有些元素限制了能被它包裹的元素。如ul里只能放li

       某些元素中放入了自定义属性,不符合W3C标准,会解析错误。变通的方式:使用特殊属性is来扩展HTML标签功能。

     

    7-单向数据流

       数据从父组件流向(传递)子组件,只能单向绑定。在子组件内部不应该修改父组件传递过来的数据。

    改变prop的情况:

     作为data中局部数据的初始值使用;作为子组件中的computed属性。

    8-props验证

      组件可以为props指定验证要求,如果未指定验证要求,vue会发出警告。

    Props:{
    
      propA:Number,  //指定类型
    
      propB:[String,Number],//多种类型
    
      propC:[type:String,required:true], //必传,且为字符串
    
      propD:[type:Number,default:100],//数字类型,默认100
    
      propE:{type:Number,default:function(){
    
       return 1000
    
    }},
    
    //自定义验证规则
    
    propF:{validator:function(value){return value>10}}
    
    }
    

       

    9-使用slot分发内容

      使用一种方式混合父组件的的内容与子组件自己的模板,这个过程被称为内容分发。在子组件中使用特殊的<slot>元素作为内容的插槽。这样可使组件的可扩展性更强。

    单个slot:

      在子组件模板中有slot标签,被视为备用内容,在父组件不提供内容的情况下使用,如果父组件提供内容,则把整个内容片段插入到slot所在的dom位置,并替换掉slot标签本身。

      子组件模板中没有slot标签,父组件提供的内容会被抛弃。
    <div id="app"> 
        <h2>自定义组件</h2> 
        <custom> 
            <!--当写在自定义标签之间的内容,要混合子组件中的模板--> 
            <div>我是html结构</div> 
        </custom> 
    </div> 
    <script> 
        //定制模板div 
        Vue.component("custom",{ 
            template:` 
             <div> 
                <slot>//该标签内的内容将会被我是html结构覆盖掉 
                <p>这是第1个提醒</p> 
                <p>这是第2个提醒</p> 
                <p>这是第3个提醒</p> 
                </slot> 
             </div> 
            ` 
        }) 
        new Vue({ 
            el:"#app" 
        }); 
    </script>
    

      

    <body> 
    <div id="app"> 
        <h2>自定义组件</h2> 
        <custom> 
            <!--当写在自定义标签之间的内容,要混合子组件中的模板--> 
            <div>替换第1个提醒</div> 
            <div>替换第2个提醒</div> 
            <div>替换第3个提醒</div> 
        </custom> 
    </div> 
    <script> 
        //定制模板div 
        Vue.component("custom",{ 
            template:` 
             <div> 
                <slot> 
                <p>这是第1个提醒</p> 
                <p>这是第2个提醒</p> 
                <p>这是第3个提醒</p> 
                </slot> 
             </div> 
            ` 
        }) 
        new Vue({ 
            el:"#app" 
        }); 
    </script> 
    </body>
    

      

    具名slot:

      <slot>元素可以用一个特殊的属性name来配置如何分发内容。

      可以使用一个匿名的slot,处理那些没有对应slot的内容
    <div id="app"> 
        <h2>自定义组件</h2> 
        <custom> 
            <!--当写在自定义标签之间的内容,要混合子组件中的模板--> 
            <div slot="one">替换第1个提醒</div> 
            <div slot="three">替换第3个提醒</div> 
            <template slot="two"> 
                <div>替换第2个提醒</div> 
                <span>替换第2个提醒</span> 
                <div>替换第2个提醒</div> 
            </template> 
        </custom> 
    </div> 
    <script> 
        //定制模板div 
        Vue.component("custom",{ 
            template:` 
             <div> 
             <slot name="one"><p>这是第1个提醒</p></slot> 
             <slot name="two"><p>这是第2个提醒</p></slot> 
             <slot name="three"><p>这是第3个提醒</p></slot> 
             </div> 
            ` 
        }) 
        new Vue({ 
            el:"#app" 
        }); 
    </script>

    编译作用域:

      父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

    <!DOCTYPE html> 
    <html> 
    <head lang="en"> 
        <meta charset="UTF-8"> 
        <title></title> 
        <script src="vue.js"></script> 
    </head> 
    <body> 
    <div id="app"> 
        <custom>  <!--这里渲染的数据是父组件中的数据--> 
            {{message}} 
        </custom> 
    </div> 
    <script> 
        Vue.component("custom",{  //子组件 
            data(){ 
              return { 
                  message:"我是子组件的数据" 
              } 
        }, 
        template:` 
           <div> 
              {{message}}  <!--这里是渲染子组件里的数据--> 
                <p>我是第1个提醒</p> 
                <slot></slot> 
           </div> 
        ` 
        }) 
        new Vue({   //父组件 
            el:"#app", 
            data:{ 
                message:"我是父组件的数据" 
            } 
        }); 
    </script> 
    </body> 
    </html>
    

    10. 获取url中参数:

      通过路由跳转的页面交互,可通过this.$route.query或this.$route.params获取url中地址参数

      


    ps:看的东西有点杂,且是之前的word笔记后更新到博客,除了官网,想不起来具体参考哪些了各路大神了,如有雷同,欢迎指出。

    宝剑锋从磨砺出,梅花香自苦寒来。
  • 相关阅读:
    C#中的String.Format()方法
    JQuery中的each方法
    [开发笔记]-使用jquery获取url及url参数的方法
    ThinkPHP3.2.3学习笔记3---视图
    PHP命名空间namespace使用小结
    ThinkPHP3.2.3学习笔记2---模型
    PHP中的连贯操作
    关于新技术的学习问题
    ThinkPHP3.2.3学习笔记1---控制器
    WinXP下如何安装及御载MySQL服务
  • 原文地址:https://www.cnblogs.com/haimengqingyuan/p/6934380.html
Copyright © 2011-2022 走看看