Vue材料清單

Vue問題整理

@mouseover

第三方組件例如el-button中使用類似api失效,此時需要使用@mouseover.native蝗锥,其它事件類比。

element文檔里沒有列出的組件

el-scrollbar章母,默認(rèn)有水平滾動條茫舶,可通過設(shè)置.el-scrollbar__wrapoverflow-x:hidden隱藏,這里可能需要使用到深度選擇器/deep/恤筛,>>>官还,::v-deep才能生效

props: {//這個組件接收以下屬性
    native: Boolean,//是否不顯示el的滾動條,默認(rèn)false
    wrapStyle: {},
    wrapClass: {}, //外層盒子class
    viewClass: {}, //內(nèi)層盒子class
    viewStyle: {},
    noresize: Boolean, // 如果 container 尺寸不會發(fā)生變化毒坛,最好設(shè)置它可以優(yōu)化性能
    tag: {
      type: String,
      default: 'div' //以DIV渲染
    }
  },

data恢復(fù)初始值

Object.assign(this.$data,this.$options.data())
this.$data是目前DOM中現(xiàn)有的data值望伦,this.$options.data()是初始的data值林说,這里用到的是Object.assign(target, source)(MDN),即是將source源數(shù)據(jù)拷貝到target目標(biāo)值并返回target屯伞。和Object.keys,Object.values, Object.hasOwnProperty配合使用起來都比較方便

$refs 和 ref

常用功能類似于選擇器腿箩,使用ref注冊引用信息string,使用$refs選中該對象object劣摇,相比于id或class選擇器減少了獲取dom節(jié)點的消耗

v-show / v-if / v-else / v-else-if / v-for

v-show判斷語句是CSS操作珠移,我還在,只不過display:none了末融,依然存在于dom中
v-if判斷是動態(tài)渲染钧惧,不合指令就鴻飛冥冥,只存在于JS里勾习,dom里會有一個空注釋行< !-- -- >表示可能存在的足跡浓瞪,elseelse-if的操作一如JS的if else語句
v-for這里列出了一種配合使用的方法,在v-for語句里可以添加條件判斷语卤,list里的某一項符合既定指令的話會添加dom節(jié)點追逮,例如對列出的某一項做出解釋或提示。寫個例子吧

<div v-for="user in userList" :key="user.id">
    <span v-if="user.name == 'me'">++{{ user.id }}:{{ user.name }}++</span>
    <span v-else>--{{ user.id }}:{{ user.name }}--</span>
    <!--這里用了v-else粹舵,3:me只出現(xiàn)一次-->
</div>
<!--shows like this-->
-- 1:him --
-- 2:you --
++ 3:me ++
-- 4:her --

axios的全局配置

主要記錄一下axios在配置時可以自己添加參數(shù)钮孵,新版的axios似乎獲取不到自定義參數(shù)了,不過寫進headers里或者config的其他屬性里也可以判斷眼滤,并不局限巴席。

axios.defaults.baseURL = 'http://url'
//baseURL類似實際url的前綴,發(fā)起請求時候添加的url會添加至baseURl尾部
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
//axios默認(rèn)是application/json的類型诅需,這里全局設(shè)置了POST的請求頭

// 配置攔截器漾唉,可設(shè)置token信息
axios.interceptors.request.use(config => {
  //這里調(diào)用了登錄時存入session里的token
  let token = window.sessionStorage.getItem('token')
  if (token) {
    config.headers.Authorization = token
    //有token就在請求頭里加入授權(quán)
  }
  if (config.method == 'post') {
  //post請求里會有其他類型的需求,例如上傳文件時用的FormData
    if (!config.typeFlag) {//在config里加了一個自定義的Boolean來判斷
      config.data = qs.stringify(config.data)
      //如果沒有這個typeFlag堰塌,就統(tǒng)一使用qs轉(zhuǎn)換格式赵刑,有的話就不做全局設(shè)置
    }
  }
  return config
}, error => {
  return Promise.reject(error)
})

// 配置響應(yīng)攔截器
axios.interceptors.response.use(res => {
  if (res.data.code == '401') {
    window.sessionStorage.removeItem('token')
    router.push('/')
    return {data: {
        code: 401,
        msg: '登錄超時'
    }}
    //這里重新回了一個401的data,這樣請求實際收到的是這個return的值
  }
  return Promise.resolve(res)
}, error => {
  return Promise.reject(error)
})

export default axios

上傳文件的實現(xiàn)

為了排版方便场刑,未使用el-upload

<!--使用form包裹一個input般此,用于上傳后的清除操作-->
<form id="uploadForm" style="display:none">
  <el-input id="uploadFile" ref="uploadFile" v-model="file" type="file" accept="application/msword"></el-input>
</form>
<!--組合一個帶前置按鈕的輸入框,禁用輸入牵现,用于選擇文件和顯示名稱-->
<el-input v-model="file" size="medium" disabled>
  <template slot="prepend">
    <el-button type="primary" size="medium" @click="chooseFile">選擇文件</el-button>
  </template>
</el-input>
<el-button type="primary" size="medium" @click="upload" :loading="uploading">上傳</el-button>
methods:{
  chooseFile() {
    //模擬點擊
    document.getElementById("uploadFile").click();
  },
  upload(){
    this.uploading = true;
    //新建FormData并append文件數(shù)據(jù)
    let fd = new FormData();
    fd.append("file", this.$refs.uploadFile.$refs.input.files[0]);
    //el-input編譯后是兩層铐懊,外層div包裹input,所以用了兩次$refs來獲取files瞎疼,
    //用原生的長度也差不多科乎,不糾結(jié)了。
    //fd.append("file", document.getElementById("uploadFile").files[0]);
    this.$http.request({
      url: this.baseUrl,
      method: "post",
      data: fd,
      typeFlag: true,//seeing this flag ?
      headers: { "Content-Type": "multipart/form-data" }
    })
    .then(res => {
        this.uploading = false;
        if (res.data.code == 0) {
          this.$message.success(res.data.msg);
        } else {
          this.$message.warning(res.data.msg);
        }
        //使用form的原生JS方法reset()在上傳成功后清除input的files贼急,
        //el-form的resetFields()好像并不好用茅茂。
        document.getElementById("uploadForm").reset();
        this.file = ""http://名字?jǐn)?shù)據(jù)也清掉
        })
    .catch(err => {
        this.uploading = false;
        console.log(err)
    });
  }
}

nextTick()

最近在使用el-scrollbar做持續(xù)底部定位的時候發(fā)現(xiàn)有點不準(zhǔn)確捏萍,數(shù)據(jù)的更新和DOM的更新不是很同步,導(dǎo)致滾動條定位在底部的代碼偶爾會失效玉吁,出現(xiàn)這個情況應(yīng)該跟el-scrollbar的實現(xiàn)方法有關(guān)照弥。最后使用VuenextTick()方法解決腻异。
nextTick()的官方解釋是【將回調(diào)延遲到下次 DOM 更新循環(huán)之后執(zhí)行进副。在修改數(shù)據(jù)之后立即使用它,然后等待 DOM 更新】悔常。方法在數(shù)據(jù)更新之后影斑,要等DOM更新完成才會執(zhí)行,可以準(zhǔn)確避免因為數(shù)據(jù)變化過快導(dǎo)致的DOM更新錯誤机打。

scroll() {
    var div = this.$refs.chat.$refs.wrap;//拿el-scrollbar的wrap元素
    this.$nextTick(() => {
        div.scrollTop = div.scrollHeight;
    });
}

ajax請求的異步處理

ajax請求在大部分情況下需要等待響應(yīng)結(jié)果返回后再進行處理矫户,可以使用ES7 async+await或者ES6 Promise對象的then()catch()方法

methods:{
  async handleClick(){//async標(biāo)記為異步函數(shù)
    await this.$ajax.post('url',this.config)//await 等待結(jié)果返回后再執(zhí)行下一句
    await ...
  }//需要注意await需要搭配async使用残邀,不可單獨存在
  //或者使用Promise方法
  handleSubmit(){
    this.axios.post('url',this.config)
      .then((res)=>{
        console.log(res) 
       })
      .then(()=>{//后邊也可以繼續(xù)加 then...注意方法里的函數(shù)不能省略
       })
      .catch((err)=>{//無法獲取結(jié)果時抓錯誤皆辽,像取消操作,服務(wù)器異常
        console.log(err)
      })
  }
}

vue.config.js

Vue-CLi里簡化處理了文件目錄芥挣,可以新建vue.config.js進行自定義配置驱闷,這里列舉一個簡單的數(shù)據(jù)mock寫法

module.exports = {
  configureWebpack: {
    devServer: {//開發(fā)環(huán)境下
      before(app) {
        //調(diào)用get方法時指向以下設(shè)置
        app.get('/api/goods', function (req, res) {
          res.json({
            list: [
              { name: 'good1', price: 100 },
              { name: 'good2', price: 80 },
              { name: 'good3', price: 60 }
            ]
          });
        });
      }
    }
  }
}

然后在頁面組件里使用axiosasync+await獲取接口數(shù)據(jù)

created(){
   axios.get('/api/goods')
     .then(res=>{
       this.goods = res.data.list
     })
     .catch(()=>{})
}
//----------
async created(){
   const res = await axios.get('/api/goods')
   this.goods = res.data.list
}

webpack-bundle-analyzer

使用交互式可縮放樹形圖可視化webpack輸出文件的大小
vue.config.js配置:

module.exports = {
    chainWebpack: config => {
        config.plugin('webpack-bundle-analyzer')
              .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }
}

運行命令:npm run serve

IOS系統(tǒng)微信分享的坑

IOS系統(tǒng)微信里在A頁面使用vuerouter跳轉(zhuǎn)到B頁面后,再分享B頁面不會分享當(dāng)前頁面的地址空免,而是分享的A頁面的地址空另,需要在每次路由變化時都重新請求下簽名,發(fā)起簽名請求的url參數(shù)必須是當(dāng)前頁面的url蹋砚。
處理方法:建立路由守衛(wèi)扼菠,如果是IOS就重新請求簽名。

router.beforeEach ((to, from, next) => {
  let u = navigator.userAgent;
  let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); 
  if (isiOS && to.path !== location.pathname) {
    location.assign(to.fullPath)
  } else {
    next()
  }
});

這樣實際體驗很差坝咐,而且不利于vuex緩存數(shù)據(jù)循榆。所以隨后更改為hash路由,用#號對url進行拆分墨坚,這樣對于同域名下的子頁面秧饮,可以只拿域名去申請簽名,因為hash后邊的地址其實瀏覽器不認(rèn)的框杜。這樣發(fā)起簽名請求的url其實就變成hash之前的一串浦楣,每個頁面都是一樣的。

Vue組件在單個頁面的循環(huán)調(diào)用

最近封裝了一個視頻組件咪辱,用以播放單個監(jiān)控的實時視頻流振劳,在父組件使用for循環(huán)傳遞不同的值多次調(diào)用,實際渲染時發(fā)現(xiàn)傳遞進去值出現(xiàn)了不同程度的串位油狂,本來給1組件的值傳到了其他組件里历恐,考慮可能是DOM同時渲染造成的寸癌。這個解釋感覺不太科學(xué),不過實際操作上對for循環(huán)增加了少量延時之后校正了這個錯位弱贼。Mark記錄新增:對于頁面渲染的錯位和數(shù)據(jù)混亂大部分情況應(yīng)該使用增加組件key值的方法解決蒸苇,for循環(huán)中為每個組件增加唯一key值可以有效避免混亂。增加延時的方案只適用在特定場合吮旅,并不是很科學(xué)溪烤。

Vue中靜態(tài)文件的頁面引用

以圖片為例,url可表示為~@/assets/img/logo.png或相對路徑庇勃。

is 和 v-bind:is

當(dāng)頁面內(nèi)有不同組件大量渲染時檬嘀,template中單獨列出每一個組件名會顯得麻煩,可以在導(dǎo)入注冊之后责嚷,使用v-bind:is動態(tài)渲染不同組件鸳兽。例如:在一個需要回顯自定義表單的頁面中,可以根據(jù)表單控件的類型引入不同的組件罕拂,這種寫法明顯會少摳不少字母:

<template v-for="(item) in items">
    <form-item :key="item.id" :label="item.title" :rules="item.rules" :prop="item.prop">
        <component v-bind:is="item.type"></component>
    <form-item>
</template>

這樣揍异,當(dāng)item.type === "singleInput"時,頁面組件會自動渲染成<component is="singleInput"></component>等同于<singleInput></singleInput>組件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末爆班,一起剝皮案震驚了整個濱河市衷掷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛋济,老刑警劉巖棍鳖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碗旅,居然都是意外死亡渡处,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門祟辟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來医瘫,“玉大人,你說我怎么就攤上這事旧困〈挤荩” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵吼具,是天一觀的道長僚纷。 經(jīng)常有香客問我,道長拗盒,這世上最難降的妖魔是什么怖竭? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮陡蝇,結(jié)果婚禮上痊臭,老公的妹妹穿的比我還像新娘哮肚。我一直安慰自己,他們只是感情好广匙,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布允趟。 她就那樣靜靜地躺著,像睡著了一般鸦致。 火紅的嫁衣襯著肌膚如雪潮剪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天蹋凝,我揣著相機與錄音鲁纠,去河邊找鬼。 笑死鳍寂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的情龄。 我是一名探鬼主播迄汛,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼骤视!你這毒婦竟也來了鞍爱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤专酗,失蹤者是張志新(化名)和其女友劉穎睹逃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祷肯,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡沉填,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了佑笋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翼闹。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蒋纬,靈堂內(nèi)的尸體忽然破棺而出猎荠,到底是詐尸還是另有隱情,我是刑警寧澤蜀备,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布关摇,位于F島的核電站,受9級特大地震影響碾阁,放射性物質(zhì)發(fā)生泄漏输虱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一瓷蛙、第九天 我趴在偏房一處隱蔽的房頂上張望悼瓮。 院中可真熱鬧戈毒,春花似錦、人聲如沸横堡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽命贴。三九已至道宅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胸蛛,已是汗流浹背污茵。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留葬项,地道東北人泞当。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像民珍,于是被迫代替她去往敵國和親襟士。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351