官网
LeanCloud: 在这里你可以注册leanCloud的账号,并且创建你的应用,即数据库
下面将以vue2案例向大家介绍如何使用leanCloud进行数据的储存, 带大家写一个最常用的登录验证的例子吧
创建一个最简单的vue2项目吧
vue create 项目名称
之前有介绍, 这里就不详细说明了
创建好后,建立两个页面,一个登录页面,还有一个登录跳转后的页面
先自己将路由写好, 能够访问这两个页面即可
下载必要的模块
npm install leancloud-storage
在登录页面引入模块并初始化
const AV = require("leancloud-storage");
// 初始化 LeanCloud
AV.init({
appId: "你的应用的appId",
appKey: "你的应用的appKey",
serverURL: "https://ysyeflyc.lc-cn-n1-shared.com",
});
用户的登录验证
// 用户登录
AV.User.logIn(username, password).then(function(user) {
// 登录成功,跳转页面
}).catch(function(error) {
// 登录失败
});
vue2的路由守卫的书写,防止用户未登录就能访问登录后的页面
beforeEnter: (to, from, next) => {
var token = localStorage.getItem('AV/YsYeflyCpiGJrcfPnYM80d43-gzGzoHsz/currentUser')
var tokenObj = JSON.parse(token)
AV.User.become(tokenObj?._sessionToken)
.then(function (user) {
// token 验证成功,user 是验证后返回的用户对象
next()
})
.catch(function (error) {
// token 验证失败
location.href = "http://xiao-zhe-is-not-lazy.gitee.io/chou/#/login"
});
}
用户属性的更改,将awordNumber改为0
var currentUser = AV.User.current();
currentUser.set("awordNumber", 0);
currentUser
.save()
.then(function (updatedUser) {
// 更新成功
console.log("更新成功");
})
.catch(function (error) {
// 更新失败
});
我的项目页面展示
我主要是写了一个抽奖的项目,一个用户登录后只能抽一次奖
登录界面:
<template>
<div class="box">
<div class="cover" v-if="isShow">登录失败</div>
<div class="container">
<!-- span标签作为背景的圆形图案 -->
<div class="bg">
<span></span>
<span></span>
<span></span>
</div>
<div class="text">
云亦音乐
<span
style="
font-size: 12px;
line-height: 50px;
margin-left: 5px;
color: gray;
"
>周年庆抽奖活动火热进行中!</span
>
</div>
<input type="text" placeholder="账号" id="username" />
<input type="password" placeholder="密码" id="password" />
<input type="text" placeholder="验证码" id="code" />
<div class="code">
<div>验证码:</div>
<div>{{ code }}</div>
</div>
<button @click="btn">→</button>
</div>
</div>
</template>
<script>
import codeFun from '@/assets/code'
const AV = require("leancloud-storage");
// 初始化 LeanCloud
AV.init({
appId: "隐藏",
appKey: "隐藏",
serverURL: "https://ysyeflyc.lc-cn-n1-shared.com",
});
export default {
data() {
return {
isShow: false,
code: "1234",
timer: null,
};
},
created(){
this.code = codeFun()
},
methods: {
btn() {
clearTimeout(this.timer);
if (code.value == this.code) {
AV.User.logIn(username.value, password.value)
.then((user) => {
// 登录成功
this.$router.push("/chou");
})
.catch(() => {
// 登录失败(可能是密码错误)
this.isShow = true;
this.timer = setTimeout(() => {
this.isShow = false;
}, 2000);
});
} else {
this.code = codeFun()
this.isShow = true;
this.timer = setTimeout(() => {
this.isShow = false;
}, 2000);
}
},
},
};
</script>
<style scoped>
.box {
background-color: rgba(0, 0, 0);
margin: 0;
padding: 0;
width: 100%;
height: 100%;
position: absolute;
z-index: -2;
}
.container {
width: 80vw;
height: 65vh;
margin: 20vh auto;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 20px;
position: relative;
box-shadow: inset 1px 1px 6px rgba(255, 255, 255, 0.3),
2px 2px 15px rgba(0, 0, 0, 0.5);
}
input {
background: transparent;
outline: none;
border: none;
border-bottom: 1px solid #666;
width: 80%;
height: 45px;
font-size: 18px;
margin-left: 30px;
margin-top: 40px;
color: white;
}
.text {
display: inline-block;
font-size: 26px;
margin-left: 34px;
margin-top: 50px;
color: #eee;
}
button {
border: none;
width: 70px;
height: 70px;
border-radius: 50%;
font-weight: bold;
font-size: 26px;
margin-top: 60px;
margin-left: calc(50% - 35px);
cursor: pointer;
background-color: rgba(255, 255, 255, 0.1);
color: white;
text-align: center;
box-shadow: 0 2px 10px #111;
}
button:hover {
color: greenyellow;
background-color: rgba(255, 255, 255, 0.2);
}
span {
position: absolute;
border-radius: 50%;
box-shadow: 1px 1px 50px #000;
z-index: -1;
}
.bg {
width: 100%;
height: 100%;
position: absolute;
z-index: -1;
animation: am2 ease-out 1s;
}
.bg span:nth-child(1) {
width: 80px;
height: 80px;
top: -30px;
left: -30px;
background-color: purple;
animation: am1 ease-in-out 3s infinite alternate;
}
.bg span:nth-child(2) {
width: 40px;
height: 40px;
top: 40px;
right: 40px;
background-color: orange;
animation: am1 ease-in-out 4s infinite alternate-reverse;
}
.bg span:nth-child(3) {
width: 120px;
height: 120px;
bottom: -60px;
right: -25px;
background-color: cyan;
animation: am1 ease-in-out 2.5s 0.5s infinite alternate;
}
/* 动画 */
@keyframes am1 {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-30px);
}
}
@keyframes am2 {
0% {
transform: scale(0, 0) rotateZ(60deg);
}
100% {
transform: scale(1, 1) rotateZ(0);
}
}
.cover {
width: 90vw;
position: absolute;
top: 10vh;
left: 5vw;
text-align: center;
opacity: 0.9;
color: #e10b0b;
border-radius: 20px;
}
/* 验证码 */
.code {
color: #c2a3a3;
display: flex;
margin-left: 10%;
margin-top: 10px;
}
.code div:nth-child(2) {
width: 70px;
height: 30px;
text-align: center;
line-height: 30px;
margin-left: 10px;
background-color: #353743;
border: 1px solid white;
font-size: 20px;
border-radius: 3px;
}
</style>
登录页面需要引用的js(验证码的生成)
let codeFun = () => {
var code1 = String(Math.floor(Math.random() * 10))
var code2 = String(Math.floor(Math.random() * 10))
var code3 = String(Math.floor(Math.random() * 10))
var code4 = String(Math.floor(Math.random() * 10))
return code1 + code2 + code3 + code4
}
export default codeFun
抽奖页面
<template>
<div @click="btn2()" class="box">
<audio src="@/assets/music.mp3" autoplay></audio>
<!-- 抽中奖品后的遮罩层 -->
<div class="cover" v-if="isShow">
{{ selectedPrize?.name }}
<span>恭喜你获得:{{ selectedPrize?.describe }}</span>
</div>
<button @click.once="btn">抽奖</button>
<div>剩余的抽奖次数: {{ currentUser?.attributes.awordNumber }}</div>
<footer>
<h3>奖品详情:</h3>
<div v-for="(data, index) in prizes" :key="index">
<span> {{ data.name }} : </span>
<span>{{ data.describe }}</span>
</div>
</footer>
</div>
</template>
<script>
const AV = require("leancloud-storage");
// 声明 class
const Todo = AV.Object.extend("Todo");
// 构建对象
const todo = new Todo();
export default {
data() {
return {
prizes: [
{ name: "一等奖", describe: "免费体验课", probability: 0 },
{ name: "二等奖", describe: "尤克里里一个", probability: 0 },
{ name: "三等奖", describe: "小玩具一个", probability: 0.05 },
{ name: "四等奖", describe: "免费来撸猫", probability: 0.15 },
{ name: "鼓励奖", describe: "抱抱", probability: 1 },
],
selectedPrize: null,
isShow: false,
currentUser: null,
};
},
created() {
this.currentUser = AV.User.current();
},
methods: {
btn(event) {
if (this.currentUser.attributes.awordNumber === 0) {
alert("抽奖次数已用完");
return;
}
this.isRote = true;
this.currentUser.attributes.awordNumber -= 1;
// 生成一个随机的概率值
var randomProbability = Math.random();
for (var i = 0; i < this.prizes.length; i++) {
var prize = this.prizes[i];
if (randomProbability < prize.probability) {
this.selectedPrize = prize;
// 为属性赋值
todo.set(this.currentUser.attributes.username, prize.describe);
break;
} else {
this.selectedPrize = { name: "空", describe: "什么都没有" };
}
}
// 更新后台
this.currentUser.set(
"awordNumber",
this.currentUser.attributes.awordNumber
);
this.currentUser
.save()
.then(function (updatedUser) {
// 更新成功
console.log("更新成功");
})
.catch(function (error) {
// 更新失败
console.log("更新失败");
});
// 用户奖品的数据储存
// 将对象保存到云端
todo.save().then(
(todo) => {
// 成功保存之后,执行其他逻辑
console.log(`奖品数据保存成功`);
},
(error) => {
// 异常处理
console.log(`奖品数据保存失败`);
}
);
this.isShow = true;
// 阻止冒泡
event.stopPropagation();
},
btn2() {
this.isShow = false;
},
},
};
</script>
<style scoped>
.box {
height: 100vh;
background: no-repeat url("@/assets/bg.png");
background-size: cover;
}
button {
border: none;
width: 70px;
height: 70px;
border-radius: 50%;
font-weight: bold;
font-size: 26px;
margin-top: 60px;
margin-left: calc(50% - 35px);
cursor: pointer;
background-color: rgba(255, 255, 255, 0.1);
text-align: center;
box-shadow: 0 2px 10px #111;
}
.item {
width: 80px;
height: 80px;
background-color: rgba(0, 0, 0, 0.8);
margin: 20px;
color: #fff;
line-height: 80px;
text-align: center;
border-radius: 10px;
font-size: 14px;
}
.cover {
width: 90vw;
height: 30vh;
position: absolute;
top: 35vh;
left: 5vw;
text-align: center;
line-height: 30vh;
background-color: black;
opacity: 0.9;
color: #eee;
border-radius: 20px;
}
footer {
width: 100%;
position: absolute;
left: 0;
bottom: 0;
font-size: 15px;
background-color: rgba(0, 0, 0, 0.4);
color: white;
font-size: 30px;
}
footer span {
margin-bottom: 5px;
}
@keyframes am1 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>