vue中實(shí)現(xiàn)一個(gè)項(xiàng)目里兼容移動(dòng)端和pc端
一個(gè)項(xiàng)目里兼容移動(dòng)端和pc端
話不多說,上代碼
先來看一下我的文件
路由文件 index.js:
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ mode:"history", routes: [ // pc端 { path: '/', name: 'pc/home', component: ()=>import("@/components/pc/home"), }, // 手機(jī)端 { path: '/mobile/home', name: 'mobile/home', component: ()=>import("@/components/mobile/home"), }, ] })
在app.vue中
mounted(){ if (this._isMobile()) { // 手機(jī)端 this.$router.replace("/mobile/home"); } else { // pc端 this.$router.replace("/"); } }, methods:{ _isMobile() { let flag = navigator.userAgent.match( /(phone|pad|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows phone)/i ); return flag; }, }
vue移動(dòng)端與PC端適配方案viewport+postcss-px-to-viewport
GitHub文檔地址:https://github.com/evrone/postcss-px-to-viewport
GitHub - evrone/postcss-px-to-viewport: A plugin for PostCSS that generates viewport units (vw, vh, vmin, vmax) from pixel units. The best choice to create a scalable interface on different displays by one design size.
優(yōu)點(diǎn)
- 不需要換算及轉(zhuǎn)換系數(shù)
- 某些屬性不需要轉(zhuǎn)換為REM、VW等
- 可以全部使用px單位
lib-flexible 作者推薦,方便好用
什么是viewport
viewport翻譯成中文的意思大致是視圖、視窗。在移動(dòng)端設(shè)備中,整塊顯示屏就相當(dāng)于視圖、視窗。但這種說法也并不完全正確。因?yàn)樵谝苿?dòng)端設(shè)備中,瀏覽器視圖并不是整個(gè)屏幕。因此viewport又被分為了3種 layout viewport(布局視口)、visual viewport(視覺視口)、ideal viewport(理想視口)
為了能夠適配到pc端開發(fā)頁面中,大部分瀏覽器把viewport的寬度設(shè)為了980px 這個(gè)瀏覽器默認(rèn)設(shè)置的視圖被稱為 layout viewport。我們可以使用document.documentElement.clientWidth 來獲取。
由于 layout viewport的寬度是遠(yuǎn)大于瀏覽器寬度的,因此我們需要一個(gè)新的viewport來代表瀏覽器的可視區(qū)域?qū)挾?,這個(gè)視圖則被稱為visual viewport我們可以使用window.innerWidth來獲取。
現(xiàn)在我們已經(jīng)有兩個(gè)viewport了,layout viewport 和 visual viewport。但瀏覽器覺得還不夠,因?yàn)楝F(xiàn)在越來越多的網(wǎng)站都會(huì)為移動(dòng)設(shè)備進(jìn)行單獨(dú)的設(shè)計(jì),所以必須還要有一個(gè)能完美適配移動(dòng)設(shè)備的ideal viewport。
ideal viewport 并沒有一個(gè)固定的尺寸,不同的設(shè)備擁有不同的 ideal viewport。比如iphone5的 ideal viewport是 320px 而 iphone6s的 ideal viewport卻是 375px
使用方法
- 下載插件postcss-px-to-viewport
- 根目錄下創(chuàng)建配置文件postcss.config.js
- 添加所需要的配置項(xiàng)
//引入?postcss-px-to-viewport npm?install?postcss-px-to-viewport?--save-dev?
//postcss.config.js module.exports = { plugins: { 'postcss-px-to-viewport': { unitToConvert: "px", // 要轉(zhuǎn)化的單位 viewportWidth: 1920, // UI設(shè)計(jì)稿的寬度 unitPrecision: 6, // 轉(zhuǎn)換后的精度,即小數(shù)點(diǎn)位數(shù) propList: ["*"], // 指定轉(zhuǎn)換的css屬性的單位,*代表全部css屬性的單位都進(jìn)行轉(zhuǎn)換 viewportUnit: "vw", // 指定需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw fontViewportUnit: "vw", // 指定字體需要轉(zhuǎn)換成的視窗單位,默認(rèn)vw selectorBlackList: ["wrap"], // 指定不轉(zhuǎn)換為視窗單位的類名, minPixelValue: 1, // 默認(rèn)值1,小于或等于1px則不進(jìn)行轉(zhuǎn)換 mediaQuery: true, // 是否在媒體查詢的css代碼中也進(jìn)行轉(zhuǎn)換,默認(rèn)false replace: true, // 是否轉(zhuǎn)換后直接更換屬性值 exclude: [/node_modules/], // 設(shè)置忽略文件,用正則做目錄名匹配 include: undefined, // 如果設(shè)置了include,那將只有匹配到的文件才會(huì)被轉(zhuǎn)換 landscape: false, // 是否添加根據(jù) landscapeWidth 生成的媒體查詢條件 @media (orientation: landscape) landscapeUnit: 'vw', // 橫屏?xí)r使用的單位 landscapeWidth: 1920 // 橫屏?xí)r使用的視口寬度 } } }
需要注意的配置:
propList
: 當(dāng)有些屬性的單位我們不希望轉(zhuǎn)換的時(shí)候,可以添加在數(shù)組后面,并在前面加上!號(hào),如propList: ["*","!letter-spacing"],這表示:所有css屬性的屬性的單位都進(jìn)行轉(zhuǎn)化,除了letter-spacing的selectorBlackList
:轉(zhuǎn)換的黑名單,在黑名單里面的我們可以寫入字符串,只要類名包含有這個(gè)字符串,就不會(huì)被匹配。比如selectorBlackList: ['wrap'],它表示形如wrap,my-wrap,wrapper這樣的類名的單位,都不會(huì)被轉(zhuǎn)換
vant組件庫兼容問題
vant組件庫的設(shè)計(jì)稿是按照375px來開發(fā)的。因此在viewportWidth
為750px
時(shí)會(huì)出現(xiàn)轉(zhuǎn)換問題。
// postcss.config.js const path = require('path'); module.exports = ({ webpack }) => { const viewWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750; //如果讀取的node_modules中的文件是vant,那么就將設(shè)計(jì)稿變?yōu)?75px。如果讀取的文件不是vant的文件,那么就將設(shè)計(jì)稿變?yōu)?50px。這樣就可以避免vant組件在750px下出現(xiàn)樣式縮小的問題了。拼接的原因是Windows和iOS系統(tǒng)的路徑轉(zhuǎn)義符不一樣Windows是“/”,ios是“\” return { plugins: { autoprefixer: {}, "postcss-px-to-viewport": { unitToConvert: "px", viewportWidth: viewWidth, unitPrecision: 6, propList: ["*"], viewportUnit: "vw", fontViewportUnit: "vw", selectorBlackList: [], minPixelValue: 1, mediaQuery: true, exclude: [], landscape: false } } } }
效果圖:
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue3如何使用provide實(shí)現(xiàn)狀態(tài)管理詳解
Vue3中有一對(duì)新增的api,provide和inject,熟悉Vue2的朋友應(yīng)該明,這篇文章主要給大家介紹了關(guān)于vue3如何使用provide實(shí)現(xiàn)狀態(tài)管理的相關(guān)資料,需要的朋友可以參考下2021-10-10在vue項(xiàng)目中集成graphql(vue-ApolloClient)
這篇文章主要介紹了在vue項(xiàng)目中集成graphql(vue-ApolloClient),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09vue+elementUI如何實(shí)現(xiàn)頂部路由標(biāo)簽跳轉(zhuǎn)
這篇文章主要介紹了vue+elementUI如何實(shí)現(xiàn)頂部路由標(biāo)簽跳轉(zhuǎn)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03一文學(xué)會(huì)什么是vue.nextTick()
這篇文章主要介紹了一文學(xué)會(huì)什么是vue.nextTick(),下面文章圍繞主題的相關(guān)資料展開詳細(xì)內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-04-04詳解Vue CLI 3.0腳手架如何mock數(shù)據(jù)
這篇文章主要介紹了詳解Vue CLI 3.0腳手架如何mock數(shù)據(jù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11