vue基础-组件总结

一,组件细节

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue组件细节</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!--is,既保证正确使用组件,又保证符合html5的编码规范-->
            <!--直接写<row></row>组件标签,dom元素会错位-->
            <!--所谓html5的编码规范,就是tbody下必为tr标签,ul下必为li标签,select下必为option等-->
            <table>
                <tbody>
                    <tr is='row'></tr>
                    <tr is='row'></tr>
                    <tr is='row'></tr>
                </tbody>
            </table>
            <!--ref引用,用于dom -->
            <div
                ref='hello'
                @click="handleClick"
            >
                hello world
            </div>
            <!--ref引用,用于组件 -->
            <counter ref="one" @change="handleChange"></counter>
            <counter ref="two" @change="handleChange"></counter>
            <div>{{total}}</div>
        </div>
        <!-- 子组件data必须为函数,便于独立每个子组件的数据-->
        <script>            
            Vue.component('row',{
                data:function(){
                    return {
                             content: 'this is content'
                    }
                },
                template:'<tr><td>{{content}}</td></tr>'
            })

            Vue.component('counter',{
                data:function(){
                    return {
                             number: 0
                    }
                },
                template:'<div @click="handleCounter">{{number}}</div>',
                methods:{
                    handleCounter: function(){
                        this.number ++
                        this.$emit('change')
                    }
                }

            })
            var vm = new Vue({
                el:'#root',
                data:{
                    total: 0    
                },
                methods:{
                    handleClick:function(){
                        console.log(this.$refs.hello.innerHTML)
                    },
                    handleChange:function(){
                        this.total = this.$refs.one.number + 
                        this.$refs.two.number
                    }
                }
            })
        </script>
    </body>
</html>

2,总结

  • is,既保证正确使用组件,又保证符合html5的编码规范

    • 直接写<row></row>组件标签,dom元素会错位
    • 所谓html5的编码规范,就是tbody下必为tr标签,ul下必为li标签,select下必为option等
  • 子组件data必须为函数,便于独立每个子组件的数据

  • ref引用可以用于dom元素,也可用于组件,再进行对元素或组件的操作

二,父子组件传值

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue父子组件传值</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 父->子 通过属性传值,子组件只能使用父组件传来的值,不能直接修改,可以复制为自己的参数再修改  -->
            <counter :count="1" @inc="handleIncrease"></counter>
            <counter :count="2" @inc="handleIncrease"></counter>
            <div>{{total}}</div>
        </div>
        <!-- 子->父 通过$emit传值 -->
        <script>            
            var counter = {
                props: ['count'],
                data: function(){
                    return {
                        number : this.count
                    }
                },
                template: '<div @click="handleClick">{{number}}</div>',
                methods:{
                    handleClick: function(){
                        this.number = this.number + 2;
                        this.$emit('inc' ,2)
                    }
                }
            }

            var vm = new Vue({
                el:'#root',
                data:{
                    total: 5
                },
                components:{
                    counter: counter
                },
                methods:{
                    handleIncrease:function(step){
                        this.total += step
                    }
                }
            })

        </script>
    </body>
</html>

2,总结

  • 父->子 通过属性传值。(子组件只能使用父组件传来的值,不能直接修改,可以复制为自己的参数再修改)
  • 子->父 通过$emit传值。

三,组件参数检验与非props特性

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件参数检验与非props特性</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 设置参数检验,字符串和数字可以 -->
            <child content="abc"></child>
            <child :content="1"></child>
            <child :content="'abc'"></child>
            <!--<child :content="{1}"></child>-->
        </div>
        <!--type参数类型,required是否传参,default默认值,validator参数校验方法 -->
        <!--非props特性就是没有props,不接收参数,父组件传的属性参数直接在子组件template中显示-->
        <script>            
            Vue.component('child',{
                props:{
//                  content: [String, Number]
                    content:{
                            type: [String, Number],
                            required: false,
                            default: 'default value',
                            validator:function(value){
                                     return (value.length > 5)
                            }
                    }
                },
                template:'<div>{{content}}</div>'
            })

            var vm = new Vue({
                el: '#root'
            })

        </script>
    </body>
</html>

2,总结

  • type参数类型,required是否传参,default默认值,validator参数校验方法
  • 非props特性就是没有props,不接收参数,父组件传的属性参数直接在子组件template中显示(没啥用)

四,给组件绑定原生事件

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>给组件绑定原生事件</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <div id="root">
            <child @click.native="handleClick"></child>
        </div>

        <script>            
            Vue.component('child',{
//              template:'<div @click="handleChildClick">child</div>',
//              methods:{
//                  handleChildClick:function(){
//                      alert('child click')
//                      this.$emit('click')
//                  }
//              }
                template:'<div>child</div>',
                methods:{
                    handleChildClick:function(){
                        alert('child click')
                    }
                }
            })

            var vm = new Vue({
                el: '#root',
                methods:{
                    handleClick:function(){
                        alert('click')
                    }
                }
            })

        </script>
    </body>
</html>

2,总结

  • native绑定原生事件可以代替从子组件事件跳转到父组件事件的过程

五,非父子组件传值

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>非父子组件传值(Bus/总线/发布订阅模式/观察者模式)</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <div id="root">
            <child content="dell"></child>
            <child content="lee"></child>
        </div>

        <script>            
            Vue.prototype.bus = new Vue()       

            Vue.component('child',{
                data:function(){
                    return{
                        selfContent: this.content
                    }
                },
                template:'<div @click="handleClick">{{selfContent}}</div>',
                props:{
                    content:String
                },
                methods:{
                    handleClick:function(){
                        this.bus.$emit('change',this.selfContent)
                    }
                },
                mounted:function(){
                    var this_ = this
                    this.bus.$on('change',function(msg){
                        //this的作用域变成function内了
                        //所以在外部提前引用
                        this_.selfContent = msg
                    })
                }
            })

            var vm = new Vue({
                el: '#root',
                methods:{
                    handleClick:function(){
                        alert('click')
                    }
                }
            })

        </script>
    </body>
</html>

2,总结

  • bus.$emit发送,bus.$on监听

六,vue的插槽(slot)

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue的插槽(slot)</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <!--可以用属性传dom元素,复杂情况要用插槽-->
        <!--如果插槽不命名,组件内整个dom元素,传入插槽-->
        <!--插槽内可设默认值<slot name='header'>default header</slot>,
            如果没有<div class="header" slot='header'>header</div>的引用,
            则会取默认值-->
        <div id="root">
            <body-content>
                <child content="<p>dell</p>"></child>
                <div class="header" slot='header'>header</div>
                <div class="footer" slot='footer'>footer</div>
            </body-content>
        </div>

        <script>        
//          Vue.component('child',{
//              props:['content'],
//              //用顿号可以格式化dom,不用每行都加了
//              template:`<div>
//                           <p>hello</p>
//                           <div v-html="this.content"></div>
//                        </div>`
//          })

            Vue.component('body-content',{
                template:`<div>
                             <slot name='header'></slot>
                             <div class='content'>content</div>
                             <slot name='footer'></slot>
                          </div>`
            })

            var vm = new Vue({
                el: '#root'
            })

        </script>
    </body>
</html>

2,总结

  • 可以用属性传dom元素,复杂情况要用插槽
  • 如果插槽不命名,组件内整个dom元素,传入插槽
  • 插槽可设默认值

七,vue的作用域插槽

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue的作用域插槽</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <!--子组件向父组件传值,通过slot-scope,
            由父组件去定义item。
            template固定写法
        -->
        <div id="root">
            <child>
                <template slot-scope="props">
                    <h1>{{props.item}}</h1>
                </template>
            </child>
        </div>

        <script>        
            Vue.component('child',{
                data:function(){
                    return{
                        list:[1,2,3,4]
                    }
                },
                template:`<div>
                            <ul>
                             <slot v-for="item of list"
                                   :item=item
                             >
                             </slot>
                            </ul>
                          </div>`
            })

            var vm = new Vue({
                el: '#root'
            })

        </script>
    </body>
</html>

2,总结

  • 子组件向父组件传值,通过slot-scope,
  • 由父组件去定义item。
  • template固定写法

八,动态组件与v-once指令

1,代码测试

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>动态组件与v-once指令</title>
        <script src="vue.js"></script>
    </head>
    <body>
        <!--动态组件可以根据组件的名称进行切换组件-->
        <!--v-once可以提高性能,它把元素存入内存,方便下次调用-->
        <div id="root">
            <component :is="type"></component>
            <!--<child-one v-if="type === 'child-one'"></child-one>
            <child-two v-if="type === 'child-two'"></child-two>-->
            <button @click="handleBtnClick">change</button>
        </div>

        <script>        
            Vue.component('child-one',{
                template:'<div v-once>child-one</div>'
            })

            Vue.component('child-two',{
                template:'<div v-once>child-two</div>'
            })

            var vm = new Vue({
                el: '#root',
                data:{
                    type:'child-one'
                },
                methods:{
                    handleBtnClick:function () {
                        this.type = this.type === 'child-one' ? 
                            'child-two':'child-one';
                    }
                }
            })

        </script>
    </body>
</html>

2,总结

  • 动态组件可以根据组件的名称进行切换组件
  • v-once可以提高性能,它把元素存入内存,方便下次调用

猜你喜欢

转载自blog.csdn.net/superjunjin/article/details/80349228
今日推荐