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可以提高性能,它把元素存入內存,方便下次調用
發佈了134 篇原創文章 · 獲贊 165 · 訪問量 139萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章