以下演示的编辑器使用HbuildX
首先安装typescript编译插件。下面演示从HbuildX安装
在HbuildX里面,依次找到 工具 -> 插件安装 -> 安装新插件 -> 前往插件市场安装
image.png
然后输入typescript,搜索,选择 typescript编译
image.png这是因为typescript编译插件不是HbuildX的核心插件,只能去插件市场。因此,其实也可以直接访问 https://ext.dcloud.net.cn/search?q=typescript&cat1=1&cat2=11,
搜索插件然后安装即可。安装好后,在已安装插件处可以看到
uniapp 对vue3+ts已经做了兼容,安装好插件后,基本就可以用vue3写了。由于uniapp 项目,通常的应用场景里面vue3都可以兼容,因此这里就不讨论vue2的写法,以下就做下vue3的示例
yl-phone-msg-code 插件地址:https://ext.dcloud.net.cn/plugin?id=8544
vue3 setup 组合式api写法,应用生命周期函数onLoad,onShow等和setUp同级
<template>
<view class="container">
<view class="app-top-box column-center">
<view class="kedang-app-img"></view>
<view class="row-center kedang-text">
欢迎光临
</view>
</view>
<yl-phone-msg-code
v-if="loginMethod===0"
mobile-prepend="+86"
:req-mobile-code="getCode"
:mobile-style="customStyle"
:mobile-prepend-style="customStyle"
:code-style="customStyle"
:msg-code-text-config="{getCodeText:'发送验证码'}"
class="userLogin"
>
<template #getCode="{msgCodeText}">
<view class="getCode">
<view class="getCodeInner">{{ msgCodeText }}</view>
</view>
</template>
</yl-phone-msg-code>
<view class="userLogin" v-if="loginMethod===1">
<view class="inputbox">
<input type="text" v-model.trim="loginform.username" placeholder-class="input-placeholder" placeholder="请输入用户名" />
<view class="row-center clearBox">
<image v-if="loginform.username" src="../../static/login/close.png" class="clear" @tap="loginform.username=''"></image>
</view>
</view>
<view class="inputbox">
<input type="password" v-model.trim="loginform.password" placeholder-class="input-placeholder" placeholder="请输入密码" />
<view class="row-center clearBox">
<image v-if="loginform.password" src="../../static/login/close.png" class="clear" @tap="loginform.password=''"></image>
</view>
</view>
</view>
<view class="read-"></view>
<view class="row-center b-btn-box" style="margin-top:40rpx;">
<button class="u-btn" hover-class="u-hover-btn" @tap="onLogin">登录</button>
</view>
<view class="row-center login-switch" @click="loginSwitch">{{ ["账号密码登录","验证码登录"][loginMethod] }}</view>
<!-- <view class="row-end findPassBox">-->
<!-- <navigator class="navigator" url="/pages/findPassword/findPassword" hover-class="navigator-hover">-->
<!-- <text class="findPassText">找回密码</text>-->
<!-- </navigator>-->
<!-- </view>-->
<view class="wxLoginBox">
<view class="otherLoginBox row-center">
<view class="line"></view>
<view class="text">其他登陆方式</view>
<view class="line"></view>
</view>
<view class="row-center">
<image class="wxImg" src="../../static/login/wx.png" @tap="wxLogin"></image>
</view>
</view>
<!-- <view class="regesterText row-center" @tap="goRegister">注册账号</view>-->
<view class="regesterText row-center" @tap="goRegister">xxx信息技术有限责任公司</view>
</view>
</template>
<script lang="ts">
import { defineComponent,ref } from 'vue'
import {useStore} from "vuex";
import {reqMobileCode} from "../../api/common"
import {preventContinuePoint,showAlert,backToFrom,jsonToqs} from "../../utils/util"
import { apiBaseUrl } from '../../utils/config.js'
export default defineComponent({
onLoad({fromPath,isTab,options}):void{
this.autocommplete()
this.fromRouteInfo={fromPath,isTab,options}
},
onShow():void{
this.autocommplete()
},
setup(props,context) {
let store=useStore();
let loginform= ref({
username: '', //正式时清除
password: '', //正式时清除
})
let isLogin= ref(false)
let loginMethod=ref(0)//登录方式 0 验证码 1 账号
let hasGetCode=ref(false)//是否获取验证码
let fromRouteInfo=ref({})//来源路由信息
let customStyle=ref({
color:"#ffffff"
})// 自定义样式
/**
* 获取验证码
* @param mobile
* @param code
* @returns {Promise<void>}
*/
const getCode = async (mobile:string,code:string):Promise<any> => {
let result = await reqMobileCode(mobile)
console.log(result)
loginform.value= {mobile,code}
hasGetCode.value=true
}
/**
* 登录
* @returns {Promise<void>}
*/
const onLogin = async ():Promise<any> => { //status == 426 用户不存在
await preventContinuePoint(this)
let {username,password,code,mobile} = loginform.value
if(loginMethod.value===1){
if (!username) {
showAlert('请输入正确的用户名')
return
}
if (!password) {
showAlert('请输入正确的密码')
return
}
}else if(loginMethod===0){
if (!mobile) {
showAlert('请输入手机号')
return
}
if (!code) {
showAlert('请输入短信验证码')
return
}
}
if(isLogin.value){
uni.showToast({
title:'正在登录,请稍后操作',
icon:'none'
})
return
}
isLogin.value = true
uni.showLoading({
title: '登录中...'
})
console.log(apiBaseUrl)
uni.request({
url: apiBaseUrl + ['auth/login_by_code','auth/login',][loginMethod],
method:'POST',
data:loginform.value,
timeout: 1000 * 5,
success:res=> {
uni.hideLoading()
console.log(res);
//登录成功
uni.setStorageSync('loginUser', {
username,
password,
checked: true
})
setLoginInfo(res)
},
fail:err=> {
uni.hideLoading()
console.log(err);
let msg=err.msg
isLogin.value = false
showAlert(msg || '网络错误!请稍后重试')
},
complete:()=> {
// uni.hideLoading()
isLogin.value=false
}
})
}
/**
* 设置登录信息
*/
const setLoginInfo = (res:any,isWx?:boolean):any => {
let {errmsg,errno,data}=res.data
console.log(errno)
if(errno!==0){
uni.showToast({
title:errmsg,
icon:'error'
})
return
}
//设置登录信息
uni.setStorage({
key: 'hasLogin',
data: 1,
})
let {token,userInfo}=res.data.data
uni.setStorage({
key: 'token',
data: token,
})
userInfo.originUserType=userInfo.userType
store.dispatch('setLoginInfo', userInfo)
uni.setStorage({
key:'userInfo',
data:userInfo
})
let queryString=jsonToqs(fromRouteInfo.value)
queryString=decodeURIComponent(queryString)
if(isWx && !userInfo.mobile){
//没有手机号时去绑定
uni.redirectTo({
url:`/pages/bindPhone/bindPhone?${queryString}`
})
}else{
backToFrom(fromRouteInfo.value)
}
}
/**
* 自动获取密码登陆
* @returns {Promise<void>}
*/
const autocommplete = async ():Promise<any> => {
let loginUser = await uni.getStorageSync('loginUser')
if (loginUser.username) {
loginform.value.username = loginUser.username
loginform.value.password = loginUser.password
}
}
/**
* 跳转注册
*/
const goRegister = ():void => {
uni.redirectTo({
url:'../register/register'
})
}
/**
* 使用微信登录
*/
const wxLogin = ():void => {
uni.showLoading({title:'加载中'})
// 获取用户信息
uni.getUserProfile({
desc:'用于完善会员资料,提升用户体验',
success: infoRes=> {
console.log(infoRes)
uni.login({
provider: 'weixin',
onlyAuthorize:true,
success: async (loginRes:any):Promise<any> => {
console.log(loginRes.code)
console.log(loginRes)
uni.request({
url:apiBaseUrl +'auth/login_by_weixin',
data:{
code: loginRes.code,
userInfo: infoRes.userInfo
},
method:'POST',
success:(res:any)=>{
console.log('调用微信登录成功')
console.log(res)
uni.hideLoading()
this.setLoginInfo(res,true)
},
fail:(err:any):void=>{
uni.hideLoading()
uni.showToast({
title:err.errMsg || '网络错误',
icon:'error'
})
},
})
},
fail:function (err:any):void{
uni.showToast({
title:'微信登录出错',
icon:'error'
})
}
})
},
fail():void{
uni.hideLoading()
}
})
}
/**
* 登录切换
*/
const loginSwitch = ():void => {
loginMethod.value = 1 - loginMethod.value
}
return {
loginform,
isLogin,
loginMethod,//登录方式 0 验证码 1 账号
hasGetCode,//是否获取验证码
fromRouteInfo,//来源路由信息
customStyle,// 自定义样式
getCode,
onLogin,
setLoginInfo,
autocommplete,
goRegister,
wxLogin,
loginSwitch
}
},
})
</script>
<style lang="scss" scoped>
.container {
background: #13141a;
height: 100vh;
box-sizing: border-box;
display: flex;
flex-direction: column;
position: relative;
padding-top:170rpx;
}
.app-top-box{
margin-bottom: 100rpx;
border:solid 1px blue;
.kedang-app-img{
width: 160rpx;
height: 160rpx;
border:solid 1px red;
margin-bottom: 20rpx;
}
.kedang-text{
color:#ffffff;
}
}
.userLogin{
height:200rpx;
}
.wxLoginBox{
//margin-top:124rpx;
//margin-bottom: 88rpx;
.otherLoginBox{
margin-bottom: 40rpx;
.line{
width: 144rpx;
height: 1rpx;
background: #EEEEEE;
}
.text{
font-size: 24rpx;
color:#aaaaaa;
margin:0 10rpx;
}
}
.wxImg{
width:96rpx;
height:96rpx;
}
}
.login-switch{
margin-top:40rpx;
color:#999999;
margin-bottom: 100rpx;
}
.regesterText{
font-size: 24rpx;
color:#666666;
}
.findPassBox{
padding:20rpx 30rpx;
}
.findPassText{
color:#3F99FF;
}
.getCode{
background: linear-gradient(90deg,#f6b847, #f1950e);
padding:2rpx;
border-radius: 30rpx;
overflow: hidden;
.getCodeInner{
width: 160rpx;
font-size: 20rpx;
text-align: center;
color: #faad14;
background: #13141a;
padding:10rpx 20rpx;
border-radius: 30rpx;
overflow: hidden;
}
}
</style>
网友评论