摘要:代碼實(shí)現(xiàn)得到合適的瀏覽器前綴對外暴露的方法使用案例導(dǎo)入該模塊加了合適前綴的屬性使用該屬性移動端的事件隨著觸屏設(shè)備的普及,為移動端新增了事件。如果用戶的手指從觸屏設(shè)備的邊緣移出了觸屏設(shè)備,也會觸發(fā)事件。
聲明
以下只是學(xué)習(xí)完慕課網(wǎng)huangyi老師實(shí)戰(zhàn)視頻課程的筆記內(nèi)容,僅供個人參考學(xué)習(xí)使用。
如果對Vue2.0實(shí)戰(zhàn)高級-開發(fā)移動端音樂WebApp感興趣的話,請移步這里:
https://coding.imooc.com/clas...
謝謝。
項(xiàng)目GitHub地址: https://github.com/bjw1234/vu...
項(xiàng)目演示地址: http://music.baijiawei.top
項(xiàng)目初始化// 安裝vue腳手架工具 npm install vue-cli -g // 初始化webpack應(yīng)用 vue init webpack vue-music項(xiàng)目中使用到的mixin
// 背景圖片 bg-image($url) background-image: url($url + "@2x.png") @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) background-image: url($url + "@3x.png") // 不換行 no-wrap() text-overflow: ellipsis overflow: hidden white-space: nowrap // 擴(kuò)展點(diǎn)擊區(qū)域 extend-click() position: relative &:before content: "" position: absolute top: -10px left: -10px right: -10px bottom: -10px配置路徑別名
resolve: { extensions: [".js", ".vue", ".json"], alias: { "@": resolve("src"), "common": resolve("src/common") } }移動端300毫秒延時和點(diǎn)透問題
fastclick:處理移動端click事件300毫秒延遲和點(diǎn)透問題。
先執(zhí)行安裝fastclick的命令。
npm install fastclick --save
之后,在main.js中引入,并綁定到body
import FastClick from "fastclick"; FastClick.attach(document.body);
注意: 當(dāng)fastclick和其他的模塊點(diǎn)擊沖突,導(dǎo)致點(diǎn)擊事件不可用時,可以給對應(yīng)的dom添加needsclick類來解決。
對jsonp進(jìn)一步封裝下載原始的jsonp模塊:
npm install jsonp --save
再次封裝:
import originJSONP from "jsonp"; /** * 做一個簡單的jsonp封裝 * @param url * @param data * @param option * @return {Promise} */ export default function jsonp (url, data, option) { return new Promise((resolve, reject) => { url = `${url}?${_obj2String(data)}`; originJSONP(url, option, (err, data) => { if (!err) { resolve(data); } else { reject(err); } }); }); }; function _obj2String (obj, arr = [], index = 0) { for (let item in obj) { arr[index++] = [item, obj[item]]; } return new URLSearchParams(arr).toString(); }vue的生命周期函數(shù)
注意: 當(dāng)使用keep-alive組件時,當(dāng)切換到其他路由,會調(diào)用前組件的deactivated鉤子函數(shù),當(dāng)切回來時,會調(diào)用activated函數(shù)。
better-scroll組件的使用注意:
1.better-scroll只處理容器的第一個子元素的滾動。
2.一定得保證子元素超出父元素,這樣才能正確的滾動。
初始化:
import BScroll from "better-scroll"; let wrapper = document.querySelector(".wrapper"); let scroll = new BScroll(wrapper,{ // 配置項(xiàng) });
.wrapper position: fixed width: 100% top: 88px bottom: 0 .scroll height: 100% overflow: hidden
問題排查(無法滾動原因:)
1.內(nèi)層容器的高度沒有超過外層容器。
2.dom沒有渲染完畢就初始化better-scroll。
3.改變了dom的顯隱性,沒有對scroll進(jìn)行重新計算。
針對3:當(dāng)dom顯示出來之后,加20毫秒延時,然后調(diào)用refresh方法。
開發(fā)模式下的請求代理當(dāng)在開發(fā)模式下,需要使用一些后臺接口,為了防止跨域問題,vue-cli提供了非常強(qiáng)大的http-proxy-middleware包。可以對我們的請求進(jìn)行代理。
進(jìn)入 config/index.js 代碼下如下配置即可:
proxyTable: { "/getDescList": { target: "http://127.0.0.1:7070/desclist", // 后端接口地址 changeOrigin: true, // secure: false, pathRewrite: { "^/getDescList": "/" } } }負(fù)外邊距的作用效果
marin-left或者margin-top是負(fù)值:它會將元素在相應(yīng)的方向進(jìn)行移動。left就是左右方向移動,top就是上下方向移動。也就是會使元素在文檔流里的位置發(fā)生變化。
margin-right或者margin-bottom是負(fù)值:它不會移動該元素(該元素不變化),但會使該元素后面的元素往前移動。也就是說,如果margin-bottom為負(fù)值,那么該元素下面的元素會往上移動;如果margin-right為負(fù)值,那么該元素右邊的元素會往左移動,從而覆蓋該元素。
配置子路由需求:在歌手頁面下需要一個歌手詳情頁。
export default new Router({ routes:[ { path: "/", component: Singer, children: [ { path: ":id", compoonent: SingerDetail } ] }, ... ] });
當(dāng)監(jiān)聽到用戶點(diǎn)擊之后進(jìn)行路由跳轉(zhuǎn):
this.$router.push({ path: `singer/${singer.id}` }); // 別忘了在`Singer`頁面中:Vuex的使用 Vuex是什么?
簡單來說:Vuex解決項(xiàng)目中多個組件之間的數(shù)據(jù)通信和狀態(tài)管理。
Vuex將狀態(tài)管理多帶帶拎出來,應(yīng)用統(tǒng)一的方式進(jìn)行處理,采用單向數(shù)據(jù)流的方式來管理數(shù)據(jù)。用處負(fù)責(zé)觸發(fā)動作(Action)進(jìn)而改變對應(yīng)狀態(tài)(State),從而反映到視圖(View)上。
Vuex怎么用?安裝:
npm install vuex --save
引入:
import Vuex from "vuex"; import Vue from "Vue"; Vue.use(Vuex);
Vuex的組成部分
使用Vuex開發(fā)的應(yīng)用結(jié)構(gòu)應(yīng)該是這樣的:
State
State負(fù)責(zé)存儲整個應(yīng)用的狀態(tài)數(shù)據(jù),一般需要在使用的時候在根節(jié)點(diǎn)注入store對象,后期就可以使用this.$store.state直接獲取狀態(tài)。
import store from "./store"; .. new Vue({ el: "#app", store, render: h => h(App) });
那么這個store又是什么?從哪來的呢?
store可以理解為一個容器,包含應(yīng)用中的state。實(shí)例化生成store的過程是:
const mutations = {...}; const actions = {...}; const state = {...}; // 實(shí)例化store對象并導(dǎo)出 export defautl new Vuex.Store({ state, actions, mutations });
Mutations
中文意思是“變化”,利用它可以來更改狀態(tài),本質(zhì)上就是用來處理數(shù)據(jù)的函數(shù)。
store.commit(mutationName)是用來觸發(fā)一個mutation的方法。
需要記住的是,定義的mutation必須是同步函數(shù)。
const mutations = { changState(state) { // 在這里改變state中的數(shù)據(jù) } }; // 可以在組件中這樣觸發(fā) this.$store.commit("changeState");
Actions
Actions也可以用于改變狀態(tài),不過是通過觸發(fā)mutation實(shí)現(xiàn)的,重要的是可以包含異步操作。
直接觸發(fā)可以使用this.$store.dispatch(actionName)方法。
簡單的多組件數(shù)據(jù)交互import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); // 狀態(tài) const state = { singer: {} }; // 跟蹤狀態(tài)的變化 const mutations = { setSinger (state, singer) { state.singer = singer; } }; // 實(shí)例化store對象 export default new Vuex.Store({ state, mutations }); // 在singer組件中提交數(shù)據(jù) this.$store.commit("setSinger",singer); // 在singer-detail組件中接收數(shù)據(jù) let singer = this.$store.state.singer;vuex稍微復(fù)雜點(diǎn)的使用
在上面的小栗子中,我們把sate、mutations等其他一些內(nèi)容寫在了一起,
但是這種方式不適合大型點(diǎn)的項(xiàng)目。最好能將這些內(nèi)容拎出來,多帶帶作為一個文件來使用。
在src/store目錄中新建以下文件:
state.js 用于存儲狀態(tài)信息
const sate = { singer: {} }; export default state;
mutation-types.js 保存一些常量(mutations中函數(shù)的函數(shù)名)
export const SET_SINGER = "SET_SINGER";
mutations.js 用于更改狀態(tài)(state中的數(shù)據(jù))
import * as types from "./mutation-types"; // 通過這個函數(shù)可以傳入payload信息 const mutations = { [types.SET_SINGER](state,singer){ state.singer = singer; } }; export default mutations;
getters.js 對狀態(tài)獲取的封裝
export const singer = state => state.singer;
actions.js 對mutation進(jìn)行封裝,或者執(zhí)行一些異步操作
// 暫時沒有什么異步操作
index.js store的入口文件
// 入口文件 import Vue from "vue"; import Vuex from "vuex"; import state from "./state"; import mutations from "./mutations"; import * as actions from "./actions"; import * as getters from "./getters"; import createLogger from "vuex/dist/logger"; Vue.use(Vuex); // 調(diào)試環(huán)境下開啟嚴(yán)格模式 const debug = process.env.NODE_ENV !== "production"; // 創(chuàng)建store對象并導(dǎo)出 export default new Vuex.Store({ state, actions, getters, mutations, strict: debug, plugins: debug ? [createLogger()] : [] });
使用:
// main.js中引入 import store from "./store";
有了以上內(nèi)容,那么我們就可以在業(yè)務(wù)中去使用了:
例如:多組件之間的的數(shù)據(jù)交互。
需求:singer組件中需要將用戶點(diǎn)擊的那個singer對象傳遞給組件singer-detail組件。
singer.vue 組件中:
// 使用這個語法糖 import { mapMutations } from "vuex"; methods:{ ...mapMutations({ // 將這個函數(shù)(setSinger)和mutations中用于修改狀態(tài)的函數(shù)關(guān)聯(lián)起來 setSinger: "SET_SINGER" }); } // 傳參 this.setSinger(singer); // 語法糖的本質(zhì) this.$store.commit("setSinger", singer);
singer-detail.vue 組件中:
我們就可以去使用這個數(shù)據(jù)了,當(dāng)然也是使用我們的語法糖啦。
import { mapGetters } from "vuex"; export default { // 使用一個計算屬性 computed: { ...mapGetters([ "singer" // 這個就是getters.js中的那個singer ]); }, created(){ console.log(this.singer); } } // 語法糖的本質(zhì): let singer = this.$store.state.singer;js中給CSS添加prefix
我們一定遇到過這種情況:
需要用JS寫CSS動畫。但我們又不得不處理前綴的問題。
所以一般是這樣寫的:
this.$refs.image.style.transform = `scale(${scale})`; this.$refs.image.style.webkitTansform = `scale(${scale})`; ...
那么問題來了,怎樣用JS處理這種情況呢?
思路:
檢測瀏覽器的能力。
返回帶著前綴的CSS樣式。
代碼實(shí)現(xiàn):
let elementStyle = document.createElement("div").style; // 得到合適的瀏覽器前綴 let vendor = (() => { let transformNames = { webkit: "webkitTransform", Moz: "MozTransform", O: "OTransform", ms: "msTransform", standard: "transform" }; for (let key in transformNames) { let support = elementStyle[transformNames[key]] !== undefined; if (support) { return key; } } return false; })(); // 對外暴露的方法 export function prefixStyle (style) { if (vendor === false) { return style; } if (vendor === "standard") { return style; } let result = vendor + style.charAt(0).toUpperCase() + style.substr(1); return result; }
使用案例:
// 導(dǎo)入該模塊 import { prefixStyle } from "common/js/dom"; // 加了合適前綴的CSS屬性 const TRANSFORM = prefixStyle("transform"); // 使用該CSS屬性 this.$refs.image.style[TRANSFORM] = `scale(${scale})`;移動端的touch事件
隨著觸屏設(shè)備的普及,w3c為移動端web新增了touch事件。
最基本的touch事件包括4個事件:
touchstart 當(dāng)在屏幕上按下手指時觸發(fā)
當(dāng)用戶手指觸摸到的觸摸屏的時候觸發(fā)。事件對象的 target 就是 touch 發(fā)生位置的那個元素。
touchmove 當(dāng)在屏幕上移動手指時觸發(fā)
即使手指移出了 原來的target元素,但 touchmove 仍然會被一直觸發(fā),而且 target 仍然是原來的 target 元素。
touchend 當(dāng)在屏幕上抬起手指時觸發(fā)
當(dāng)用戶的手指抬起的時候,會觸發(fā) touchend 事件。如果用戶的手指從觸屏設(shè)備的邊緣移出了觸屏設(shè)備,也會觸發(fā) touchend 事件。
touchend 事件的 target 也是與 touchstart 的 target 一致,即使已經(jīng)移出了元素。
touchcancel 當(dāng)一些更高級別的事件發(fā)生的時候(如電話接入或者彈出信息)會取消當(dāng)前的touch操作,即觸發(fā)touchcancel。一般會在touchcancel時暫停游戲、存檔等操作。
如果你使用了觸摸事件,可以調(diào)用 event.preventDefault()來阻止鼠標(biāo)事件被觸發(fā)。
與移動端相關(guān)的interface主要有三個:
TouchEvent 表示觸摸狀態(tài)發(fā)生改變時觸發(fā)的event
可以通過檢查觸摸事件的 TouchEvent.type 屬性來確定當(dāng)前事件屬于哪種類型。
dom.addEventListener("touchstart",(e) => { // 獲取事件類型 let type = e.type; // toch事件發(fā)生時那個位置的元素對象 let target = e.target; });
Touch 表示用戶和觸屏設(shè)備之間接觸時多帶帶的交互點(diǎn)(a single point of contact)
screenX、screenY:觸點(diǎn)相對于屏幕左邊緣或上邊緣的x、y坐標(biāo)。
clientX、clientY:觸點(diǎn)相對于瀏覽器viewport左邊緣或上邊緣的x、y坐標(biāo)。(不包含滾動距離)
pageX、pageY:觸點(diǎn)相對于document的左邊緣或上邊緣的x、y坐標(biāo)。與client不同的是,包含左邊滾動的距離。
target:觸摸開始時的element。
// 獲取touchList let touchList = e.changedTouches; // 獲取第i個touch對象 let touch = touchList[i]; touch.screenX touch.clientX touch.pageX touch.target ...
TouchList 表示一組touches。當(dāng)發(fā)生多點(diǎn)觸摸的時候才用的到。
如果一個用戶用三根手指接觸屏幕(或者觸控板), 與之相關(guān)的TouchList對于每根手指都會生成一個 Touch 對象, 共計 3 個.
可以通過三種方式獲取這個對象:
dom.addEventListener("touchstart",(e) => { // 這個 TouchList對象列出了和這個觸摸事件對應(yīng)的那些發(fā)生了變化的 Touch 對象 e.changedTouches // 這個TouchList列出了那些 touchstart發(fā)生在這個元素,并且還沒有離開 touch surface 的touch point(手指) e.targetTouches // 這個 TouchList 列出了事件觸發(fā)時: touch suface上所有的 touch point。 e.touches });播放器內(nèi)核開發(fā) audio標(biāo)簽
對于音樂的播放,我們使用了audio標(biāo)簽,監(jiān)聽它的事件和操作DOM,可以達(dá)到對音樂播放、
暫停、進(jìn)度控制等操作。
對audio進(jìn)行操作
let audio = this.$refs.audio; // 暫停和播放 audio.pause(); audio.play(); // Audio對象的屬性(部分) audio.currentTime // 設(shè)置或返回音頻中的當(dāng)前播放位置(以秒計)。 audio.duration // 返回音頻的長度(以秒計)。 audio.loop // 設(shè)置或返回音頻是否應(yīng)在結(jié)束時再次播放。(默認(rèn)false) audio.volume // 設(shè)置或返回音頻的音量。[0,1] // Audio對象多媒體事件(Media Events) onerror // 加載發(fā)生錯誤時的回調(diào) ontimeupdate // 當(dāng)播放位置改變時調(diào)用 updateTime(e) { if(this.currentSongReady){ // 獲取當(dāng)前播放的進(jìn)度 this.currentSongTime=e.traget.currentTime; } } oncanplay // 能夠播放時調(diào)用 // 通過監(jiān)聽這個事件,設(shè)置標(biāo)志位,這個標(biāo)志位可以幫助我們 // 防止用戶快速切換歌曲引起一些錯誤。 songCanPlay(){ this.currentSongReady = true; } onended // 到達(dá)結(jié)尾時調(diào)用 onplay、onpause...進(jìn)度條組件
1.progress-bar.vue接收一個percent參數(shù),用來顯示當(dāng)前播放的一個進(jìn)度。
2.對于進(jìn)度條用戶手動拖動進(jìn)度的實(shí)現(xiàn)。
思路:主要是通過監(jiān)聽ontouchstart、ontouchmove、ontouchend事件來完成。
// 首先得定義一個`touch`對象 let touch = {}; // 在監(jiān)聽的方法中 touchStart(e){ this.touch.initialized = true; // 獲取touch的起始位置 this.touch.startX = e.touches[0].pageX; // 獲取整個進(jìn)度條的寬度 this.touch.barW = xxx; // 獲取已經(jīng)播放的進(jìn)度 this.touch.offset = xxx; } touchMove(e){ // 判斷有無初始化 ... // 獲取用戶滑動的距離 let deltaX = e.touches[0].pageX - this.touch.startX; let barW = xxx; // 進(jìn)度條的寬度 - 拖動btn的寬度 let offset = Math.min(Math.max(0, this.touch.offset + detail), barW); // 最后設(shè)置btn的位置和progress的進(jìn)度就OK ... } touchEnd(){ this.touch.initialized = false; // 然后將進(jìn)度推送出去就好了 this.$emit("percentChange",percent); }svg實(shí)現(xiàn)圓形進(jìn)度條
通過svg可以實(shí)現(xiàn)各種進(jìn)度條,有一個問題,怎樣去動態(tài)的修改它的進(jìn)度值呢?
這就不能不提 SVG Stroke 屬性
stroke 定義一條線,文本或元素輪廓顏色
stroke-width 文本或元素輪廓的厚度
stroke-dasharray 該屬性可用于創(chuàng)建虛線
stroke-dashoffset 設(shè)置虛線邊框的偏移量
OK,知道了以上屬性,就足以實(shí)現(xiàn)一個可設(shè)置進(jìn)度的SVG進(jìn)度條了。
思路:stroke-dasharray適用于創(chuàng)建虛線的,如果這個虛線長度為整個輪廓的周長呢。
stroke-dashoffset可以設(shè)置虛線的偏移量,利用這兩個屬性,我們就可以完成對進(jìn)度的控制。
且看一個小栗子:
所以,通過父組件傳入的percent,不斷地修改stroke-dashoffset就能達(dá)到進(jìn)度的顯示了。
全屏和退出全屏// 全屏顯示 document.documentElement.webkitRequestFullScreen(); // 退出全屏 document.webkitExitFullscreen(); // 1.得根據(jù)不同的瀏覽器添加前綴 // 2.程序主動調(diào)用不管用,得用戶操作才可以(點(diǎn)擊按鈕)歌詞頁的顯示
通過網(wǎng)絡(luò)接口獲取的歌詞:
對于歌詞的解析,播放是通過一個插件lyric-parser完成的。
這個插件很簡單:
1.通過正則把時間和對應(yīng)的歌詞切分出來創(chuàng)建成對象。
2.當(dāng)調(diào)用play方法時,通過定時器完成歌詞的播放,并將對應(yīng)的行號和歌詞通過回調(diào)函數(shù)傳遞出去。
當(dāng)播放的歌詞超過5行時,就可以使用封裝的scroll組件完成滾動操作。
if (lineNum > 5) { let elements = this.$refs.lyricLine; this.$refs.lyricScroll.scrollToElement(elements[lineNum - 5], 1000); } else { this.$refs.lyricScroll.scrollTo(0, 0, 1000); }Vue中的mixin
為什么要使用mixin?
多個組件公用一樣的代碼,我們可以將這部分抽離出來作為mixin,只要引入對應(yīng)的組件中就可以了。
例如下面的mixin:
import { mapGetters } from "vuex"; export const playListMixin = { mounted () { this.handlePlayList(this.playList); }, // 當(dāng)路由對應(yīng)的頁面激活時調(diào)用 activated () { this.handlePlayList(this.playList); }, watch: { playList (newPlayList) { this.handlePlayList(newPlayList); } }, computed: { ...mapGetters([ "playList" ]) }, methods: { // 這個方法需要對應(yīng)的組件自己去實(shí)現(xiàn),直接調(diào)用拋出錯誤 handlePlayList () { throw new Error("Components must implement handlePlayList method."); } } };
有了mixin我們在組件中就可以這樣使用了:
import { playListMixin } from "common/js/mixin"; export default{ mixins: [playListMixin], ... }節(jié)流處理
在搜索頁面,我們需要處理用戶的輸入,然后向服務(wù)器發(fā)起請求。
為了不必要的請求、節(jié)省流量和提高頁面性能,我們都有必要做節(jié)流處理。
在搜索框search-box這個基礎(chǔ)組件中:
// 在created鉤子中,我們監(jiān)聽用戶輸入字符串(query)變化,然后將變化后的字符串 // 提交給父組件 // 可以看到在回調(diào)函數(shù)中,又包了一層debounce函數(shù) created () { this.$watch("query", debounce(() => { this.$emit("queryChange", this.query); }, 500)); }
所以debounce函數(shù),就是我們的節(jié)流函數(shù),這個函數(shù),接收一個函數(shù),返回一個新的函數(shù)
function debounce(func,delay){ let timer = null; return function(...args){ if(timer){ clearTimeout(timer); } timer = setTimeout(()=>{ func.apply(this,args); },delay) } } // 測試 function show(){ console.log("hello..."); } var func = debounce(show,3000); // 調(diào)用 func(); // 連續(xù)調(diào)用時,沒有超過三秒是不會有任何輸出的animation動畫
語法:
animation: name duration timing-function delay iteration-count direction fill-mode play-state;封裝localStorage操作
animation: 動畫名稱 執(zhí)行時間 速度曲線 延時時間 執(zhí)行次數(shù) 動畫播放順序 結(jié)束時應(yīng)用的樣式 播放的狀態(tài)(paused|running)
const __VERSION__ = "1.0.1"; const store = { version: __VERSION__, storage: window.localStorage, session: { storage: window.sessionStorage } }; // 操作store的api const api = { set (key, val) { if (this.disabled) { return false; } if (val === undefined) { return this.remove(key); } this.storage.setItem(key, this.serialize(val)); return val; }, get (key, val) { if (this.disabled) { return false; } let result = this.storage.getItem(key); if (!result) { return val; } return this.deSerialize(result); }, getAll () { if (this.disabled) { return false; } let ret = {}; for (let key in this.storage) { if (this.storage.hasOwnProperty(key)) { ret[key] = this.get(key); } } return ret; }, remove (key) { if (this.disabled) { return false; } this.storage.removeItem(key); }, removeAll () { if (this.disabled) { return false; } this.storage.clear(); }, forEach (cb) { if (this.disabled) { return false; } for (let key in this.storage) { if (this.storage.hasOwnProperty(key)) { cb && cb(key, this.get(key)); } } }, has (key) { if (this.disabled) { return false; } return key === this.get(key); }, serialize (val) { try { return JSON.stringify(val) || undefined; } catch (e) { return undefined; } }, deSerialize (val) { if (typeof val !== "string") { return undefined; } try { return JSON.parse(val) || undefined; } catch (e) { return undefined; } } }; // 擴(kuò)展store對象 Object.assign(store, api); Object.assign(store.session, api); // 瀏覽器能力檢測 try { let testKey = "test_key"; store.set(testKey, testKey); if (store.get(testKey) !== testKey) { store.disabled = true; } store.remove(testKey); } catch (e) { store.disabled = true; } export default store;路由懶加載
為什么需要?
如果開發(fā)的App太大的話,就會導(dǎo)致首屏渲染過慢,為了增強(qiáng)用戶體驗(yàn),加快渲染速度,
需要用到懶加載功能。讓首屏的內(nèi)容先加載出來,其他路由下的組件按需加載。
vue官網(wǎng)描述:
異步組件
在大型應(yīng)用中,我們可能需要將應(yīng)用分割成小一些的代碼塊,并且只在需要的時候才從服務(wù)器加載一個模塊。
為了簡化,Vue 允許你以一個工廠函數(shù)的方式定義你的組件,這個工廠函數(shù)會異步解析你的組件定義。
Vue 只有在這個組件需要被渲染的時候才會觸發(fā)該工廠函數(shù),且會把結(jié)果緩存起來供未來重渲染。
const AsyncComponent = () => ({ // 需要加載的組件 (應(yīng)該是一個 `Promise` 對象) component: import("./MyComponent.vue"), // 異步組件加載時使用的組件 loading: LoadingComponent, // 加載失敗時使用的組件 error: ErrorComponent, // 展示加載時組件的延時時間。默認(rèn)值是 200 (毫秒) delay: 200, // 如果提供了超時時間且組件加載也超時了, // 則使用加載失敗時使用的組件。默認(rèn)值是:`Infinity` timeout: 3000 })
注意:如果你希望在 Vue Router 的路由組件中使用上述語法的話,你必須使用 Vue Router 2.4.0+ 版本。
當(dāng)然為了簡單起見:
在router/index.js路由配置文件中這樣加載組件:
// import Recommend from "@/components/recommend/recommend"; const Recommend = () => ({ component: import("@/components/recommend/recommend") });
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/52621.html
摘要:寫在前面沒錯,這就是慕課網(wǎng)上的那個音樂播放器,后臺是某音樂播放器的線上接口扒取,雖然這類項(xiàng)目寫的人很多,但不得不說這還是個少有的適合提升的好項(xiàng)目,做這個項(xiàng)目除了想寫一個比較大并且功能復(fù)雜的項(xiàng)目,主要原因是要拿它來應(yīng)對面試,也確實(shí)對我的業(yè)務(wù)能 寫在前面 沒錯,這就是慕課網(wǎng)上的那個vue音樂播放器,后臺是某音樂播放器的線上接口扒取,雖然這類項(xiàng)目寫的人很多,但不得不說這還是個少有的適合vu...
摘要:代碼實(shí)現(xiàn)得到合適的瀏覽器前綴對外暴露的方法使用案例導(dǎo)入該模塊加了合適前綴的屬性使用該屬性移動端的事件隨著觸屏設(shè)備的普及,為移動端新增了事件。如果用戶的手指從觸屏設(shè)備的邊緣移出了觸屏設(shè)備,也會觸發(fā)事件。 聲明 以下只是學(xué)習(xí)完慕課網(wǎng)huangyi老師實(shí)戰(zhàn)視頻課程的筆記內(nèi)容,僅供個人參考學(xué)習(xí)使用。如果對Vue2.0實(shí)戰(zhàn)高級-開發(fā)移動端音樂WebApp感興趣的話,請移步這里:https://c...
摘要:基于等開發(fā)一款移動端音樂,界面參考了安卓版的網(wǎng)易云音樂布局適配常見移動端。圖標(biāo)使用阿里巴巴圖標(biāo)庫,中間的唱片旋轉(zhuǎn)動畫使用了實(shí)現(xiàn)。搜索功能實(shí)現(xiàn)功能搜索歌手歌單歌曲熱門搜索數(shù)據(jù)節(jié)流上拉刷新保存搜索記錄。 基于 Vue(2.5) + vuex + vue-router + vue-axios +better-scroll + Scss + ES6 等開發(fā)一款移動端音樂 WebApp,UI ...
閱讀 3141·2023-04-26 02:33
閱讀 3102·2023-04-25 21:33
閱讀 907·2021-09-02 09:56
閱讀 2910·2019-08-30 15:44
閱讀 2460·2019-08-30 13:15
閱讀 1034·2019-08-30 13:04
閱讀 1634·2019-08-29 15:09
閱讀 3956·2019-08-26 18:26