第152天:表单短标题的两端对齐

在做前端界面的时候,比如一些文字的列表或者一些表单的标题,经常是2个字,3个字,4个字的类型。

一般对齐就是在中间打空格或者用 来空开,但是效果并不好,兼容性有问题,造成不美观。经过一番折腾,

找到了比较好的办法解决。利用letter-spacing来解决:

letter-spacing 属性增加或减少字符间的空白(字符间距)。

该属性定义了在文本字符框之间插入多少空间。由于字符字形通常比其字符框要窄,指定长度值时,会调整字母之间通常的间隔。因此,normal 就相当于值为 0。

 1 <style type="text/css">
 2 .hotsearch dd{
 3 float: left;
 4 line-height: 24px;
 5 margin-right: 30px;
 6 overflow: hidden;
 7 text-align: center;
 8 width: 4em; /*这个值是看最长能显示几个文字,如x,则为x em*/
 9 }
10 .hotsearch dd a{
11 display:block;
12 }
13 .w2{
14 letter-spacing:2em; /*如果需要y个字两端对齐,则为(x-y)/(y-1),这里是(4-2)/(2-1)=2em */
15 margin-right:-2em; /*同上*/
16 }
17 .w3{
18 letter-spacing:0.5em; /*如果需要y个字两端对齐,则为(x-y)/(y-1),这里是(4-3)/(3-1)=0.5em */
19 margin-right:-0.5em; /*同上*/
20 }
21 </style>
 1 <span style="font-size:12px;"><dl class="hotsearch" style="width:300px;">
 2 <dt>热门搜索</dt>
 3 <dd><a href="#" target="_blank" ref="nav" class="w3">电视机</a></dd>
 4 <dd><a href="#" target="_blank" ref="nav" class="w4">性感漂亮</a></dd>
 5 <dd><a href="#" target="_blank" ref="nav" class="w3">高跟鞋</a></dd>
 6 <dd><a href="#" target="_blank" ref="nav" class="w2">手机</a></dd>
 7 <dd><a href="#" target="_blank" ref="nav" class="w2">对齐</a></dd>
 8 <dd><a href="#" target="_blank" ref="nav" class="w3">牛仔裤</a></dd>
 9 <dd><a href="#" target="_blank" ref="nav" class="w4">小家碧玉</a></dd>
10 <dd><a href="#" target="_blank" ref="nav" class="w2">家居</a></dd>
11 </dl></span>

 

<template> <!-- 背景图容器 --> <view class="background-container"> <image class="background-image" src="/static/dlbj.jpg" mode="aspectFill" ></image> <!-- 半透明遮罩 --> <view class="overlay"></view> </view> <!-- 登录表单 --> <view class="login-container"> <view class="login-form"> <text class="login-title">用户登录</text> <input v-model="username" placeholder="用户名" class="login-input" placeholder-class="input-placeholder" /> <input v-model="password" type="password" placeholder="密码" class="login-input" placeholder-class="input-placeholder" /> <!-- 记住密码 --> <view class="remember-section"> <checkbox-group @change="toggleRemember"> <label class="checkbox-label"> <checkbox :checked="remember" color="#3498db" style="transform: scale(0.8);" /> <text>记住账号密码</text> </label> </checkbox-group> <text class="forgot-password" @click="handleForgotPassword">忘记账号密码</text> </view> <button class="login-button" :loading="loading" @click="handleLogin" >登录</button> </view> </view> </template> <script> import { ref,onMounted } from 'vue' import { onShow } from '@dcloudio/uni-app'; export default { setup() { const username = ref('') const password = ref('') const loading = ref(false) const remember = ref(false) // 记住密码状态 // 页面加载时检查是否有保存的凭据 onMounted(() => { const savedUsername = uni.getStorageSync('savedUsername') const savedPassword = uni.getStorageSync('savedPassword') if (savedUsername && savedPassword) { username.value = savedUsername password.value = savedPassword remember.value = true } }) // 切换记住密码状态 const toggleRemember = (e) => { remember.value = e.detail.value.length > 0 } // 忘记密码处理 const handleForgotPassword = () => { uni.showModal({ title: '忘记密码', content: '是否清除保存的账号密码?', success: (res) => { if (res.confirm) { // 清除保存的账号密码 uni.removeStorageSync('savedUsername') uni.removeStorageSync('savedPassword') username.value = '' password.value = '' remember.value = false uni.showToast({ title: '已清除账号密码', icon: 'success' }) } } }) } const handleLogin = async () => { // 验证输入 if (!username.value.trim()) { uni.showToast({ title: '请输入用户名', icon: 'none', duration: 2000 }) return } if (!password.value) { uni.showToast({ title: '请输入密码', icon: 'none', duration: 2000 }) return } loading.value = true try { // 兼容性请求 const response = await new Promise((resolve, reject) => { uni.request({ url: 'http://172.26.26.43/dev-api/login', method: 'POST', data: { username: username.value, password: password.value }, header: { 'Content-Type': 'application/json' }, timeout: 10000, success: (res) => resolve(res), fail: (err) => reject(err) }) }) // 处理响应 await handleResponse(response) // 登录成功后保存凭据(如果用户选择了记住密码) if (remember.value) { saveCredentials() } else { clearSavedCredentials() } } catch (error) { console.error('登录请求出错:', error) let errorMsg = '登录失败,请重试' if (error.errMsg) { errorMsg = `请求失败: ${error.errMsg}` } else if (error.message) { errorMsg = error.message } uni.showToast({ title: errorMsg, icon: 'none', duration: 2000 }) } finally { loading.value = false } } // 保存凭据到本地存储 const saveCredentials = () => { uni.setStorageSync('savedUsername', username.value) uni.setStorageSync('savedPassword', password.value) } // 清除保存的凭据 const clearSavedCredentials = () => { uni.removeStorageSync('savedUsername') uni.removeStorageSync('savedPassword') } // 清除token缓存 onShow(() => { uni.removeStorageSync('token'); uni.removeStorageSync('userInfo'); }); const handleResponse = async (response) => { // 检查HTTP状态码 if (response.statusCode < 200 || response.statusCode >= 300) { throw new Error(`服务器错误: ${response.statusCode}`) } // 解析响应数据 const { data } = response if (!data) { throw new Error('服务器返回空数据') } const { code, message, token } = data if (code === 200) { // 存储token uni.setStorageSync('token', token) uni.showToast({ title: '登录成功!', icon: 'success', duration: 1000 }) // 登录成功后跳转 setTimeout(() => { uni.redirectTo({ url: '/pages/index/index' }) }, 1000) } else { throw new Error(`登录失败: ${message || '未知错误'}`) } } // 在登录页面的onShow方法中 onShow(() => { // 清除 token 缓存 uni.removeStorageSync('token'); // 清除其他用户相关数据 uni.removeStorageSync('userInfo'); console.log('已清除登录状态缓存'); // 生产环境可移除 }); return { username, password, remember, loading, handleLogin, toggleRemember, handleForgotPassword } } } </script> <style scoped> /* 背景图容器 */ .background-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; } /* 背景图片样式 */ .background-image { width: 100%; height: 100%; object-fit: cover; filter: brightness(0.7) blur(2rpx); } /* 半透明遮罩层 */ .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient( to bottom, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.4) 50%, rgba(0, 0, 0, 0.6) 100% ); } /* 登录容器 */ .login-container { display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 32rpx; } /* 登录表单 */ .login-form { width: 100%; max-width: 600rpx; padding: 60rpx; background: rgba(255, 255, 255, 0.9); border-radius: 24rpx; box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.2); backdrop-filter: blur(10rpx); animation: fadeInScale 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); transform-origin: center; } /* 登录标题 */ .login-title { display: block; text-align: center; margin-bottom: 60rpx; font-size: 44rpx; font-weight: bold; color: #333; text-shadow: 0 1rpx 2rpx rgba(255, 255, 255, 0.8); letter-spacing: 1rpx; } /* 输入框样式 */ .login-input { width: 100%; height: 96rpx; padding: 0 30rpx; margin-bottom: 50rpx; border: 2rpx solid #ddd; border-radius: 16rpx; font-size: 34rpx; box-sizing: border-box; background: rgba(255, 255, 255, 0.95); box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); transition: all 0.3s ease; } /* 输入框聚焦效果 */ .login-input:focus { border-color: #3498db; box-shadow: 0 0 0 4rpx rgba(52, 152, 219, 0.2); background: #fff; } .input-placeholder { color: #aaa; font-size: 34rpx; } /* 修改记住密码区域样式 */ .remember-section { display: flex; justify-content: space-between; /* 左右两端对齐 */ align-items: center; /* 垂直居中 */ margin-bottom: 30rpx; font-size: 28rpx; padding: 0 10rpx; /* 添加内边距 */ } .checkbox-label { display: flex; align-items: center; color: #555; flex-shrink: 0; /* 防止缩小 */ } .forgot-password { color: #e74c3c; /* 使用更醒目的颜色 */ text-decoration: underline; padding: 10rpx 0; flex-shrink: 0; /* 防止缩小 */ margin-left: 20rpx; /* 添加左边距 */ } /* 登录按钮 */ .login-button { width: 100%; height: 96rpx; line-height: 96rpx; background: linear-gradient(135deg, #3498db, #2980b9); color: white; font-size: 36rpx; font-weight: bold; border-radius: 16rpx; margin-top: 20rpx; border: none; box-shadow: 0 4rpx 15rpx rgba(41, 128, 185, 0.3); position: relative; overflow: hidden; transition: all 0.3s ease; } /* 按钮悬停效果 */ .login-button:hover { transform: translateY(-4rpx); box-shadow: 0 8rpx 20rpx rgba(41, 128, 185, 0.4); } /* 按钮点击效果 */ .login-button:active { transform: translateY(0); box-shadow: 0 2rpx 8rpx rgba(41, 128, 185, 0.3); } /* 按钮加载状态 */ .login-button[loading] { opacity: 0.8; } /* 按钮光晕效果 */ .login-button::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.4) 0%, transparent 70%); opacity: 0; transition: opacity 0.3s ease; } .login-button:hover::after { opacity: 1; } /* 表单动画 */ @keyframes fadeInScale { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } /* 响应式调整 */ @media (max-width: 480px) { .login-form { padding: 40rpx; max-width: 90%; } .login-title { font-size: 40rpx; margin-bottom: 50rpx; } .login-input { height: 88rpx; font-size: 32rpx; } .login-button { height: 88rpx; line-height: 88rpx; } } </style> 我点击登录后浏览器控制台报错:uni-h5.es.js:2712 Uncaught (in promise) {errMsg: ‘redirectTo:fail can not redirectTo a tabbar page’} errMsg : “redirectTo:fail can not redirectTo a tabbar page” [[Prototype]] : Object  我的package.json代码如下:{ “easycom”: { “autoscan”: true, “custom”: { “^u-(.)": “uview-plus/components/u-$1/u-$1.vue”, "uni-(.)”: “@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue” } }, “pages”: [ { “path”: “pages/guide/guide”, “style”: { // “navigationBarTitleText”: “引导页” } }, { “path”: “pages/index/index”, “style”: { // “navigationBarTitleText”: “首页” } }, { “path”: “pages/login/login”, “style”: { “navigationBarTitleText”: “登录” } }, { “path”: “pages/message/message”, “style”: { “navigationBarTitleText”: “消息”, “enablePullDownRefresh”: true } }, { “path”: “pages/workbench/workbench”, “style”: { “navigationBarTitleText”: “工作台”, “enablePullDownRefresh”: true } }, { “path”: “pages/workbench/mycp/detail/detail”, “style”: { // “navigationBarTitleText”: “民意测评的详情页” } }, { “path”: “pages/workbench/mycp/operation/operation”, “style”: { // “navigationBarTitleText”: “民意测评的操作页” } }, { “path”: “pages/my/my”, “style”: { “navigationBarTitleText”: “我的” } } ], “tabBar”: { “color”: “#7A7E83”, // 未选中颜色 “selectedColor”: “#007AFF”, // 选中颜色 “borderStyle”: “white”, // 边框颜色 “backgroundColor”: “#FFFFFF”, // 背景色 “list”: [ { “pagePath”: “pages/message/message”, “iconPath”: “static/tabbar/message.png”, “selectedIconPath”: “static/tabbar/message-active.png”, “text”: “消息” }, { “pagePath”: “pages/workbench/mycp/detail/detail”, “iconPath”: “static/tabbar/workbench.png”, “selectedIconPath”: “static/tabbar/workbench-active.png”, “text”: “工作台” }, { “pagePath”: “pages/index/index”, “iconPath”: “static/tabbar/profile.png”, “selectedIconPath”: “static/tabbar/profile-active.png”, “text”: “首页” }, { “pagePath”: “pages/my/my”, “iconPath”: “static/tabbar/profile.png”, “selectedIconPath”: “static/tabbar/profile-active.png”, “text”: “我的” } ] }, “globalStyle”: { “navigationBarTextStyle”: “black”, “navigationBarTitleText”: “工具系统”, “navigationBarBackgroundColor”: “#F8F8F8”, “backgroundColor”: “#F8F8F8” }, “uniIdRouter”: {} }
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值