群山艳阳
群山艳阳
  • 发布:2026-02-06 11:42
  • 更新:2026-02-06 11:42
  • 阅读:92

鸿蒙对uview组件的支持

分类:鸿蒙Next

鸿蒙对uview组件不支持吗

<template> <view class="min-h-full box-border"> <!-- :style="{ paddingTop: statusBarHeight + 44 + 'px', }" --> <!-- <view class="bg-white fixed w-[100%] top-[0]" :style="{ height: statusBarHeight + 44 + 'px', }"></view> --> <image class="myBacImg" src="@/static/images/self/loginBac.png" alt="" srcset="" /> <view class="" style="position: relative; z-index: 2;"> <view class="flex justify-between"> <view class="font-[500] text-[48rpx] text-[#333] pt-[60rpx] pl-[32rpx]"> <view class="">欢迎登陆</view> <view class="">供销员工端</view> </view> <view class="pt-[14rpx]"> <image class="w-[380rpx] h-[380rpx]" src="@/static/images/self/loginTop.png" alt="" srcset="" /> </view> </view> <view class="bg-white rounded-t-[16rpx] pt-[64rpx] relative" style="height: calc(100vh - 338rpx); margin-top: -64rpx;"> <view class="h-[88rpx] flex justify-center items-center"> <view @click="tabChange(index)" class="text-[#4D4D4D] text-[30rpx] relative" v-for="(item, index) in listLoginTabs" :key="index"

style="{ fontWeight: tabActive==index ? '500' : '400'}"> {{ item.name }}
<!-- marginRight: index == 0 ? '64rpx' : '0', -->
<view v-show="tabActive==index"
class="absolute bottom-[-20rpx] left-[50%] h-[6rpx] w-[60rpx] bg-[#0065f4]"
style="transform: translateX(-50%);"></view>
</view>
</view>

        <view class="px-[32rpx] mt-[48rpx]">  
            <view class="w-[686rpx]">  
                <u-form :model="loginForm" ref="loginFormRef">  

                    <u-form-item label="" prop="tenantName">  
                        <view class="bg-[#F5F7FB] h-[88rpx] rounded-[16rpx] flex  items-center w-[100%]">  
                            <image class="h-[32rpx] w-[32rpx] ml-[32rpx] mr-[24rpx]"  
                                src="@/static/images/self/loginPhone.png" alt="" srcset="" />  
                            <u-input @blur="phoneInput" style=" width: 100px; height: 50px;"  
                                placeholder-style="color:#999999; font-size: 28rpx; font-weight: 400;"  
                                class="h-[88rpx] flex-1" v-model="loginForm.tenantName" placeholder="请输入租户名称" />  
                        </view>  
                    </u-form-item>  

                    <u-form-item label="" prop="username">  
                        <view class="bg-[#F5F7FB] h-[88rpx] rounded-[16rpx] flex  items-center w-[100%]">  
                            <image class="h-[32rpx] w-[32rpx] ml-[32rpx] mr-[24rpx]"  
                                src="@/static/images/self/loginPhone.png" alt="" srcset="" />  
                            <u-input placeholder-style="color:#999999; font-size: 28rpx; font-weight: 400;"  
                                class="h-[88rpx] flex-1" v-model="loginForm.username" placeholder="请输入账号" />  
                        </view>  
                    </u-form-item>  

                    <u-form-item label="" prop="password">  
                        <view class="bg-[#F5F7FB] h-[88rpx] rounded-[16rpx] flex  items-center w-[100%]">  
                            <image class="h-[32rpx] w-[32rpx] ml-[32rpx] mr-[24rpx]"  
                                src="@/static/images/self/loginPwd.png" alt="" srcset="" />  
                            <u-input placeholder-style="color:#999999; font-size: 28rpx; font-weight: 400; "  

password="showPassword" type="password" style="padding-right: 10rpx;" class="pwdContainer h-[88rpx] flex-1" v-model="loginForm.password"
placeholder="请输入密码" />
<!-- <u-icon class="ml-[24rpx] mr-[32rpx]" :name="showPassword ? 'eye-off' : 'eye-fill'"
color="#999" size="48" @click="changePassword"></u-icon> -->
</view>
</u-form-item>

                    <!-- <u-form-item label="" prop="mobile" v-if="tabActive == 1">  
                        <view class="bg-[#F5F7FB] h-[88rpx] rounded-[16rpx] flex  items-center w-[100%]">  
                            <image class="h-[32rpx] w-[32rpx] ml-[32rpx] mr-[24rpx]"  
                                src="@/static/images/self/loginPhone.png" alt="" srcset="" />  
                            <u-input placeholder-style="color:#999999; font-size: 28rpx; font-weight: 400;"  
                                class="h-[88rpx] flex-1" v-model="loginForm.mobile" placeholder="请输入手机号" />  
                        </view>  
                    </u-form-item>  

                    <u-form-item label="" prop="code" v-if="tabActive == 1">  
                        <view class="bg-[#F5F7FB] h-[88rpx] rounded-[16rpx] flex  items-center w-[100%]">  
                            <image class="h-[32rpx] w-[32rpx] ml-[32rpx] mr-[24rpx]"  
                                src="@/static/images/self/loginPwd.png" alt="" srcset="" />  
                            <u-input placeholder-style="color:#999999; font-size: 28rpx; font-weight: 400;"  
                                class="h-[88rpx] flex-1" v-model="loginForm.code" placeholder="请输入验证码" />  
                            <text v-if="!isCodeSend"  
                                class="ml-[24rpx] mr-[32rpx] text-[#0065f4] text-[28rpx] font-[400]"  
                                @click="sendCode">获取验证码</text>  
                            <text v-else  
                                class="ml-[24rpx] mr-[32rpx] text-[#999] text-[28rpx] font-[400]">{{ codeCountdown }}后重新获取</text>  
                        </view>  
                    </u-form-item> -->  

                </u-form>  
            </view>  
            <view class="flex justify-end mt-[16rpx]">  
                <!-- <text class="text-[#333] text-[28rpx] font-[400]" @click="forgetPwd">忘记密码?</text> -->  
            </view>  
            <button class="w-[686rpx] h-[88rpx] bg-[#0065f4] mt-[48rpx] text-[#fff] text-[32rpx] font-[500]"  
                @click="handleLogin">登录</button>  
        </view>  

        <view class="absolute bottom-[86rpx] left-[50%] w-[686rpx] flex justify-center"  
            style="transform: translateX(-50%);">  
            <u-checkbox v-model="isCheckAgreement" shape="circle" active-color="#0065f4">  
                <view class="flex text-[#999] text-[28rpx] font-[400]">  
                    请您阅读并同意  
                    <view @click.stop>  
                        <navigator class="text-[#0065f4]" hover-class="none"  
                            url="/pages/agreement/agreement?type=user_agreement">  
                            《用户协议》  
                        </navigator>  
                    </view>  

                    和  
                    <view @click.stop>  
                        <navigator class="text-[#0065f4]" hover-class="none"  
                            url="/pages/agreement/agreement?type=privacy_policy">  
                            《隐私协议》  
                        </navigator>  
                    </view>  
                </view>  
            </u-checkbox>  
        </view>  
    </view>  

</view>  

</view>
</template>

<script setup lang="ts">
import { useLockFn } from '@/hooks/useLockFn'
import { useAppStore } from '@/stores/app'
import { useUserStore } from '@/stores/user'
import { isWeixinClient } from '@/utils/client'
import { onLoad, onShow, onReady } from '@dcloudio/uni-app'
import { onMounted, computed, reactive, ref, shallowRef, } from 'vue'
import cache from '@/utils/cache'
// 接口引入
import { getBytenantName, getUserInfoAPI } from '@/api/newlogin.ts'
import { mobileLogin, accountLogin, mnpLogin, OALogin } from '@/api/account'

// 安全获取 store 的函数,延迟调用确保 pinia 就绪  
const getUserStore = () => useUserStore()  

let listLoginTabs = ref([{  
    name: '账号登录'  
},  
    // {  
    //  name: '验证码登录'  
    // },  
])  
const isCheckAgreement = ref(false)  
let tabActive = ref(0)  
let loginFormRef = ref()  
let isCodeSend = ref(false)  
let codeCountdown = ref(60)  
let loginForm = reactive({  
    tenantName: "",  
    scene: 'account',  
    username: '',  
    password: '',  
    code: '',  
    mobile: ''  
})  

let showPassword = ref(true)  
const changePassword = () => {  
    showPassword.value = !showPassword.value;  
}  

let loginRules = reactive({  
    tenantName: [  
        {  
            required: true,  
            message: '请输入租户名称',  
            // 可以单个或者同时写两个触发验证方式   
            trigger: ['change', 'blur'],  
        },  
    ],  
    username: [  
        {  
            required: true,  
            message: '请输入账户',  
            // 可以单个或者同时写两个触发验证方式   
            trigger: ['change', 'blur'],  
        },  
    ],  
    mobile: [  
        {  
            required: true,  
            message: '请输入手机号',  
            trigger: ['change', 'blur'],  
        },  
        {  
            pattern: /^1[3-9]\d{9}$/,  
            transform(value : any) {  
                return String(value);  
            },  
            message: '手机号不合法'  
        },  
    ],  
    password: [  
        {  
            required: true,  
            message: '请输入密码',  
            trigger: ['change', 'blur']  
        }  
    ],  
    code: [  
        {  
            required: true,  
            message: '请输入验证码',  
            trigger: ['change', 'blur']  
        }  
    ],  
})  

const submit = () => {  
    if (!isCheckAgreement.value) {  
        uni.$u.toast('请您阅读并同意《用户协议》和《隐私协议》')  
        return  
    }  
    loginFormRef.value.validate(async (valid : any) => {  
        if (valid) {  
            console.log('验证通过');  
            const userStore = getUserStore()  
            userStore.login('111111111111111')  
            await userStore.getUser()  
            uni.reLaunch({  
                url: '/pages/index/index'  
            })  
        }  
    });  
}  

// tab栏 ( 登录方式 ) 切换  
const tabChange = (index : any) => {  
    console.log("index", index);  
    tabActive.value = index  
}  

// 忘记密码  
const forgetPwd = () => {  
    uni.navigateTo({  
        url: '/pages/newUser/forgetPwd?type=forget'  
    })  
}  

// 获取验证码  
const sendCode = () => {  
    isCodeSend.value = true  
    codeCountdown.value = 60  
    let timer = setInterval(function () {  
        codeCountdown.value--  
        if (codeCountdown.value <= 0) {  
            clearInterval(timer)  
        }  
    }, 1000)  
}  

const checkAgreement = async () => {  
    if (!isCheckAgreement.value)  
        return Promise.reject('请勾选底部已阅读并同意《服务协议》和《隐私协议》')  
}  

const loginFun = async () => {  
    try {  
        await checkAgreement()  

        uni.showLoading({  
            title: '请稍后...'  
        })  
        let data  
        data = await accountLogin(loginForm)  
        if (data) {  
            loginHandle(data)  
        }  
    } catch (error : any) {  
        uni.hideLoading()  
        uni.$u.toast(error)  
    }  
}  

const loginHandle = async (data : any) => {  
    const { access_token } = data  
    const userStore = getUserStore()  
    userStore.login(access_token) // 存储 token  
    // await userStore.getUser()  
    uni.$u.toast('登录成功')  
    uni.hideLoading()  
    uni.reLaunch({  
        url: '/pages/index/index'  
    })  
}  

const getUserInfoFN = () => {  
    getUserInfoAPI().then(res => {  
        console.log('获取用户信息', res);  
    }).catch(err => {  
        console.log('获取用户信息失败', err);  
    })  
}  

// const getUserInfoFN = ()=>{  
//  getUserInfoAPI().then(res=>{  
//      console.log('获取用户信息', res);  
//  }).catch(err=>{  
//      console.log('获取用户信息失败', err);  
//  })  
// }  

const { lockFn: handleLogin } = useLockFn(loginFun)  

// 获取租户id  
let timer = ref(null)  
const phoneInput = (e) => {  
    if (timer.value) {  
        clearTimeout(timer.value)  
    }  
    timer.value = setTimeout(() => {  
        console.log(1231231231, e);  
        getBytenantNameFn(e)  
    }, 500)  
}  
const getBytenantNameFn = (text) => {  
    getBytenantName(text).then(res => {  
        if (res.code == 0 && res.data && res.data.id) {  
            cache.set('Tenant-Id', res.data.id)  
        } else {  
            uni.showToast({  
                title: '未查到该租户',  
                icon: 'none',  
            })  
        }  
    }).catch(err => {  
        uni.showToast({  
            title: '查询租户失败,网络错误',  
            icon: 'none',  
        })  
    })  
}  

onReady(() => {  
    loginFormRef.value.setRules(loginRules);  
})  

onShow(async () => {  

})  

onLoad(async (options) => {  

})  

const statusBarHeight = ref(0)  
const navBarHeight = ref(0)  
const totalNavHeight = ref(0)  
const getStatusBarHeight = () => {  
    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-KUAISHOU  
    try {  
        // 获取系统信息  
        const systemInfo = uni.getSystemInfoSync()  

        // 状态栏高度  
        statusBarHeight.value = systemInfo.statusBarHeight || 0  

        // 导航栏高度(状态栏 + 标题栏)  
        // 微信小程序标题栏高度通常是 44px  
        const titleBarHeight = 44  
        navBarHeight.value = statusBarHeight.value + titleBarHeight  

        // 总导航高度(包含状态栏)  
        totalNavHeight.value = navBarHeight.value  

        console.log('状态栏高度:', statusBarHeight.value)  
        console.log('导航栏高度:', navBarHeight.value)  

    } catch (error) {  
        console.error('获取状态栏高度失败:', error)  
        // 设置默认值  
        statusBarHeight.value = 20  
        navBarHeight.value = 64  
        totalNavHeight.value = 64  
    }  
    // #endif  

    // #ifdef H5  
    // H5 环境通常没有状态栏,设置为 0  
    statusBarHeight.value = 0  
    navBarHeight.value = 0  
    totalNavHeight.value = 0  
    // #endif  

    // #ifdef APP-PLUS  
    // APP 环境  
    try {  
        const systemInfo = uni.getSystemInfoSync()  
        statusBarHeight.value = systemInfo.statusBarHeight || 0  
        navBarHeight.value = systemInfo.statusBarHeight || 0  
        totalNavHeight.value = systemInfo.statusBarHeight || 0  
    } catch (error) {  
        console.error('获取状态栏高度失败:', error)  
        statusBarHeight.value = 20  
        navBarHeight.value = 20  
        totalNavHeight.value = 20  
    }  
    // #endif  
}  
onMounted(() => {  
    getStatusBarHeight()  
})  

</script>

<style lang="scss">
page {
height: 100%;
background-color: #fff;
}

.myBacImg {  
    width: 100%;  
    height: 100%;  
    position: fixed;  
    background-size: 100% 100%;  
    z-index: 1;  
}  

.u-form-item__message {  
    padding-left: 4rpx !important;  
}  

.u-border-bottom:after {  
    border-bottom-width: 0;  
}  

.u-input {  
    height: 100%;  

    input {  
        height: 100%;  
    }  
}  

.pwdContainer {  
    .uicon-eye {  
        font-size: 48rpx !important;  
    }  

    .uicon-eye-fill {  
        font-size: 48rpx !important;  
    }  
}  

</style>

2026-02-06 11:42 负责人:无 分享
已邀请:

要回复问题请先登录注册