日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

第130天:移动端-rem布局

發(fā)布時間:2025/6/16 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第130天:移动端-rem布局 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、關(guān)于布局方案

當(dāng)拿到設(shè)計師給的UI設(shè)計圖,前端的首要任務(wù)就是布局和樣式,相信這對于大部分前端工程師來說已經(jīng)不是什么難題了。移動端的布局相對PC較為簡單,關(guān)鍵在于對不同設(shè)備的適配。之前介紹了一篇關(guān)于移動端rem布局方案,這大致是網(wǎng)易H5的適配方案。不過實踐中發(fā)現(xiàn)淘寶開源的可伸縮布局方案效果更好且更容易使用。

網(wǎng)易云的方案總結(jié)為:根據(jù)屏幕大小 / 750 = 所求字體 / 基準(zhǔn)字體大小比值相等,動態(tài)調(diào)節(jié)html的font-size大小。

淘寶的方案總結(jié)為:根據(jù)設(shè)備設(shè)備像素比設(shè)置scale的值,保持視口device-width始終等于設(shè)備物理像素,接著根據(jù)屏幕大小動態(tài)計算根字體大小,具體是將屏幕劃分為10等分,每份為a,1rem就等于10a。

通常我們會拿到750寬的設(shè)計稿,這是基于iPhone6的物理分辨率。有的設(shè)計師也許會偷懶,設(shè)計圖上面沒有任何的標(biāo)注,如果我們邊開發(fā)邊量尺寸,無疑效率是比較低的。要么讓設(shè)計師標(biāo)注上,要么自食其力。如果設(shè)計師實在沒有時間,推薦使用markman進(jìn)行標(biāo)注,免費版閹割了一些功能(比如無法保存本地)不過基本滿足了我們的需求了。

標(biāo)注完成后開始寫我們的樣式,使用了淘寶的lib-flexible庫之后,我們的根字體基準(zhǔn)值就為750/100*10 = 75px。此時我們從圖中若某個標(biāo)注為100px,那么css中就應(yīng)該設(shè)置為100/75 = 1.333333rem。所以為了提高開發(fā)效率,可以使用px轉(zhuǎn)化為rem的插件。如果你使用sublimeText,可以用?rem-unit

使用rem單位注意以下幾點:

  • 在所有的單位中,font-size推薦使用px,然后結(jié)合媒體查詢進(jìn)行重要節(jié)點的控制,這樣可以滿足突出或者弱化某些字體的需求,而非整體調(diào)整。

  • 縱向的單位可以全部使用px,橫向的使用rem,因為移動設(shè)備寬度有限,而高度可以無限向下滑動。但這也有特例,比如對于一些活動注冊頁面,需要在一屏幕內(nèi)完全顯示,沒有下拉,這時候所有縱向或者橫向都應(yīng)該使用rem作為單位。如圖:

  • 左圖的表單高度單位由于下邊空距較大,使用px在不同屏幕顯示更加;而右邊的活動注冊頁由于不能出現(xiàn)滾動條,所有的眾向高度、margin、padding都應(yīng)該使用rem

    ?3. border、box-shadow、border-radius等一些效果應(yīng)該使用px作為單位。

    二、基于接口返回數(shù)據(jù)的屬性注入

    可能大家不明白什么叫"基于接口返回數(shù)據(jù)的屬性注入",在此之前,先說一下表單數(shù)據(jù)的綁定方式,一個重要的點是有幾份表單就分開幾個表單對象進(jìn)行數(shù)據(jù)綁定

    已上圖公積金查詢?yōu)槔?#xff0c;由于不同城市會有不同的查詢要素,可能登陸方式只有一種,也可能有幾種。比如上圖有三種登陸方式,在使用vue布局時,有兩種方案。一是只建立一個表單用于數(shù)據(jù)綁定,點擊按鈕觸發(fā)判斷;而是有幾種登陸方式建立幾個表單,用一個字段標(biāo)識當(dāng)前顯示的表單。由于使用第三方的接口,一開始也沒有先進(jìn)行接口返回數(shù)據(jù)結(jié)構(gòu)的查看,采用了第一種錯誤的方式,錯誤一是每種登陸方式下面的登陸要素的數(shù)量也不同,錯誤二是數(shù)據(jù)綁定在同一個表單data下,當(dāng)用戶在用戶名登陸方式輸入用戶名密碼后,切換到客戶號登陸方式,就會出現(xiàn)數(shù)據(jù)錯亂的情況。

    解決完布局問題后,我們需要根據(jù)設(shè)計圖定義一些狀態(tài),比如當(dāng)前登陸方式的切換、同意授權(quán)狀態(tài)的切換、按鈕是否可以點擊的狀態(tài)、是否處于請求中的狀態(tài)。當(dāng)然還有一些app穿過來的數(shù)據(jù),這里就忽略了。

    1 data: { 2 tags: { 3 arr: [''], 4 activeIndex: 0 5 }, 6 isAgreeProxy: true, 7 isLoading: false 8 }

    接著審查一下接口返回的數(shù)據(jù),推薦使用chrome插件postman,比如呼和浩特的登陸要素如下:

    {"code": 2005,"data": [{"name": "login_type","label": "身份證號","fields": [{"name": "user_name","label": "身份證號","type": "text"},{"name": "user_pass","label": "密碼","type": "password"}],"value": "1"},{"name": " login_type","label": "公積金賬號","fields": [{"name": "user_name","label": "公積金賬號","type": "text"},{"name": "user_pass","label": "密碼","type": "password"}],"value": "0"}],"message": "登錄要素請求成功" }

    可以看到呼和浩特有兩種授權(quán)登陸方式,我們在data中定義了一個loginWays,初始為空數(shù)組,接著methods中定義一個請求接口的函數(shù),里面就是基于返回數(shù)據(jù)的基礎(chǔ)上為上面fields對象注入一個input字段用于綁定,這就是所謂的基于接口返回數(shù)據(jù)的屬性注入。

    1 methods: { 2 queryloginWays: function(channel_type, channel_code) { 3 var params = new URLSearchParams(); 4 params.append('channel_type', channel_type); 5 params.append('channel_code', channel_code); 6 axios.post(this.loginParamsProxy, params) 7 .then(function(res) { 8 console.log(res); 9 var code = res.code || res.data.code; 10 var msg = res.message || res.data.message; 11 var loginWays = res.data.data ? res.data.data : res.data; 12 // 查詢失敗 13 if (code != 2005) { 14 alert(msg); 15 return; 16 } 17 // 添加input字段用于v-model綁定 18 loginWays.forEach(function(loginWay) { 19 loginWay.fields.forEach(function(field) { 20 field.input = ''; 21 }) 22 }) 23 this.loginWays = loginWays; 24 this.tags.arr = loginWays.map(function(loginWay) { 25 return loginWay.label; 26 }) 27 }.bind(this)) 28 } 29 }

    即使返回的數(shù)據(jù)有我們不需要的數(shù)據(jù)也沒有關(guān)系,這樣保證我們不會遺失進(jìn)行下一步登陸所需要的數(shù)據(jù)。

    這樣多個表單綁定數(shù)據(jù)問題解決了,那么怎么進(jìn)行頁面間數(shù)據(jù)傳遞?如果是app傳過來,那么通常使用URL拼接的方式,使用window.location.search獲得queryString后再進(jìn)行截取;如果通過頁面套入javaWeb中,那么直接使用"${字段名}"就能獲取,注意要js中獲取java字段需要加雙引號。

    computed: {// 真實姓名realName: function() {return this.getQueryVariable('name') || ''},// 身份證identity: function() {return parseInt(this.getQueryVariable('identity')) || ''},/*If javaWebrealName: function() {return this.getQueryVariable('name') || ''},identity: function() {return parseInt(this.getQueryVariable('identity')) || ''}*/},methods: {getQueryVariable: function(variable) {var query = window.location.search.substring(1);var vars = query.split('&');for (var i = 0; i < vars.length; i++) {var pair = vars[i].split('=');if (decodeURIComponent(pair[0]) == variable) {return decodeURIComponent(pair[1]);}}console.log('Query variable %s not found', variable);}}

    三、關(guān)于前端跨域調(diào)試

    在進(jìn)行接口請求時,我們的頁面通常是在sublime的本地服務(wù)器或者vscode本地服務(wù)器預(yù)覽,所以請求接口會遇到跨域的問題。 在項目構(gòu)建的時候通常我們源代碼會放在src文件夾下,然后使用gulp進(jìn)行代碼的壓縮、合并、圖片的優(yōu)化(根據(jù)需要)等等,我們會使用gulp。這里解決跨域的問題可以用gulp-connect結(jié)合http-proxy-middleware,此時我們在gulp-connect中的本地服務(wù)器進(jìn)行預(yù)覽調(diào)試。 gulpfile.js如下: 開發(fā)過程使用gulp server命令,監(jiān)聽文件改動并使用livereload刷新;使用gulp命令進(jìn)行打包。

    1 var gulp = require('gulp'); 2 var concat = require('gulp-concat'); 3 var uglify = require('gulp-uglify'); 4 var autoprefixer = require('gulp-autoprefixer'); 5 var useref = require('gulp-useref'); 6 var connect = require('gulp-connect'); 7 var proxyMiddleware = require('http-proxy-middleware'); 8 // 定義環(huán)境變量,若為 dev,則代理src目錄; 若為prod,則代理dist目錄 9 var env = 'prod' 10 // 跨域代理 將localhost:8088/api 映射到 https://api.shujumohe.com/ 11 gulp.task('server', ['listen'], function() { 12 var middleware = proxyMiddleware(['/api'], { 13 target: 'https://api.shujumohe.com/', 14 changeOrigin: true, 15 pathRewrite: { 16 '^/api': '/' 17 } 18 }); 19 connect.server({ 20 root: env == 'dev' ? './src' : './dist', 21 port: 8088, 22 livereload: true, 23 middleware: function(connect, opt) { 24 return [middleware] 25 } 26 }); 27 }); 28 gulp.task('html', function() { 29 gulp.src('src/*.html') 30 .pipe(useref()) 31 .pipe(gulp.dest('dist')); 32 }); 33 gulp.task('css', function() { 34 gulp.src('src/css/main.css') 35 .pipe(concat('main.css')) 36 .pipe(autoprefixer({ 37 browsers: ['last 2 versions'], 38 cascade: false 39 })) 40 .pipe(gulp.dest('dist/css/')); 41 gulp.src('src/css/share.css') 42 .pipe(concat('share.css')) 43 .pipe(autoprefixer({ 44 browsers: ['last 2 versions'], 45 cascade: false 46 })) 47 .pipe(gulp.dest('dist/css/')); 48 gulp.src('src/vendors/css/*.css') 49 .pipe(concat('vendors.min.css')) 50 .pipe(autoprefixer({ 51 browsers: ['last 2 versions'], 52 cascade: false 53 })) 54 .pipe(gulp.dest('dist/vendors/css')); 55 return gulp 56 }); 57 gulp.task('js', function() { 58 return gulp.src('src/vendors/js/*.js') 59 .pipe(concat('vendors.min.js')) 60 .pipe(uglify()) 61 .pipe(gulp.dest('dist/vendors/js')); 62 }); 63 gulp.task('img', function() { 64 gulp.src('src/imgs/*') 65 .pipe(gulp.dest('dist/imgs')); 66 }); 67 gulp.task('listen', function() { 68 gulp.watch('./src/css/*.css', function() { 69 gulp.src(['./src/css/*.css']) 70 .pipe(connect.reload()); 71 }); 72 gulp.watch('./src/js/*.js', function() { 73 gulp.src(['./src/js/*.js']) 74 .pipe(connect.reload()); 75 }); 76 gulp.watch('./src/*.html', function() { 77 gulp.src(['./src/*.html']) 78 .pipe(connect.reload()); 79 }); 80 }); 81 gulp.task('default', ['html', 'css', 'js', 'img']);

    ?

    《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的第130天:移动端-rem布局的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。