[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善

导语:

暑假在家闲着无事,就琢磨着做一个web博客练练手,现在已经做完了,把过程分享出来给大家看看,分享一下学习经验。这是第三篇,主要讲node,webpack和vue-cli环境的搭建,使用vue全家桶,写好路由,构建静态页面,完善前端的一些功能。

微信搜索 【web小馆】,回复 “全栈博客项目”,即可获取 项目源码和后续的实战文章教程。

本文的目录一,编写子组件1,消息提示框子组件toast2,登陆注册弹出框子组件login3,右拉信息框right4,个人信息组件information

一,编写子组件
1,消息提示框子组件toast

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善

这个主要是z-index还有居中等要素。

<template>
<div class="toast" v-show="toastShow">
{{toastStr}}
</div>
</template>

<script>
export default {
props: {
toastShow: {
type: Boolean,
default: false
},
toastStr: {
type: String,
default: ''
}
},
data() {
return {
}
}
}
</script>

<style>
.toast {
position: fixed;
z-index: 2100;
left: 50%;
top: 45%;
transition: all .5s;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
text-align: center;
border-radius: 5px;
color: #FFF;
background: rgba(17, 17, 17, 0.7);
height: 45px;
line-height: 45px;
padding: 0 15px;
max-width: 150px;
}
</style>


2,登陆注册弹出框子组件login

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善
[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善
弹出层内点击转换登陆和注册。

<template>
<div class="login">
<div class="modal-body">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li v-for="(item,index) in tabsParam" @click="toggleTabs(index)" :class="{active:index == nowIndex}" :key="index">{{item}}</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane fade in" id="login" v-show="nowIndex === 0">
<div class="signup-form-container text-center">
<form class="mb-0" @submit.prevent="_login($event)">
<div class="form-group">
<input type="text" class="form-control" name="username" placeholder="*用户名或邮箱">
</div>
<div class="form-group">
<input type="password" class="form-control" name="password" placeholder="*密码">
</div>
<button type="submit" class="go-login btn btn--primary btn--block"><i class="fa fa-bullseye"></i> 安全登录</button>
<!-- <a href="#" class="forget-password">忘记密码?</a> -->
</form>
<!-- form end -->
</div>
<!-- .signup-form end -->
</div>
<div class="tab-pane fade in " id="signup" v-show="nowIndex === 1">
<form class="mb-0" @submit.prevent="_signup($event)">
<div class="form-group">
<input type="text" class="form-control" name="username" placeholder="输入账号">
</div>
<div class="form-group">
<input type="text" class="form-control" name="realname" placeholder="输入用户名">
</div>
<!-- .form-group end -->
<div class="form-group">
<input type="email" class="form-control" name="email" placeholder="绑定邮箱">
</div>
<!-- .form-group end -->
<div class="form-group">
<input type="password" class="form-control" name="password" placeholder="密码最小长度为6">
</div>
<div class="form-group">
<input type="password" class="form-control" name="password1" placeholder="再次输入密码">
</div>
<button type="submit" class="go-register btn btn--primary btn--block"><i class="fa fa-bullseye"></i> 立即注册</button>
</form>
<!-- form end -->
</div>
</div>
</div>
</div>

</template>

<script>
import { login, signup } from "@/api/user"
import { ContactList } from 'vant';
export default {
data(){
return {
tabsParam : ['登陆', '注册'],
nowIndex:0,//默认第一个tab为激活状态
}
},
methods: {
toggleTabs:function(index){
this.nowIndex=index;
},
_login() {
var formData = new FormData(event.target);
login(formData).then(res => {
if (res.data.errno == 0) {
console.log(res)
let userinfo = res.data.data
this.$store.commit('updateUserStatus',userinfo);
}
this.$emit('closelogin',res.data.errno)
})
},
_signup(event) {
let message = event.target
if (message.password.value != message.password1.value) {
// console.log('buyiy')
this.$emit('passwordNoSame')
return
}
var formData = new FormData(message)
formData.email = message.email.value
formData.username = message.username.value
formData.password = message.password.value
formData.realname = message.realname.value
// console.log(formData)
signup(formData).then(res => {
if (res.data.errno == 0) {
console.log(res)
}
this.$emit('closesign', res.data.errno)
})
}

},
mounted() {
console.log(this.$store.getters.getCurrentUser)
console.log(this.$store.getters.getIsLogin)
},
}
</script>

<style scoped>
.login{
border: none;
box-shadow: none;
position: relative;
background-color: transparent;
}
.model-body{
position: relative;
padding: 15px;
}
.nav-tabs{
border-bottom: none;
text-align: center;
padding-left: 0;
padding: 10px;
list-style: none;
margin: 0;
}
.nav-tabs li{
float: none;
display: inline-block;
margin: 0 5px;
}
.tab-content{
padding: 20px;
background-color: #ffffff;
border-radius: 4px;
}
.form-group{
margin-bottom: 15px;
position: relative;
}
.form-control{
border-radius: 0;
font-family: Lato,sans-serif;
line-height: 30px;
margin-bottom: 10px;
padding: 0 12px;
transition: border-color cubic-bezier(0.77,0,0.175,1);
border: 1px solid #dad9d9;
font-size: 14px;
border-radius: 10px;
}
.active{
color: #69d78a;
}
.tabnav{
color: red;
}
.mb-0{
text-align: center;
}
.btn{
background-color: #69d78a;
border: 1px solid #69d78a;
color: white;
padding: 5px 10px;
border-radius: 10px;
font-size: 14px;
}
</style>


3,右拉信息框right

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善

<template>
<div class="right">
<div class="img-div">
<img src="../../assets/logo.jpg" class="logo">
<p class="rightp">轻松学算法</p>
<p class="rightp">小程序:轻松学算法</p>
</div>
<div class="button_div">
<van-button type="primary" size="mini" to="/home">首页</van-button>
</div>
</div>
</template>

<script>
import Vue from 'vue';
import { Button } from 'vant';

Vue.use(Button);
export default {

}
</script>

<style scoped>
.img-div{
margin-top: 30px;
text-align: center;
}
.logo{
height: 160px;
width: 160px;
}
.rightp{
font-size: 14px;
margin-top: 0;
}
.button_div{
padding-left: 10px
}
</style>


4,个人信息组件information

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善

<template>
<div class="information">
<toast :toastShow = "isLoading" :toastStr = "str"></toast>
<van-popup v-model="show" style="border-radius: 10px;">
<div class="inputdiv">
<input class="input" v-model="newName">
<button class="but" @click= "chance">修改昵称</button>
</div>
</van-popup>
<topnav @back= "back" :text= "text"></topnav>
<div class="userimgdiv">
<div class="text">头像</div>
<div class="imgdiv">
<img :src="avatar" class="img">
<van-icon name="arrow" class="myicon" size="20"/>
</div>
<input id="fileImage" type="file" @change="avatarChange($event)">
</div>
<div class="item" @click="showPopup">
<div class="textitem">昵称</div>
<div class="textdiv">
<div class="textitem" v-html="realname"></div>
<van-icon name="arrow" class="myiconitem" size="20"/>
</div>
</div>
<div class="item">
<div class="textitem">账号</div>
<div class="textdiv">
<div class="textitem" v-html="username"></div>
</div>
</div>
</div>
</template>

<script>

import toast from '@/base/toast/toast'
import topnav from '@/components/top-nav/top-nav'
import Vue from 'vue';
import { Icon } from 'vant';
import { upavatar, upname } from '@/api/user'

Vue.use(Icon);
export default {
data() {
return {
text: '个人信息',
show: false, //弹出层的显示
isLoading: false, //消息提示框的显示
str: '', //消息提示框的内容
newName: ''
}
},
methods: {
back() {
this.$router.back()
},
showPopup() {
this.show = true;
},
chance() { // 修改接口
this.show = false;
// console.log(this.newName)
let param = new FormData()
param.append('name', this.newName)
upname(param).then(res => {
if (res.data.errno == 0) {
let userinfo = this.$store.getters.getCurrentUser
userinfo.realname = this.newName
this.toastshow('修改成功')
}
})
},
toastshow(str) {
this.showloginstate = false;
this.isLoading = true //提示框的显示
this.str = str
setTimeout(() => {
this.isLoading = false //提示框的消失
this.str = ''
}, 1500);
},
avatarChange(el) {
if (!this.$store.getters.getIsLogin) {
return
}
let file = el.target.files[0]
console.log(file)
let param = new FormData() // 创建form对象
param.append('file', file) // 通过append向form对象添加数据
param.append('chunk', '0') // 添加form表单中其他数据
console.log(param.get('file')) // FormData私有类对象,访问不到,可以通过get判断值是否传进去

upavatar(param).then(res => {
if (res.data.errno == 0) {
let userinfo = this.$store.getters.getCurrentUser
userinfo.avatar = res.data.data.avatar_url
this.$store.commit('updateUserStatus',userinfo);
this.toastshow('修改成功')
} else {
this.toastshow('修改失败')
}

})
}
},
computed: {
avatar() {
if (this.$store.getters.getIsLogin){
return this.$store.getters.getCurrentUser.avatar
} else {
return 'http://localhost:8000/api/file/avatar?pic=logo.png'
}
},
realname() {
if (this.$store.getters.getIsLogin){
return this.$store.getters.getCurrentUser.realname
} else {
return '轻松学算法'
}
},
username() {
if (this.$store.getters.getIsLogin){
return this.$store.getters.getCurrentUser.username
} else {
return 'xiaomizhou'
}
},
},
components: {
topnav,
toast
}
}
</script>

<style scoped>
.information{
position: fixed;
top: 50px;
bottom: 0;
right: 0;
left: 0;
z-index: 1000;
background-color: white;
}
.userimgdiv{
height: 60px;
display: flex;
padding: 5px 0;
border-bottom: 1.5px solid #eeeeee;
margin: 0px 10px;
}
.text{
font-size: 14px;
margin:15px 5px 5px 5px;
}
.imgdiv{
margin-left: auto;
height: 60px;
width: 68px;
padding: 8px 5px 8px 8px;
display: flex;
}
.img{
height: 44px;
width: 44px;
border-radius: 10px;
}
.myicon{
margin-top: 10px;
margin-left: 5px;
}
.item{
height: 40px;
display: flex;
padding: 5px 0;
border-bottom: 1.5px solid #eeeeee;
margin: 0px 10px;
}
.textitem{
font-size: 14px;
margin:8px 5px 5px 5px;
}
.textdiv{
margin-left: auto;
padding: 4px;
display: flex;
}
.myiconitem{
margin-top: 7px;
margin-left: 5px;
}
.inputdiv{
height: 160px;
width: 280px;
border-radius: 10px;
}
.input{
margin: 40px 0 20px 0;
display:block;
margin-left:auto;
margin-right:auto;
border: 1px solid #a5a4a4;
border-radius: 8px;
height: 26px;
padding: 2px 8px 2px 8px;
font-size: 14px;
}
.but{
margin: 30px 0 20px 0;
display:block;
margin-left:auto;
margin-right:auto;
border: 1px solid #a5a4a4;
border-radius: 8px;
height: 30px;
padding: 3px 8px 3px 8px;
font-size: 14px;
}
#fileImage
{
height: 70px;
width: 100%;
overflow: hidden;
cursor: pointer;
opacity: 0;
position: absolute;
}
</style>

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善
你们的赞就是对我最大的鼓励,谢谢啦~~~

补充:

微信搜索【web小馆】,回复全栈博客项目,即可获取项目源码和后续的实战文章教程。每天用最简单朴实的语言,潜移默化的提升你的计算机基础知识和前端技术。小米粥,一个专注的web全栈工程师,我们下期再见!

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善
[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

[记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » [记录三] Vue(全家桶)+node+koa2+mysql+nginx+redis,全栈博客项目前端部分完善
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏