Vue項目經驗

1、動態(tài)添加class或style

有時候希望根據(jù)某個狀態(tài)值來決定是否添加某個類,可以這樣:

// 數(shù)組語法
<div :class="['a',value==true?'b':'']">             //類a總是存在间唉,當value為真時類b存在
// 對象語法
<div :class="{'a':true,'b':value}">            //類a,b都由value控制
<div :style="{background:'url('+value.url+')'}">    //對于style绞灼,最好用對象語法,屬性值取自當前vue實例

2呈野、綁定事件函數(shù)

有兩種方式:

// 方式1
<div @click='handle'></div>         //handle函數(shù)的this指向當前vue實例低矮,并且會將event對象傳入handle作第一個參數(shù),通潮幻埃可用event.target獲取被點擊的DOM元素
// 方式2
<div @click='handle("param1",$event)'></div>         //handle函數(shù)的this指向當前實例军掂,也可將$event傳入handle,作用同上姆打,一般用來獲取被點擊的DOM元素

3良姆、關于箭頭函數(shù)

vue的一些配置項肠虽,如mounted,beforeRouteEnter,beforeRouteLeave等幔戏,本身是一個函數(shù),若使用箭頭函數(shù)語法税课,則其內的this對象不是當前vue實例闲延。因此這三個配置項不要用箭頭函數(shù),其它的配置項韩玩,如methods,computed,watch等接受對象作為配置的垒玲,其內的函數(shù)最好用箭頭函數(shù),另外setTimeout(fn,time)中的fn最好也用箭頭函數(shù)找颓。

4合愈、數(shù)據(jù)傳遞

1、父子組件(prop down,event up)

  • 一般而言击狮,父組件通過prop傳遞屬性給子組件佛析,子組件事先需定義props屬性,如果沒有定義props彪蓬,那這個傳遞過來的值會自動添加到子組件的根元素上寸莫;
  • 子組件中一般通過觸發(fā)某種自定義事件向父元素通信,因此一般在父元素中使用子組件的地方監(jiān)聽該事件名档冬,該事件名是自定義的膘茎,因此要與子組件的一致。
<div id="counter-event-example">
  <p>{{ total }}</p>
  <button-counter v-on:increment="incrementTotal"></button-counter>
  <button-counter v-on:increment="incrementTotal"></button-counter>
</div>
Vue.component('button-counter', {
  template: '<button v-on:click="incrementCounter">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    incrementCounter: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})
  • 如果要在父元素中使用子組件的地方監(jiān)聽原生事件酷誓,可用@click.native
  • 普通html標簽上用@click是原生事件披坏,自定義組件中用@click是自定義事件

2、非父子組件
有時候盐数,非父子關系的兩個組件之間也需要通信棒拂。在簡單的場景下,可以使用一個空的 Vue 實例作為事件總線:

var bus = new Vue()
// 觸發(fā)組件 A 中的事件
bus.$emit('id-selected', 1)
/ 在組件 B 創(chuàng)建的鉤子中監(jiān)聽事件
bus.$on('id-selected', function (id) {
  // ...
}.bind(this))//綁定作用域

5娘扩、不能觸發(fā)視圖更新的操作

  • 數(shù)組
// 無法觸發(fā)
vm.items[indexOfItem] = newValue
vm.items.length = newLength
// 可以觸發(fā)
Vue.set(example1.items, indexOfItem, newValue)
example1.items.splice(newLength)
  • 對象
var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 現(xiàn)在是響應式的
vm.b = 2
// `vm.b` 不是響應式的
var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})
Vue.set(vm.userProfile, 'age', 27) //響應式

3着茸、watch對象變化:

              'messages': {   // messages是一個數(shù)組壮锻,監(jiān)聽數(shù)組或對象的變化
            handler: function(newValue, old) {
                if (newValue.length == 0) {
                    setTimeout(() => {
                        history.back();
                    }, 1000)
                }
            },
            deep: true
        }

6、關于beforeRouteEnter和beforeRouteLeave

  • beforeRouteEnter(to,from,next) 無法訪問當前vue實例涮阔,一般用于從localStorage中讀取數(shù)據(jù)恢復頁面猜绣,比如從頁面a到b,在從b回到a敬特,若a有數(shù)據(jù)變化(ajax拉取)就更新頁面掰邢,否則不更新;或者還原當前滾動條位置
  • beforeRouteLeave(to,from,next) 可訪問當前vue實例伟阔,一般用于頁面離開時將某些狀態(tài)保存在localStorage中辣之,例如當前滾動條位置
  • 二者都必須顯示調用next函數(shù)

7、keep-alive和router-view混合使用

// 這是目前用的比較多的方式
<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>

... 
  routes: [
    { path: '/', redirect: '/index',  component: Index, meta: { keepAlive: true }},
    {
      path: '/common',
      component: TestParent,
      children: [
        { path: '/test2', component: Test2, meta: { keepAlive: true } } 
      ]
    }
    ....
    // 表示index和test2都使用keep-alive

若有三個頁面A->B->C皱炉,希望A->B時B拉新數(shù)據(jù)怀估;C返回B時B不拉新數(shù)據(jù),且保存B到C之前的位置,該如何做?
1帅掘、給B設置keepAlive:true;
2康铭、在B的beforeRouteEnter中做獲取數(shù)據(jù)的操作,該鉤子的三個參數(shù)可以判斷B的上一個頁面赌髓,從而決定是否拉數(shù)據(jù)从藤;
在B的beforeRouteLeave里用localStorage記錄位置,并清除和頁面展現(xiàn)相關的數(shù)據(jù)狀態(tài)锁蠕;
3夷野、在接口回調里最好用EventCenter這種觀察者模式來觸發(fā)數(shù)據(jù)獲取成功的事件
4、在B的mounted鉤子里接受數(shù)據(jù)獲取成功的事件匿沛,就可以拿到數(shù)據(jù)
5扫责、在B的activated鉤子里取localStorage里的位置

8、router-link常用方式

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 帶查詢參數(shù)逃呼,下面的結果為 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

//對應js
this.$route.params.userId
this.$route.query.plan

9鳖孤、過度動畫

  • 單元素過渡
    transition包一個含有v-if或v-show指令的元素就行


    動畫過程
  • 多元素過渡
    transition下只能有一個根元素,所以多元素時必須用v-if抡笼,v-else來保證只有一個苏揣,此外,多個相同標簽時推姻,最好給每個標簽設置key
  • 多組件過渡
    用動態(tài)組件即可
  • 列表過渡
    需用transition-group組件包裹平匈,被包裹元素必須設置key,其他和單元素一樣

10、數(shù)據(jù)拉取

  • 數(shù)據(jù)獲取操作最早可以放在每個組件的beforeRouteEnter里增炭,然后利用觀察者模式把數(shù)據(jù)傳到beforeMount鉤子函數(shù)里做邏輯操作
     beforeRouteEnter(to, from, next) {
        let feed_id = to.params.id;
        if (from.name != 'CommentDetail' && feed_id) {
            getArticleDetail({
                feed_id: feed_id
            }).then(res => EventCenter.$emit('renderArticle', res));

            getComment({
                feed_id: feed_id
            }).then(res => EventCenter.$emit('renderComment', res));
        }
        next();
      }

     beforeMount(){
           // 1忍燥、渲染文章詳情
       EventCenter.$on('renderArticle', res => {
            
       });
       // 2、渲染文章評論
       EventCenter.$on('renderComment', res => {
            
       })
      }  

11隙姿、插件 or 組件

對于全局使用頻率較高的最好寫成插件梅垄,而不是組件。例如loading,toast之類,若寫成組件输玷,則需要在每個父組件中引入該組件队丝,比較麻煩,寫成插件就可以直接調用

import $ from 'n-zepto';
import Vue from 'vue';
export default {
    install() {
        var timer = null;
        Vue.prototype.$alerTip = function(text, delay, options) {
            var defaultCssObject = {
                position: 'fixed',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                zIndex: 10000,
                minWidth: '1.5rem',
                margin: '0 auto',
                left: 'calc((100% - 1.5rem) / 2)',
                bottom: '1.4rem',
                borderRadius: '.1rem',
                height: '.5rem',
                lineHeight: '.5rem',
                background: '#000',
                opacity: 0.85,
                color: 'white',
            };
            var cssObject = options || defaultCssObject;
            var temp = `<div class="v-toast">${text}</div>`;
            var $div = $(temp);
            $div.css(cssObject);
            $('body').append($div);
            clearTimeout(timer);
            timer = setTimeout(() => {
                $('.v-toast').remove();
                timer = null;
            }, delay);
        }
    }
}

12欲鹏、vue父子組件生命周期執(zhí)行順序問題

父子組件鉤子執(zhí)行順序:
father created
father before mounted
son created
son before mount
son mounted
father mounted
所以机久,你在父組件 beforeMounted 中已初始化的值一定可以通過props下發(fā)到子組件

13、vue-router切換頁面滾動條位置問題

注意:scrollBehavior只有在history.pushState可用時才有效赔嚎,而該方法僅兼容到IE10(移動端可放心使用)

const router = new VueRouter({
    routes,
    scrollBehavior (to, from, savedPosition) {
        if (savedPosition) {
            return savedPosition
        } else {
            if (from.meta.keepAlive) {       // 通過meta屬性精細控制
                from.meta.savedPosition = document.body.scrollTop;
            }
            return { x: 0, y: to.meta.savedPosition || 0 }
        }
    }
})

14膘盖、vue庫的引入問題

vue提供眾多版本庫文件,在使用*.vue單文件組件的開發(fā)模式時尽狠,只需引入vue.runtime.min.js即可衔憨,該庫體積最小,不過要注意初始化vue實例時袄膏,不能用template選項,而應該換為render掺冠,其他組件中的template會被vue-loader轉化為類似h=>h(Component)這種形式沉馆,本質上是將模板編譯的時機從運行時轉移到了編譯時(只有初始化時不能用template選項,因為vue-loader 和 vue 都無法識別)

                new Vue({
            el: '#app',
            router,
            render: h => h(App)
        })
              // webpack對應修改:
                alias: {
            'vue$': 'vue/dist/vue.runtime.min.js'
        }

15德崭、三種路由鉤子執(zhí)行順序問題,
全局:beforeEach斥黑,beforeResolve,afterEach
組件:beforeRouteEnter眉厨,beforeRouteUpdate锌奴,beforeRouteLeave
路由:beforeEnter
調用要離開路由的組件守衛(wèi)beforeRouteLeave
調用全局前置守衛(wèi):beforeEach
在重用的組件里調用 beforeRouteUpdate
調用路由獨享守衛(wèi) beforeEnter。
解析異步路由組件憾股。
在將要進入的路由組件中調用beforeRouteEnter
調用全局解析守衛(wèi) beforeResolve
導航被確認鹿蜀。
調用全局后置鉤子的 afterEach 鉤子。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末服球,一起剝皮案震驚了整個濱河市茴恰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌斩熊,老刑警劉巖往枣,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡分冈,警方通過查閱死者的電腦和手機圾另,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雕沉,“玉大人盯捌,你說我怎么就攤上這事∧⒒啵” “怎么了饺著?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肠牲。 經常有香客問我幼衰,道長,這世上最難降的妖魔是什么缀雳? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任渡嚣,我火速辦了婚禮,結果婚禮上肥印,老公的妹妹穿的比我還像新娘识椰。我一直安慰自己,他們只是感情好深碱,可當我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布腹鹉。 她就那樣靜靜地躺著,像睡著了一般敷硅。 火紅的嫁衣襯著肌膚如雪功咒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天绞蹦,我揣著相機與錄音力奋,去河邊找鬼。 笑死幽七,一個胖子當著我的面吹牛景殷,可吹牛的內容都是我干的。 我是一名探鬼主播澡屡,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼猿挚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挪蹭?” 一聲冷哼從身側響起亭饵,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梁厉,沒想到半個月后辜羊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踏兜,經...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年八秃,在試婚紗的時候發(fā)現(xiàn)自己被綠了碱妆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡昔驱,死狀恐怖疹尾,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情骤肛,我是刑警寧澤纳本,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站腋颠,受9級特大地震影響繁成,放射性物質發(fā)生泄漏。R本人自食惡果不足惜淑玫,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一巾腕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧絮蒿,春花似錦尊搬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至回铛,卻和暖如春狗准,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茵肃。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袭祟,地道東北人验残。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像巾乳,于是被迫代替她去往敵國和親您没。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內容