從0到1搭建一款頁(yè)面自適應(yīng)組件(Vue.js)
組件將根據(jù)屏幕比例及當(dāng)前瀏覽器窗口大小,自動(dòng)進(jìn)行縮放處理。
建議在組件內(nèi)使用百分比搭配flex進(jìn)行布局,以便于在不同的分辨率下得到較為一致的展示效果。
使用前請(qǐng)注意將body的margin設(shè)為0,否則會(huì)引起計(jì)算誤差。
fullScreenContainer.vue
<template><div id="full-screen-container" :ref="ref"><template v-if="ready"><slot>slot>template>div>template><script>import autoResize from './autoResize.js'export default {name: 'DvFullScreenContainer',mixins: [autoResize],data () {return {ref: 'full-screen-container',allWidth: 0,scale: 0,datavRoot: '',ready: false}},methods: {afterAutoResizeMixinInit () {const { initConfig, setAppScale } = thisinitConfig()setAppScale()this.ready = true},initConfig () {const { dom } = thisconst { width, height } = screenthis.allWidth = widthdom.style.width = `${width}px`dom.style.height = `${height}px`},setAppScale () {const { allWidth, dom } = thisconst currentWidth = document.body.clientWidthdom.style.transform = `scale(${currentWidth / allWidth})`},onResize () {const { setAppScale } = thissetAppScale()}}}script><style lang="scss">#full-screen-container {position: fixed;top: 0px;left: 0px;overflow: hidden;transform-origin: left top;z-index: 999;}style>
autoResize.js
export default {data() {return {dom: '',width: 0,height: 0,debounceInitWHFun: '',domObserver: ''};},methods: {debounce(delay, callback) {let lastTime;return function() {clearTimeout(lastTime);const [that, args] = [this, arguments];lastTime = setTimeout(() => {callback.apply(that, args);}, delay);};},observerDomResize(dom, callback) {const MutationObserver =window.MutationObserver ||window.WebKitMutationObserver ||window.MozMutationObserver;const observer = new MutationObserver(callback);observer.observe(dom, {attributes: true,attributeFilter: ['style'],attributeOldValue: true});return observer;},async autoResizeMixinInit() {const {initWH,getDebounceInitWHFun,bindDomResizeCallback,afterAutoResizeMixinInit} = this;await initWH(false);getDebounceInitWHFun();bindDomResizeCallback();if (typeof afterAutoResizeMixinInit === 'function')afterAutoResizeMixinInit();},initWH(resize = true) {const { $nextTick, $refs, ref, onResize } = this;return new Promise(resolve => {$nextTick(() => {const dom = (this.dom = $refs[ref]);this.width = dom ? dom.clientWidth : 0;this.height = dom ? dom.clientHeight : 0;if (!dom) {console.warn('DataV: Failed to get dom node, component rendering may be abnormal!');} else if (!this.width || !this.height) {console.warn('DataV: Component width or height is 0px, rendering abnormality may occur!');}if (typeof onResize === 'function' && resize) onResize();resolve();});});},getDebounceInitWHFun() {const { initWH } = this;this.debounceInitWHFun = this.debounce(100, initWH);},bindDomResizeCallback() {const { dom, debounceInitWHFun } = this;this.domObserver = this.observerDomResize(dom, debounceInitWHFun);window.addEventListener('resize', debounceInitWHFun);},unbindDomResizeCallback() {let { domObserver, debounceInitWHFun } = this;if (!domObserver) return;domObserver.disconnect();domObserver.takeRecords();domObserver = null;window.removeEventListener('resize', debounceInitWHFun);}},mounted() {const { autoResizeMixinInit } = this;autoResizeMixinInit();},beforeDestroy() {const { unbindDomResizeCallback } = this;unbindDomResizeCallback();}};
這樣,一個(gè)頁(yè)面自適應(yīng)組件就這樣搭建完成了,下面,我們將引入組件看一下效果。
<template><div id="app"><fullScreenContainer><img alt="Vue logo" src="./assets/logo.png" /><HelloWorld msg="Welcome to Your Vue.js App" />fullScreenContainer>div>template><script>import HelloWorld from "./components/HelloWorld.vue";import fullScreenContainer from "./components/fullScreenContainer/fullScreenContainer.vue";export default {name: "App",components: {HelloWorld,fullScreenContainer,},};script><style>#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;}style>

效果很好,這樣對(duì)于一些開(kāi)發(fā)自適應(yīng)頁(yè)面非常容易。
歡迎關(guān)注我的公眾號(hào) 前端歷劫之路回復(fù)關(guān)鍵詞 電子書(shū),即可獲取12本前端熱門(mén)電子書(shū)。回復(fù)關(guān)鍵詞 紅寶書(shū)第4版,即可獲取最新《JavaScript高級(jí)程序設(shè)計(jì)》(第四版)電子書(shū)。我創(chuàng)建了一個(gè)技術(shù)交流、文章分享群,群里有很多大廠的前端大佬,關(guān)注公眾號(hào)后,點(diǎn)擊下方菜單了解更多即可加我微信,期待你的加入。

評(píng)論
圖片
表情
