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

   日期:2020-08-23     浏览:88    评论:0    
核心提示:导语:暑假在家闲着无事,就琢磨着做一个web博客练练手,现在已经做完了,把过程分享出来给大家看看,分享一下学习经验。这是第三篇,主要讲node,webpack和vue-cli环境的搭建,使用vue全家桶,写好路由,构建静态页面,完善前端的一些功能。本文的目录一,编写子组件1,消息提示框子组件toast一,编写子组件1,消息提示框子组件toast...

导语:

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

本文的目录

  • 一,编写子组件
    • 1,消息提示框子组件toast
    • 2,登陆注册弹出框子组件login
    • 3,右拉信息框right
    • 4,个人信息组件information

一,编写子组件

1,消息提示框子组件toast

这个主要是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



弹出层内点击转换登陆和注册。

<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

<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

<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>


你们的赞就是对我最大的鼓励,谢谢啦~~~

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服