从0到1搭建一款页面自适应组件(Vue.js)

开发 前端
本篇教大家从0到1搭建一款页面自适应组件(Vue.js), 组件将根据屏幕比例及当前浏览器窗口大小,自动进行缩放处理。建议在组件内使用百分比搭配flex进行布局,以便于在不同的分辨率下得到较为一致的展示效果。

[[382308]]

 组件将根据屏幕比例及当前浏览器窗口大小,自动进行缩放处理。

  • 建议在组件内使用百分比搭配flex进行布局,以便于在不同的分辨率下得到较为一致的展示效果。
  • 使用前请注意将body的margin设为0,否则会引起计算误差。

fullScreenContainer.vue

  1. <template> 
  2.   <div id="full-screen-container" :ref="ref"
  3.     <template v-if="ready"
  4.       <slot></slot> 
  5.     </template> 
  6.   </div> 
  7. </template> 
  8.  
  9. <script> 
  10. import autoResize from './autoResize.js' 
  11. export default { 
  12.   name'DvFullScreenContainer'
  13.   mixins: [autoResize], 
  14.   data () { 
  15.     return { 
  16.       ref: 'full-screen-container'
  17.       allWidth: 0, 
  18.       scale: 0, 
  19.       datavRoot: ''
  20.       ready: false 
  21.     } 
  22.   }, 
  23.   methods: { 
  24.     afterAutoResizeMixinInit () { 
  25.       const { initConfig, setAppScale } = this 
  26.       initConfig() 
  27.       setAppScale() 
  28.       this.ready = true 
  29.     }, 
  30.     initConfig () { 
  31.       const { dom } = this 
  32.       const { width, height } = screen 
  33.       this.allWidth = width 
  34.       dom.style.width = `${width}px` 
  35.       dom.style.height = `${height}px` 
  36.     }, 
  37.     setAppScale () { 
  38.       const { allWidth, dom } = this 
  39.       const currentWidth = document.body.clientWidth 
  40.       dom.style.transform = `scale(${currentWidth / allWidth})` 
  41.     }, 
  42.     onResize () { 
  43.       const { setAppScale } = this 
  44.       setAppScale() 
  45.     } 
  46.   } 
  47. </script> 
  48.  
  49. <style lang="scss"
  50. #full-screen-container { 
  51.   position: fixed; 
  52.   top: 0px; 
  53.   left: 0px; 
  54.   overflow: hidden; 
  55.   transform-origin: left top
  56.   z-index: 999; 
  57. </style> 

autoResize.js

  1. export default { 
  2.     data() { 
  3.         return { 
  4.             dom: ''
  5.             width: 0, 
  6.             height: 0, 
  7.             debounceInitWHFun: ''
  8.             domObserver: '' 
  9.         }; 
  10.     }, 
  11.     methods: { 
  12.         debounce(delay, callback) { 
  13.             let lastTime; 
  14.  
  15.             return function() { 
  16.                 clearTimeout(lastTime); 
  17.  
  18.                 const [that, args] = [this, arguments]; 
  19.  
  20.                 lastTime = setTimeout(() => { 
  21.                     callback.apply(that, args); 
  22.                 }, delay); 
  23.             }; 
  24.         }, 
  25.  
  26.         observerDomResize(dom, callback) { 
  27.             const MutationObserver = 
  28.                 window.MutationObserver || 
  29.                 window.WebKitMutationObserver || 
  30.                 window.MozMutationObserver; 
  31.  
  32.             const observer = new MutationObserver(callback); 
  33.  
  34.             observer.observe(dom, { 
  35.                 attributes: true
  36.                 attributeFilter: ['style'], 
  37.                 attributeOldValue: true 
  38.             }); 
  39.  
  40.             return observer; 
  41.         }, 
  42.         async autoResizeMixinInit() { 
  43.             const { 
  44.                 initWH, 
  45.                 getDebounceInitWHFun, 
  46.                 bindDomResizeCallback, 
  47.                 afterAutoResizeMixinInit 
  48.             } = this; 
  49.  
  50.             await initWH(false); 
  51.  
  52.             getDebounceInitWHFun(); 
  53.  
  54.             bindDomResizeCallback(); 
  55.  
  56.             if (typeof afterAutoResizeMixinInit === 'function'
  57.                 afterAutoResizeMixinInit(); 
  58.         }, 
  59.         initWH(resize = true) { 
  60.             const { $nextTick, $refs, ref, onResize } = this; 
  61.  
  62.             return new Promise(resolve => { 
  63.                 $nextTick(() => { 
  64.                     const dom = (this.dom = $refs[ref]); 
  65.  
  66.                     this.width = dom ? dom.clientWidth : 0; 
  67.                     this.height = dom ? dom.clientHeight : 0; 
  68.  
  69.                     if (!dom) { 
  70.                         console.warn( 
  71.                             'DataV: Failed to get dom node, component rendering may be abnormal!' 
  72.                         ); 
  73.                     } else if (!this.width || !this.height) { 
  74.                         console.warn( 
  75.                             'DataV: Component width or height is 0px, rendering abnormality may occur!' 
  76.                         ); 
  77.                     } 
  78.  
  79.                     if (typeof onResize === 'function' && resize) onResize(); 
  80.  
  81.                     resolve(); 
  82.                 }); 
  83.             }); 
  84.         }, 
  85.         getDebounceInitWHFun() { 
  86.             const { initWH } = this; 
  87.  
  88.             this.debounceInitWHFun = this.debounce(100, initWH); 
  89.         }, 
  90.         bindDomResizeCallback() { 
  91.             const { dom, debounceInitWHFun } = this; 
  92.  
  93.             this.domObserver = this.observerDomResize(dom, debounceInitWHFun); 
  94.  
  95.             window.addEventListener('resize', debounceInitWHFun); 
  96.         }, 
  97.         unbindDomResizeCallback() { 
  98.             let { domObserver, debounceInitWHFun } = this; 
  99.  
  100.             if (!domObserver) return
  101.  
  102.             domObserver.disconnect(); 
  103.             domObserver.takeRecords(); 
  104.             domObserver = null
  105.  
  106.             window.removeEventListener('resize', debounceInitWHFun); 
  107.         } 
  108.     }, 
  109.     mounted() { 
  110.         const { autoResizeMixinInit } = this; 
  111.  
  112.         autoResizeMixinInit(); 
  113.     }, 
  114.     beforeDestroy() { 
  115.         const { unbindDomResizeCallback } = this; 
  116.  
  117.         unbindDomResizeCallback(); 
  118.     } 
  119. }; 

这样,一个页面自适应组件就这样搭建完成了,下面,我们将引入组件看一下效果。

  1. <template> 
  2.   <div id="app"
  3.     <fullScreenContainer> 
  4.       <img alt="Vue logo" src="./assets/logo.png" /> 
  5.       <HelloWorld msg="Welcome to Your Vue.js App" /> 
  6.     </fullScreenContainer> 
  7.   </div> 
  8. </template> 
  9.  
  10. <script> 
  11. import HelloWorld from "./components/HelloWorld.vue"
  12. import fullScreenContainer from "./components/fullScreenContainer/fullScreenContainer.vue"
  13. export default { 
  14.   name"App"
  15.   components: { 
  16.     HelloWorld, 
  17.     fullScreenContainer, 
  18.   }, 
  19. }; 
  20. </script> 
  21.  
  22. <style> 
  23. #app { 
  24.   font-family: Avenir, Helvetica, Arial, sans-serif; 
  25.   -webkit-font-smoothing: antialiased; 
  26.   -moz-osx-font-smoothing: grayscale; 
  27.   text-align: center; 
  28.   color: #2c3e50; 
  29.   margin-top: 60px; 
  30. </style> 

 

效果很好,这样对于一些开发自适应页面非常容易。

 

责任编辑:姜华 来源: 前端历劫之路
相关推荐

2020-12-29 05:26:27

视频播放器Vuevideo

2021-01-27 07:24:38

TypeScript工具Java

2022-01-27 13:02:46

前端爬虫工具

2021-09-26 05:00:11

Vscode插件

2021-03-30 07:11:22

Vue3parcel-vue-工具

2023-11-15 08:14:35

2023-03-29 08:52:58

视觉Vue组件库

2023-03-06 11:35:55

经营分析体系

2017-07-11 18:00:21

vue.js数据组件

2021-04-12 08:31:53

PC-Dooring项目PC端搭建

2022-03-15 11:51:00

决策分析模型

2020-09-16 06:12:30

Vue.js 3.0Suspense组件前端

2017-05-27 09:23:10

IOS框架APP框架代码

2022-06-13 07:02:02

Zadig平台自动化

2019-07-31 10:18:17

Web 开发Python

2023-03-16 14:29:48

Vue.js测试

2016-09-19 13:44:54

vue翻页组件Web

2021-02-10 07:31:12

VuejsElementUI

2022-12-01 17:13:44

2016-11-28 16:23:23

戴尔
点赞
收藏

51CTO技术栈公众号