vue2實踐(持續(xù)更新)

segmentfault 會及時更新,這個定期更新杏瞻。

記錄一些小技巧和踩過的坑

1. props 帶不帶冒號的區(qū)別

 <child1 ref="child1" msg="{name:'bill'}"></child1>
 
 <child1 ref="child1" :msg="{name:'bill'}"></child1>

首先冒號是v-bind的縮寫熬丧,不帶冒號后面是字符串曼振,帶了冒號就是數(shù)據(jù)綁定,引號里面的內(nèi)容是變量或者表達式,
組件內(nèi)不能修改props的值昔园,同時修改的值也不會同步到組件外層扁瓢,即調(diào)用組件方不知道組件內(nèi)部當前的狀態(tài)是什么

vue 組件props傳遞時,為什么有時候需要加冒號堕战,有時候不需要坤溃?
如何在Vue2中實現(xiàn)組件props雙向綁定

2. computed屬性,可以set嘱丢,但是設(shè)置的是data返回的數(shù)據(jù)薪介,不能設(shè)置自身。

如果計算屬性是對象的話越驻,可以設(shè)置他的屬性汁政。

3. 組件的生命周期函數(shù)是在template標簽里的數(shù)據(jù)發(fā)生變化時候觸發(fā)update

數(shù)據(jù)可能更新了,但是沒有綁定到dom上面的話缀旁,不會調(diào)用update鉤子函數(shù)记劈。

4. 給變data的第二季屬性的值,data不會更新并巍,導(dǎo)致組件不會更新

所以在這個時候應(yīng)該用Object.assign()重新生成新的對象目木。第一級屬性值更新的話,data是更新的懊渡!

5. 動態(tài)綁定style的話刽射,后面的樣式值不能加分號

  style = {
            color: "rgb(66, 180, 232)"
       };
  //下面渲染不出來
    style = {
            color: "rgb(66, 180, 232)";
       };

6. filter 過濾器

vue2.0 的時候把過濾器移除了,現(xiàn)在2.10又加了上去距贷,

定義filter過濾器:
寫在實例Vue內(nèi)部的是局部過濾器柄冲,

new Vue({
  filters:{
  formatMoney: function (value){
      return "$"+value.toFixed(2);
   }
 }
})

寫在外部的是全局過濾器

Vue.filter("money", function (vaule, type) {
    return "¥" + vaule.toFixed(2) + type;
})

組件內(nèi)調(diào)用:

<span v-text="message | wrap 'before' 'after'"></span>//1.x的寫法,2直接wrap('before','after')調(diào)用
Vue.filter('wrap', function (value, begin, end) {
  return begin + value + end
})

補充下:一個豎線 | 在js中是二進制運算

想問一下這個用豎線分隔開是什么意思

7. watch監(jiān)測對象或者數(shù)組忠蝗,不是替換對象或者數(shù)組现横,newVal和oldVal是同一個值。

注意:在變異(不是替換)對象或數(shù)組時,舊值將與新值相同戒祠,因為它們的引用指向同一個對象/數(shù)組骇两。Vue 不會保留變異之前值的副本。

vm.$watch

8. 為組件綁定原生事件

有時候姜盈,你可能想在某個組件的根元素上監(jiān)聽一個原生事件低千。可以使用 .native 修飾 v-on 馏颂。例如:

<my-component v-on:click.native="doTheThing"></my-component>

9. 2.1.6computed在beforeMount前面執(zhí)行的示血,vue2.2.1剛好相反

10. v-for和v-if在同一個標簽使用的話,v-for的優(yōu)先級高于v-if

如果在同一標簽使用救拉,v-if就是用來過濾v-for里面的數(shù)據(jù)的难审,先走if的話用template套在外面

今天并列使用的時候遇到的巨坑:

<topic v-for="(topic,idx) in topics" :model="topic" :showIdx="false" :clickHandler="handleTopicClick"  v-if="mode==0"/>
<school-topic v-for="t in topics" :model="t" :style="showStyle(t)" :clickHandler="handleTopicClick" v-else />

結(jié)果topics只有三條數(shù)據(jù),但是渲染出9條數(shù)據(jù)亿絮,官網(wǎng)說的很清楚:v-for with v-if

11.keep-alive 緩存組件在內(nèi)存中告喊,再次進入該頁面不會重新渲染,用于保存頁面的原始狀態(tài)

<template>
    <div id="app">
        <keep-alive include="SelectTopics">
            <router-view></router-view>
        </keep-alive>
    </div>
</template>

即使設(shè)置了keep-alive組件的beforeUpdateupdated鉤子函數(shù)還是會調(diào)用的派昧。

activated和unactivated鉤子是在keep-alive組件里面被調(diào)用的黔姜,不是第一次進入keep-alive組件的話,調(diào)用順序是:
beforeEach->beforeRouteEnter->activated->beforeUpdate->beforeRouteEnternext函數(shù)

也可以在離開頁面的時候手動銷毀改組件:

 beforeRouteLeave(to, from, next) {
    if (to.path === "/examcentre") {
        this.$destroy();
    }
    next();
 }
//或者
  deactivated: function () {
    console.log(4)
    this.$destroy();
  },

有時候根據(jù)需求(比如該組件是復(fù)用的)需要在再次進入該頁面的時候重新從后臺獲取數(shù)據(jù)蒂萎,那么可以在activated鉤子函數(shù)中請求數(shù)據(jù)來update頁面秆吵。

vue.js 能否設(shè)置某個組件不被keep-alive?
vue2.0 keep-alive最佳實踐
Vue如何做到前進刷新數(shù)據(jù),后退不刷新數(shù)據(jù)呢?
<keep-alive>組件緩存問題
Vue路由開啟keep-alive時的注意點
vue.js+vue-router+webpack keep-alive用法

瀏覽器的前進回退并不會走dom綁定的前進后退的事件

所以要想清除vuex state里面的數(shù)據(jù)的話,可以放在beforeRouteLeave里面做處理岖是。

 this.$store.commit("SET_PAPERATTRIBUTE", {}); 

彈窗組件

mint-ui 中的Toast MessageBox Indicator 調(diào)用的方式是Toast('提示信息');或者在全局引入mint-ui然后再組件里this.$toast("提示信息"),這種方式和我們普通的引入組件的方式都不同帮毁,通常我們是在模板里直接將組件放到模板里面,這就意味著父組件在render的時候豺撑,子組件也被render到了dom里面:

<template>
    <div class="my-set-attr-wrap">
        <set-attribute ref="setMyAttr" :style="setAttrStyle" :model="attributeModel" />
    </div>
</template>

this.$toast("提示信息")這種是在函數(shù)中調(diào)用烈疚,肯定也是要render到dom里面的,改咋辦呢聪轿?查看了mint-ui的實現(xiàn)方式:document.body.appendChild(instance.$el);
目錄:

clipboard.png
clipboard.png

TopicDetailPopup.vue文件就是普通的vue寫法爷肝,
index.js:

clipboard.png
clipboard.png

這里考慮到每次彈出層不能都去創(chuàng)建新的組件,我們只需要將組件內(nèi)的數(shù)據(jù)更新就可以了陆错,dom也不需要刪除灯抛,然后再創(chuàng)建,就用到了單例模式音瓷,這邊的instance是在父組件沒銷毀之前都是存在的对嚼,每次只是更新了組件的數(shù)據(jù),為啥沒被銷毀呢绳慎,這邊形成了一個閉包:


clipboard.png
clipboard.png

調(diào)用:

import TopicDetailPopup from '../topicDetailPopup/index.js'
TopicDetailPopup.open({
                            detail: res.data
                     });

但是這個地方出現(xiàn)個問題this.$store現(xiàn)在為undefined纵竖,應(yīng)該是因為這個組件是直接new實例化的漠烧,而不是通過根組件嵌套的,
main.js

new Vue({
    router: router,
    store,
    render: h => h(App)
}).$mount("#app");

store注冊在根組件里面靡砌,而彈窗組件沒有和根組件關(guān)聯(lián)已脓,所以拿不到store。

要是能將彈窗組件插入其他組件問題就能解決了通殃,貌似現(xiàn)在API沒有提供這樣的接口度液,vue2動態(tài)添加組件的話可以用render函數(shù),可以我現(xiàn)在的彈窗組件是模板的形式画舌,也可以動態(tài)插入到父組件堕担,<component :is="componentId"></component>且需要在components里面引用,這樣又回到了模板語法了骗炉。

彈窗的弊端:
vue-devtools 沒法檢測到組件照宝,也沒法檢測到vuex,對于webapp來說返回鍵沒法使用句葵,關(guān)閉不了當前的彈窗,造成上面的問題都是由于沒用使用router兢仰。
對于安卓手機返回鍵沒法使用可以采用曲線救國的方式乍丈,禁用返回鍵,js沒法直接操作安卓返回鍵把将,但是可以使用beforeRouteLeave轻专,使得返回鍵沒有效果,

 beforeRouteLeave(to, from, next) {
        if (this.popupVisible) {//彈窗顯示的話察蹲,路由沒法跳轉(zhuǎn)
            next(false);
        } else {
            next(true);
        }
 }

彈窗的好處:
在當前頁面直接彈出请垛,這樣可以保存當前頁面的數(shù)據(jù)和滾動條的位置,還有就是組件復(fù)用的話洽议,直接關(guān)閉彈窗宗收,不需要根據(jù)不同的頁面去回退或者前進到特定的頁面。

使用的是vue2.0亚兄,如何動態(tài)添加組件混稽。例如實現(xiàn)點擊A按鈕添加aTest組件,點擊B按鈕添加bTest組件审胚。

:model和v-model的區(qū)別

v-model通常用于input的雙向數(shù)據(jù)綁定<input v-model="parentMsg">匈勋,也可以實現(xiàn)子組件到父組件數(shù)據(jù)的雙向數(shù)據(jù)綁定:
首先說說v-model的用法:
model.vue

<template>
    <div>
        父:
        <input type="text"
               v-model="msg">
        <child v-model="msg"></child>
    </div>
</template>
<script>
import child from './modelChild.vue'
export default {
    name: "model",
    props: {

    },
    components: {
        child
    },
    data() {
        return {
            msg: "ppp"
        }
    },
    methods: {

    }
}
</script>
<style lang="less">

</style>

modelChild.vue

<template>
    <div>
        子:
        <input type="text"
               @input="handleInput"
               class="text"
               :value="value">
    </div>
</template>
<script>
export default {
    name: "modelChild",
    props: ["value"],
    methods: {
        handleInput(e) {
            this.$emit("input", e.target.value)
        }
    }
}
</script>
<style lang="less">
.text {
    height: 20px;
    width: 200px;
}
</style>

無論改變父組件還是子組件的輸入框,value和msg的值都會改變膳叨,兩個輸入框的值也就同時改變了洽洁。

:model和v-model的區(qū)別
:model是v-bind:model的縮寫,<child :model="msg"></child>這種只是將父組件的數(shù)據(jù)傳遞到了子組件,并沒有實現(xiàn)子組件和父組件數(shù)據(jù)的雙向綁定菲嘴。當然引用類型除外饿自,子組件改變引用類型的數(shù)據(jù)的話碎浇,父組件也會改變的。

Vue.component注冊全局組件

查看vue-router源碼的時候發(fā)現(xiàn)install.js里面兩句:

Vue.component('router-view', View)
Vue.component('router-link', Link)

這兩句就是全局注冊了這兩個組件,

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
clipboard.png
clipboard.png
clipboard.png
clipboard.png

這三步后璃俗,在組件里直接使用<router-view></router-view>而不用先import再使用奴璃。

在mint-ui里也是相同的做法:
src/index.js

const install = function(Vue) {
  if (install.installed) return;
  Vue.component(Header.name, Header);//注冊全局組件
  Vue.component(Button.name, Button);
  Vue.use(InfiniteScroll);//使用指令插件
  Vue.use(Lazyload, {
    loading: require('./assets/loading-spin.svg'),
    try: 3
  });//使用指令插件或lazy-component
  Vue.$messagebox = Vue.prototype.$messagebox = MessageBox;
  Vue.$toast = Vue.prototype.$toast = Toast;
  Vue.$indicator = Vue.prototype.$indicator = Indicator;
};

后面的Vue.$toast = Vue.prototype.$toast = Toast;使得我們可以在組件中直接調(diào)用this.$toast("提示信息")

組件上寫class

clipboard.png
clipboard.png

之前在寫react的時候是不可以這么做的,今天查看了popup.vue的時候發(fā)現(xiàn)vue是可以這么干的城豁,直接渲染到了組件的根元素上面苟穆。用在組件上

Boolean類型的props可以直接定義:

clipboard.png
clipboard.png
 props: {
    fixed: Boolean,
    value: {}
  }

數(shù)據(jù)更新頁面沒刷新

今天在concat兩個數(shù)組的時候發(fā)現(xiàn)數(shù)據(jù)更新了,頁面并沒有刷新唱星,debug看了下數(shù)據(jù)雳旅,concat的數(shù)據(jù)沒有g(shù)et set屬性訪問器,導(dǎo)致后來push的數(shù)據(jù)也沒有屬性訪問器间聊。之前沒有細看文檔攒盈。搜了下原來push是變異方法,concat不是哎榴。
解決辦法有二:

  • 使用變異方法
  • 使用vue component的$set函數(shù)
    看一些小伙伴的回答是data的$set方法型豁,至少vue2是沒有的。具體可查看文檔列表渲染
    我的解決辦法是:
Array.prototype.push.apply(arr, item);

render函數(shù)和模板語法只能二選一

今天在模板.vue文件里加入render函數(shù)發(fā)現(xiàn)并不會執(zhí)行render函數(shù)尚蝌,原來是vue-loader會將template轉(zhuǎn)成render函數(shù)迎变,所以只能二選一。.vue文件如何使用render函數(shù)渲染組件

控制input只能輸入數(shù)字

<input type="number">在pc和手機端都可以實現(xiàn)只能輸入數(shù)字飘言,可是手機端彈出的軟鍵盤里面沒有完成或者搜索按鈕衣形,搜了下,現(xiàn)在的HTML5 number的情況下并沒有支持搜索按鈕姿鸿,type='text'是有的谆吴。所以曲線救國,控制表單只能輸入數(shù)字苛预。
起初的想法是先把在

<input type='text' @input="handleInput" :value="val"/>

handleInput(e){
this.val=e.target.value.replace(/[^\d]/g,'');
}

但是這種并不會實時刷新表單的數(shù)據(jù)句狼,下面就會起作用

e.target.value=e.target.value.replace(/[^\d]/g,'');

優(yōu)雅點的寫法,用自定義指令:

//<input type="text" v-number-only />
 directives: {
        numberOnly: {
            bind: function(el) {
                el.handler = function() {
                    el.value = el.value.replace(/\D+/, '')
                }
                el.addEventListener('input', el.handler)
            },
            unbind: function(el) {
                el.removeEventListener('input', el.handler)
            }
        }
    },

vue的input中碟渺,如何限制只能輸入number

彈出層彈出文本框獲取焦點

由于彈出層是單例模式鲜锚,所以打開彈出層只會執(zhí)行一次mounted鉤子函數(shù),我去監(jiān)聽

  visible(val) {
            if (val) {
                this.$refs.textbox.focus();//這樣并不能使文本框獲取焦點
            } else {
                this.detail = null;
                this.$refs.textbox.value = "";
            }
        }

解決辦法也是使用自定義指令

  focus: {
            update(el) {
                el.focus();
            }
  }

vue如何實現(xiàn)點擊button 使input獲取焦點

改變v-html解析后臺返回的HTML樣式

平時在寫組件里面的樣式加上scoped苫拍,避免樣式的全局污染芜繁,而從后臺返回的HTML無效的,解決辦法就是在組件里再加一對style標簽绒极,將樣式寫到這里骏令。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市垄提,隨后出現(xiàn)的幾起案子榔袋,更是在濱河造成了極大的恐慌周拐,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凰兑,死亡現(xiàn)場離奇詭異妥粟,居然都是意外死亡,警方通過查閱死者的電腦和手機吏够,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門勾给,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锅知,你說我怎么就攤上這事播急。” “怎么了售睹?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵桩警,是天一觀的道長。 經(jīng)常有香客問我昌妹,道長捶枢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任捺宗,我火速辦了婚禮柱蟀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚜厉。我一直安慰自己,他們只是感情好畜眨,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布昼牛。 她就那樣靜靜地躺著,像睡著了一般康聂。 火紅的嫁衣襯著肌膚如雪贰健。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天恬汁,我揣著相機與錄音伶椿,去河邊找鬼。 笑死氓侧,一個胖子當著我的面吹牛脊另,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播约巷,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼偎痛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了独郎?” 一聲冷哼從身側(cè)響起踩麦,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤枚赡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谓谦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贫橙,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年反粥,在試婚紗的時候發(fā)現(xiàn)自己被綠了卢肃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡星压,死狀恐怖践剂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娜膘,我是刑警寧澤逊脯,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站竣贪,受9級特大地震影響军洼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜演怎,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一匕争、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爷耀,春花似錦甘桑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咆耿,卻和暖如春德谅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背萨螺。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工窄做, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慰技。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓椭盏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惹盼。 傳聞我的和親對象是個殘疾皇子庸汗,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對于 Vue 1.0 印象不深的內(nèi)容手报。關(guān)于...
    云之外閱讀 5,050評論 0 29
  • 1.安裝 可以簡單地在頁面引入Vue.js作為獨立版本蚯舱,Vue即被注冊為全局變量改化,可以在頁面使用了。 如果希望搭建...
    Awey閱讀 11,016評論 4 129
  • 由于我是從一個舊的項目上面改得代碼枉昏,舊的項目啟動頁陈肛,我把它刪除了,由于新項目的啟動頁還沒有做好兄裂。所以暫時就空起了句旱。...
    FengxinLi閱讀 352評論 0 1
  • 如果我告訴你匾南,大家的情況幾乎都是這樣啃匿,但是有解決方案,你相信嗎蛆楞? 我的工作是組建完整的產(chǎn)品研發(fā)團隊溯乒,包括工程師、設(shè)...
    啟庵閱讀 502評論 0 2
  • 媽媽 我愛您 我希望您頭發(fā)不會白 我希望您背不會駝 我希望您身體健康 我希望歲月善待您豹爹!
    綿海寶寶閱讀 103評論 0 0