vue實用難點講解

此篇文章是我基於研究vue文檔三遍的基礎上,以爲還有點難理解或者難記的知識點總結

  1. 列表渲染css

    1.渲染組件必須加key,而且屬性是手動傳遞給組件的
        <my-component
            v-for="(item, index) in items"
            v-bind:item="item"
            v-bind:index="index"
            v-bind:key="item.id">
        </my-component>
    2.v-for和v-if用在同一個節點上面,會先執行v-for而後再執行v-if
    3.使用v-for最好加上key值,由於vue自己是基於就地更換的原則,也就是你在1-100之間再插入一個數值好比5,那麼原來的5和後面的數據都會依次加一,這樣的效率是很是低的,若是你傳遞了key作惟一的標識,那麼插入的5就插在4後面了,後面的數據就不變了,只是位置挪了下
  2. 事件對象html

    • 要使用事件對象,必須在調用的時候傳遞$event,不能是其餘的名字
    • 經常使用的事件修飾符vue

      .stop 阻止冒泡
      .prevent 阻止默認行爲
      .capture 使用事件捕獲
      .self 自身觸發
      .once 觸發一次
    • 按鍵修飾符node

      .enter
      .tab
      .delete
      .esc
      .space
      .up
      .down
      .left
      .right
      自定義修飾符 Vue.config.keyCodes.f1 = 12
    • 鼠標按鍵修飾符react

      .left
      .right
      .middle
  3. 表單webpack

    表單修飾符
    .lazy v-model默認是監聽oninput事件的加上這個修飾符,就是監聽onchange事件 <input v-model.lazy="msg" >
    .number 將用戶輸入值轉換成數字
    .trim 自動將用戶輸入的首尾空格去掉
  4. 組件通訊git

    1.父組件傳遞信息給子組件
        子組件要想獲得父組件的數據,只須要在子組件內部經過props顯示的聲明本身想要什麼屬性,是否是有點意思,就像女的問男的要東西同樣,我要lv包包。聲明以後父組件將數據傳遞給子組件就ok了,以下
            Vue.component('child',{
                props: ['message','myMessage'],
                template: '<span>{{ message }}</span>'
            })
            在父組件中使用 <child message="hello!" :my-message="parentMsg"></child> 便可
        注意:在子組件中不能修改父組件傳遞過來的數據,只能作備份來修改,而且引用類型要深拷貝
    2.在父組件中經過傳遞非props屬性,將自動添加到子組件根元素上面,以下
        <bs-date-input data-3d-date-picker="true"></bs-date-input>
        若是子組件上面已經存在了同名屬性,通常都是直接替換的,可是class和style是和子組件的class和style合併的
    3.子組件通知父組件
        在子組件中觸發某個事件同時v-on:click="childfunciton",能夠經過在childfunction內部添加this.$emit('somefunction')通知觸發父組件中的事件,在父組件中經過v-on:somefunction="parentfunction"接受到通知,而後觸發父組件中的parentfunction事件,也就是說在父組件中,將v-on用在子組件標籤上面並非給子組件綁定事件而是監聽子組件內部的消息,可是若是確實想綁定一個事件給子組件能夠經過添加.native修飾符,以下
        <my-component v-on:click.native="doTheThing"></my-component>這個事件將直接綁定到子組件的根元素
    4.子組件父組件數據雙向綁定
        在父組件中的子組件標籤上綁定屬性使用.sync修飾符,便可完成數據雙向綁定,以下
        <child :foo.sync="bar"></child>
        在parent組件內部定義bar屬性,便可將bar值實時的經過foo傳遞給子組件
        在子組件內部經過this.$emit('update:foo','hahahha');能夠在任意時刻修改父組件中的bar值,此函數內部其實執行的是 bar => bar = val,實際上就是直接給bar賦值,可是隻能採用這種方式
    5.其實上面說的組件通訊仍是基礎的,下面來看一個高級點的
        <input v-model="something">
        v-model其實,就是下面的簡寫形式
        <input v-bind:value="something" v-on:input="something =  $event.target.value">
        一樣v-model也能夠用在組件身上,就是以下的樣子了
        <custom-input :value="something" @input="value => { something = value }"></custom-input>
        因此知道這上面兩點就能夠實現自定義組件v-model功能了
        下面是child.vue的代碼
            <div>
                <input type="text" :value="value" @input="updateValue($event.target.value)">
                {{value}}
            </div>
            export default {
                props: ['value'],
                methods: {
                    updateValue(value){
                        this.$emit('input',value)
                    }
                },
            }
        下面是father.vue的代碼
            <child v-model="price"></child>
            data () {
                return {
                    price: ''
                }
            }
        在子組件中的input中輸入數據,能夠動態的反應到父組件中,實現雙向綁定
        因爲默認是value和input若是想改變這個默認的,能夠在子組件中,使用model以下
            在子組件中聲明
            model: {
                prop: 'checked',
                event: 'change'
            },
            props: {
                checked: Boolean,
                value: String
            }
        因此使用<my-checkbox v-model="foo" value="some value"></my-checkbox>其實就是下面的簡寫
        <my-checkbox :checked="foo" @change="val => { foo = val }" value="some value"></my-checkbox>
    6.非父子組件之間的通訊
        非父子組件之間的通訊就要使用$on了
        首先要有一個空的vue實例
            var bus = new Vue();
            若是你使用vue的webpack項目的話,這個東西你要單獨的加在一個js文件中以store.js爲例,添加以下代碼
                import Vue from 'vue'
                window.bus = new Vue();
            而且還要在main.js中經過import './store.js'導入,這時就能夠在vue項目全局使用bus了
        若是在一個組件中須要傳遞消息,就使用bus.$emit('fn', 1)傳遞數據
        在要接受數據的組件中使用,bus.$on('fn',function(value){...})便可
    講到這兒,vue最核心的部分也就將完了,弄懂這塊兒東西,相信後面的學習就易如反掌了
    7.使用slot實現內容分發
        實際工做中組件的組成大多數是相似下面的
            <parent>
                <child>
                    <someother-component></someother-component>
                </child>
            </parent>
        slot的做用就是用來處理嵌套在組件標籤內部的內容
    8.單一slot
        若是隻有一個slot標籤而且沒有任何屬性,slot標籤將會被所有替換成嵌套在組件標籤內部的內容,若是slot標籤自身包裹內容,這個內容只會在組件標籤內部不包含任何東西的時候展現,demo以下
            若是一個child組件的模板內容以下
            <div>
                <h2>I'm the child title</h2>
                <slot>
                    這裏面的內容只會在沒有插入內容時顯示
                </slot>
            </div>
            而後<child>hahahhahahah</child>
            那麼hahahhahahah就會替換slot成爲child模板的一部分
    9.命名slot
        能夠給slot起個名字,好比<slot name="header"></slot>
        而後給組件標籤內容添加slot屬性,屬性值和上面的名字相同,就能夠實現特殊指派了,如
        <child>
            <h1 slot="header">指定的內容</h1>
        </child>
        這樣就實現的需求導入了
    10.局部slot
        上面講的slot都是能夠實現父組件傳遞數據到子組件中,如今想實現將子組件中的數據傳遞到slot要替換的內容中
        能夠在子組件中的slot插槽中添加任意屬性,如 <slot text="子組件child中的數據"></slot>
        而後,在子組件標籤內部,以下
            <parent>
                <child>
                    // 必須使用template標籤,而且添加scope屬性,屬性值props就是包含slot傳遞的數據對象
                    <template scope="props">
                        <span>父組件parent中的數據</span>
                        <span>{{props.text}}</span>
                    </template>
                </child>
            </parent>
    11.動態組件
        可使用同一個綁定點,動態的切換渲染不一樣的組件,要實現這個功能要藉助component標籤和is屬性
            <component :is="currentView"></component>    
            vue實例代碼以下
            var vm = new Vue({
                el: "#example",
                data: {
                    currentView: 'home'
                },
                components: { home,posts,archive }
            })    
            經過改變currentView的值,能夠實現動態切換組件   
        上面這種寫法能夠知足局部組件,也就是你本身定義的組件的切換,可是若是你使用全局組件,好比某些UI組件庫中的組件,那麼就要像下面這樣用
            var Home = {
                template: ...
            };
            var vm = new Vue({
                el: "#example",
                data: {
                    currentView: Home
                }
            });
        若是你想將切換渲染過的組件保留在內存中可使用keep-alive將動態組件包裹
            <keep-alive>
                <component :is="currentView">
                    ...
                </component>
            <keep-alive>
  5. vue動畫效果github

    **vue的過渡
    過渡通常用於元素的插入,刪除,移除
    下面講解過渡的知識
        1.對單個的元素或者組件使用過渡
            使用transition標籤包裹要應用過渡的元素
            <transition name="fade">
                <p v-if="show">hello</p>
            </transition>
            當上面的p元素在顯示和隱藏中間切換時,會發生如下事情
            第一,檢測目標元素,自動添加或移除css過渡類名
            第二,執行transition的鉤子函數
            第三,若是上面兩步驟都沒有對應的設置,那麼不會應用過渡效果
        2.過渡的類名
            v-enter 進入的開始狀態,在元素插入以前添加,在元素插入以後刪除
            v-enter-active 整個進入過程的狀態,連續的畫面,這個類就是用來定義動畫的持續時間,延遲和線性函數的
            v-enter-to 進入的結束狀態,在元素插入以後添加,在整個enter-active結束後刪除
            v-leave 消失的開始狀態
            v-leave-active 整個消失的過程
            v-leave-to 消失的結束狀態
            上面的這些類名的v是默認的前綴,你能夠給transition標籤指定name屬性,用來自定義類名前綴
            上面提到的元素的插入和移除就是頁面上dom元素的一瞬間的狀態
        3.css過渡
            就是指定好開始和結束的css樣式,而後定義動畫的執行過程,以下所示
                .v-enter-active,.v-leave-active{
                    transition: all .3s ease;
                }
                .v-enter,.v-leave-to{
                    transform: translateX(10px);
                    opacity: 0;
                }
        4.css動畫
            上面都是應用的transition,這裏是animation,其實相似
                .v-enter-active{
                    animation: bounce-in .5s;
                }
                .v-leave-active{
                    animation: bounce-in .5s;
                }
                @keyframes bounce-in {
                    0% {
                        transform: scale(0);
                    }
                    50% {
                        transform: scale(1.5);
                    }
                    100% {
                        transform: scale(1);
                    }
                }
        5.css過渡類名
            若是你使用animate.css這類的第三方css庫,能夠藉助以下的類名
                enter-class
                enter-active-class
                enter-to-class
                leave-class
                leave-active-class
                leave-to-class
            使用demo
                <transition
                    enter-active-class="animated tada"
                    leave-active-class="animated bounceOutRight"
                >
                    <p v-if="show">hello</p>
                </transition>
        6.如何區分animation和transition
            當你的動畫中同時使用transition形式和animation形式的動畫,必須添加type屬性,指定屬性值爲animation或者transition
        7.指定動畫持續時間
            vue默認的動畫持續時間是基於根過渡元素,內部的子過渡元素的持續時間若是長於根過渡元素將會被忽略,因此能夠在transition標籤上面添加duration屬性,demo以下
                <transition :duration="1000">...</transition>
                <transition :duration="{enter: 500,leave: 800}"></transition>
        8.添加動畫鉤子函數,這部份內容用的比較少,感興趣自行了解
        9.對初次渲染的元素添加過渡
            添加appear屬性 <transition appear> </transition>
            添加這個屬性以後,會自動應用以前指定好的enter和leave的動畫,若是想實現單獨的動畫功能可使用以下的方式
                <transition
                    appear
                    appear-class="..."
                    appear-to-class="..."
                    appear-active-class="..."
                ></transition>
        10.在多個元素中應用過渡
            上面討論的都是基於單個過渡元素,下面討論多個元素的過渡
            通常使用v-if/v-else在元素以前切換,相同的元素在切換的時候回覆用,因此要添加key屬性,以下
                <transition>
                    <button v-if="isEditing" key="save">
                        Save
                    </button>
                    <button v-else key="edit">
                        Edit
                    </button>
                </transition>
            此外,很能夠添加mode屬性,用來指定顯示和隱藏的前後順序
                in-out 先入後出
                out-in 先出後入
        11.列表過渡
            上面講的都是一次過渡一個元素,如今講一次過渡多個元素
            過渡多個元素就要藉助transition-group而且還要給須要過渡的元素添加key屬性,能夠給transition-group標籤添加tag屬性,指定具體渲染後的元素,還能夠添加.v-move類,當元素的位置變化了,自動添加此類,此動畫功能只適用於非display: inline元素
    **過渡state數據
        能夠對數字型的數據,顏色值,這類的數據作過渡效果,主要是配合第三方庫來作的,感興趣的本身去看吧
  6. render函數web

    講實話這部份內容在實際使用中,幾乎用不上,我的感受vue的單文件組件,已經替代了這個的功能,因此說強大的jsx功能在vue中可能就是一個擺設而已,這也是爲何高端互聯網企業選擇react的緣由了吧
    vue的render函數說白了就是用js編寫html,說實話和jsx比起來,render是很是麻煩的
    vue中寫render就不須要template選項了
        Vue.component('demo-render',{
            render: function(createElement){
                // 這個函數的結果就是組件的template
                return createElement(
                    // 這個函數接受三個參數
                    'div', 能夠是組件也能夠是html標籤
                    {}, 當前vnode的屬性對象,這個屬性對象的介紹請看下面
                    [] 字符串或者數組均可以,子節點,若是子節點下面還有子節點能夠再次調用createElement方法
                )
            }
        })
    屬性對象的介紹
        {
            'class': {//v-bind:class},
            style: {//v-bind:style},
            attrs: {//正常的html屬性如id這類的},
            props: {//當前的節點是另一個組件的話,這個就是傳遞給組件的屬性對象},
            domoProps: {//Dom節點的屬性對象好比innerHTML},
            on: {//v-on: 不支持修飾符},
            nativeOn: {// 只能在當前的節點是其它組件的時候生效},
            directives: [//自定義指令],
            slot: 'somename', //指定slot標籤,用於插入內容,屬性值是slot的name屬性值
            scopedSlots: {
                // 說實話這個東西對於初學者是很難懂的,我也是看了不少遍才明白
                /*
                 局部插槽顧名思義,其實就是用來給子組件使用的,因此這部份內容就直
                 接放在render裏面編寫
                 default: props => createElement('span',props.text);
                 上面的代碼和下面的原始寫法是表達的意思是如出一轍的
                    <template scope="props">
                        <span>{{props.text}}</span>
                    </template>
                */
            },
            key: 'myKey', 就是key屬性
            ref: 'myRef' 當前vnode的引用
        }
    使用render的注意點
        全部的render內部使用的vnode必須都是獨一無二的,不一樣使用相同vnode的引用
        能夠在vue中使用jsx代替你,render函數的複雜寫法,例子以下
            render (h) {
                return (
                    <AnchoredHeading level={1}>
                        <span>Hello</span> world!
                    </AnchoredHeading>
                )
            }
            這就是jsx語法,通俗易懂
            具體的學習地址https://github.com/vuejs/babel-plugin-transform-vue-jsx#usage
        建議:
            若是你被jsx的魅力所吸引,我我的以爲仍是去學react的吧,在vue中的單文件組件徹底能夠知足你的項目開發需求,若是你在.vue文件中使用jsx或者render會變得很是奇怪,在template中使用html又在js中使用html簡直就是怪胎
  7. 自定義指令數組

    說實話,這部份內容我不太想寫出來,一門技術總有好的和壞的反面,偶爾瞭解一些不太好的東西,對本身學習其餘知識,能夠擴展視野
    這部份內容就是本身寫一個指令好比v-myDirective,而後利用vue提供的鉤子函數,在合適的時機觸發他們。簡單demo以下
        Vue.directive('focus',{
            // 全局指令
        })或者
        directive: {
            focus: {
                // 局部指令
                // 能夠在這裏面指定鉤子函數,表示在什麼時候執行這些鉤子函數
                // 說白了就是利用元素的生命週期鉤子實現所謂的自定義指令和vue實例的生命週期鉤子本質是同樣的,呵呵
                bind: function(// 全部的鉤子函數在這裏面均可以傳遞參數,參數後面講){// 當指令綁定到元素上執行,只執行一次},
                inserted: // 元素插入的時候執行,
                update: // 元素自身更新,執行,
                componentUpdated: // 子組件更新執行,
                unbind: // 解綁的時候執行
            }
        }
        具體使用,就在須要的元素上面直接寫上指令名稱便可 <input v-focus>
    鉤子函數的參數
        el // 綁定的dom元素
        binding // 關於指令的相關屬性對象,細節本身看
        vnode ,oldVnode // 虛擬節點對象
    這部份內容瞭解,就能夠了
  8. Mixins混入

    這部份內容用的也比較少,不過當你的組件中有不少重複的method或者其餘的選項,可使用這個減小冗餘代碼
    一個mixin對象能夠包含實例的任何選項
        var myMixin = {
            created: function(){
                this.hello();
            },
            methods: {
                hello: function(){
                    console.log('hello from mixin!')
                }
            }
        }
        var Component = Vue.extend({
            mixins: [myMixin]
        })
        var component = new Component();
    混入的規則以下
        1.鉤子函數會放進一個隊列裏面,先執行mixin對象中的鉤子,而後執行實例的鉤子
        2.methods,components,directives都會被合併成一個對象,同名的屬性只會使用組件的,捨棄掉mixin對象的
        3.全局混入
            全局混入儘可能不要用會污染全部的vue實例
                Vue.mixin({
                    created: function() {
                        ...
                    }
                })
        4.用戶自定義選項的合併
            默認是組件的直接覆蓋掉mixin對象的同名屬性
            若是想對自定義選項myOption應用自定義邏輯,可使用以下的函數  
                Vue.config.optionMergeStrategies.myOption = function(toVal,fromVal){
                    // ...
                }
            若是自定義選項是對象的話也可使用methods選項的合併規則
                var strategies = Vue.config.optionMergeStrategies;
                strategies.myOption = strategies.methods

    結語

    有能力的同窗,我建議去學學react,畢竟到這兒,vue你已經精通了

相關文章
相關標籤/搜索