Website front desk - login and user center

Chapter 6 website front desk - login and user center

Learning objectives:

  • Complete the user registration function
  • Complete the user login function and master the use of JS cookies
  • Complete the function of wechat code scanning and login
  • Complete the nesting layout of user center and master the use of nuxt nesting route

1 user registration

1.1 page building

Create pages/login.vue

<template>
 <div class="wrapper loginsign"> 
   <div class="item signup"> 
    <div class="form"> 
     <h3 class="loginsign-title">Register a new account</h3> 
     <form class="sui-form"> 
      <div class="control-group"> 
       <label for="inputname" class="control-label">Name</label> 
       <div class="controls"> 
        <input type="text" id="inputname" placeholder="Real name or common nickname" class="input-xlarge" data-rules="required" /> 
       </div> 
      </div> 
      <div class="different"> 
       <div class="radio-content"> 
        <div id="a1" class="phone"> 
         <div class="control-group number"> 
          <input type="text" placeholder="Only mainland mobile phone numbers are supported" class="input-xlarge" data-rules="required|mobile" /> 
         </div> 
         <div class="control-group code"> 
          <div class="input-append"> 
           <input id="appendedInputButton" type="text" placeholder="SMS verification" class="span2 input-large msg-input" /> 
           <button type="button" class="sui-btn msg-btn">Get verification code</button> 
          </div> 
         </div> 
         <div class="control-group"> 
          <label for="inputpassword" class="control-label">Password</label> 
          <div class="controls"> 
           <input type="text" id="inputpassword" placeholder="Please input 6-16 Bit password" class="input-xlarge" /> 
          </div> 
         </div> 
        </div> 
        <div id="a2" class="email"> 
         <div class="control-group inputemail"> 
          <input type="text" placeholder="Enter phone number" class="input-xlarge" /> 
         </div> 
         <div class="control-group"> 
          <label for="inputpassword" class="control-label">Password:</label> 
          <div class="controls"> 
           <input type="text" id="inputpassword" placeholder="Please input 6-16 Bit character" class="input-xlarge" /> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
      <div class="control-group btn-signup"> 
       <label class="control-label"></label> 
       <div class="controls"> 
        <label> <input type="checkbox" /><span class="type-text" style="font-size:12px;">Agree to the agreement and accept the terms of service</span> </label> 
        <button type="submit" class="sui-btn btn-danger btn-yes">Registration</button> 
       </div> 
      </div> 
     </form> 
    </div> 
   </div> 
   <div class="item"> 
    <div class="form"> 
     <h3 class="loginsign-title">User login</h3> 
     <form class="sui-form login-form"> 
      <div class="control-group"> 
       <label for="inputname" class="control-label">Mobile phone number or Email: </label> 
       <div class="controls"> 
        <input type="text" id="inputname" placeholder="11 Digit mobile number or Email" class="input-xlarge" data-rules="required" /> 
       </div> 
      </div> 
      <div class="control-group"> 
       <label for="inputpassword" class="control-label">Password:</label> 
       <div class="controls"> 
        <input type="text" id="inputpassword" placeholder="Enter login password" class="input-xlarge" /> 
       </div> 
      </div> 
      <div class="controls"> 
       <label> <input type="checkbox" name="remember-me" /><span class="type-text" style="font-size:12px;">Remember login status</span> </label> 
       <button type="submit" class="sui-btn btn-danger btn-yes">Sign in</button> 
      </div> 
      <div class="other-methods"> 
      </div> 
     </form> 
    </div> 
   </div> 
  </div>   
</template>
<script>
import '~/assets/css/page-sj-person-loginsign.css'
export default {
  
}
</script>

See person-loginsign.html for details

1.2 obtaining the verification code

1.2.1 simulation data and API

(1) Import user.yml into easymock

(2) Modify easy mock data

url: /user/user/sendsms/{mobile}

method: put

{
  "code": 20000,
  "flag": true,
  "message": "Verification code sent successfully"
}

(3) Write API to create api/user.js

import request from '@/utils/request'
const api_group = 'user'
const api_name = 'user'
export default {  
  sendsms(mobile) {
    return request({
      url: `/${api_group}/${api_name}/sendsms/${mobile}`,
      method: 'put'
    })
  }
}

1.2.2 calling API

(1) Modify the script section of pages/login.vue

<script>
import '~/assets/css/page-sj-person-loginsign.css'
import userApi from '@/api/user'
export default {
    data(){
      return {
        pojo: {}
      }
    },
    methods: {
      sendsms(){
        userApi.sendsms( this.pojo.mobile ).then(res => {
          alert(res.data.message)          
        })
      }
    }
}
</script>

(2) Modify pages/login.vue binding variable

<input type="text" v-model="pojo.mobile" placeholder="Only mainland mobile phone numbers are supported" class="input-xlarge" /> 

(3) Modify the binding method of pages/login.vue button

<button type="button" class="sui-btn msg-btn" @click="sendsms" >Get verification code</button> 

1.2.3 pop up using element UI

(1) Install element UI

cnpm install element-ui --save

(2) Create element-ui.js under plugins folder

import Vue from 'vue'  
import ElementUI from 'element-ui'  
Vue.use(ElementUI) 

(3) Modify nuxt.config.js, add plug-ins and styles

  .......
  plugins: [
    .....
    { src: '~plugins/element-ui.js', ssr: false }
  ],
  css: [
    'element-ui/lib/theme-chalk/index.css'
  ],
  .........

(4) Modify the script section of pages/login.vue and replace the alert with the following code

          this.$message({
            message: res.data.message,
            type: (res.data.flag?'success':'error')
          })

1.3 submit registration

(1) Add data in easy mock

URL: /user/user/register/{code}

Method: post

{
  "flag": true,
  "code": 20000,
  'message': "Successful implementation"
}

(2) Modify api/user.js and add methods

  register(user,code) {
    return request({
      url: `/${api_group}/${api_name}/register/${code}`,
      method: 'post',
      data:user
    })
  },

(3) Modify pages/login/index.vue script to add attributes

  data(){
    return {
        pojo: {},
        code:''
    }
  },

New registration method

     register () {
         userApi.register(this.pojo).then( res =>{
                if(res.data.flag){
                    this.$message({
                        message: 'login was successful',
                        type: 'success'
                    })
                    this.pojo={}
                }else{
                    this.$message({
                        message: 'Registration error',
                        type: 'error'
                    })
                }
          })
      }

(4) Modify page / login / index.vue

Bind form input box

     <form class="sui-form"> 
      <div class="control-group"> 
       <label for="inputname" class="control-label">Login name</label> 
       <div class="controls"> 
        <input type="text" id="inputname" v-model="pojo.loginname" placeholder="Login name" class="input-xlarge" /> 
       </div> 
      </div> 
      <div class="control-group"> 
       <label for="inputname" class="control-label">Nickname?</label> 
       <div class="controls"> 
        <input type="text" id="inputname" v-model="pojo.nickname" placeholder="Real name or common nickname" class="input-xlarge" /> 
       </div> 
      </div> 
      <div class="different"> 
       <div class="radio-content"> 
        <div id="a1" class="phone"> 
         <div class="control-group number"> 
          <input type="text" v-model="pojo.mobile" placeholder="Only mainland mobile phone numbers are supported" class="input-xlarge" data-rules="required|mobile" /> 
         </div> 
         <div class="control-group code"> 
          <div class="input-append"> 
           <input id="appendedInputButton" v-model="code" type="text" placeholder="SMS verification" class="span2 input-large msg-input" /> 
           <button type="button" class="sui-btn msg-btn" @click="sendsms" >Get verification code</button> 
          </div> 
         </div> 
         <div class="control-group"> 
          <label for="inputpassword" class="control-label">Password</label> 
          <div class="controls"> 
           <input type="text" id="inputpassword" v-model="pojo.password" placeholder="Please input 6-16 Bit password" class="input-xlarge" /> 
          </div> 
         </div> 
        </div>         
       </div> 
      </div> 
      <div class="control-group btn-signup"> 
       <label class="control-label"></label> 
       <div class="controls"> 
        <label> <input type="checkbox" /><span class="type-text" style="font-size:12px;">Agree to the agreement and accept the terms of service</span> </label> 
        <button type="button" class="sui-btn btn-danger btn-yes" @click="register">Registration</button> 
       </div> 
      </div> 
     </form>

Binding method

<button type="button" class="sui-btn btn-danger btn-yes" @click="register">Registration</button> 

1.4 input verification

The following functions are implemented by students:

(1) Verification nickname must be filled in

(2) To verify the validity of mobile phone number, regular expression can be used.

^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$

(3) Password length verification

(4) Determine whether the consent clause is checked

2 user login

2.1 login verification

(1) mock simulation data

url: /user/user/login

method: post

{
  "code": 20000,
  "flag": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5ODcyNTUxMDQ1NDM1MjY5MTIiLCJpYXQiOjE1MjQyMTQ5NDgsInJvbGVzIjoidXNlciIsImV4cCI6MTUyNDIxNTMwOH0.icFRMKfaHlPn224hU3Gm_LOHflaONj9IfWIVj8gSbbM",
    "name": "Xiao Bai",
    "avatar": 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif'
  }
}

(2) API writing. Modify api/user.js and add a new method

  login(mobile, password) {
    return request({
      url: `/${api_group}/${api_name}/login`,
      method: 'post',
      data: {
        mobile,
        password
      }
    })
  }

(3) Modify pages/login/index.vue and add attributes: user name and password

  data(){
    return {
        ....
        mobile: '',
        password: ''
    }
  },

(4) Modify pages/login/index.vue and add login method

login () {    
    userApi.login(this.mobile,this.password).then( res =>{
      if(res.data.flag){
          location.href='/manager'
      }else{
          this.$message({
              message: res.data.message,
              type: 'error'
          })
          this.mobile=''
          this.password=''
      }
   })
}

(5) Binding page

 <form class="sui-form login-form"> 
      <div class="control-group"> 
       <label for="inputname" class="control-label">Cell-phone number:</label> 
       <div class="controls"> 
        <input type="text" id="inputname"  v-model="loginname"  placeholder="11 Mobile phone number" class="input-xlarge" /> 
       </div> 
      </div> 
      <div class="control-group"> 
       <label for="inputpassword" class="control-label">Password:</label> 
       <div class="controls"> 
        <input type="password" id="inputpassword"  v-model="password" placeholder="Enter login password" class="input-xlarge" /> 
       </div> 
      </div> 
      <div class="controls"> 
       <label> <input type="checkbox" name="remember-me" /><span class="type-text" style="font-size:12px;">Remember login status</span> </label> 
       <button type="button" @click="login" class="sui-btn btn-danger btn-yes">Sign in</button> 
      </div> 
      <div class="other-methods"> 
      </div> 
     </form> 

Test effect, log in and jump to the homepage

2.2 login user information storage

(1) Install JS cookie

cnpm install js-cookie --save

(2) Create utils/auth.js

import Cookies from 'js-cookie'

const TokenKey = 'User-Token'
const NameKey = 'User-Name'
const AvatarKey = 'User-Avatar'

export function setUser(token,name,avatar) {  
  Cookies.set(NameKey, name)
  Cookies.set(AvatarKey, avatar)
  Cookies.set(TokenKey, token)
}

(3) Modify pages/login/index.vue and import auth.js

import { setUser } from '@/utils/auth'

Modify the login method and call auth to save the cookie data

      login(){
        userApi.login(this.mobile,this.password ).then( res=> {
          if(res.data.flag){
            //Save user information 
            setUser(res.data.data.token, res.data.data.name, res.data.data.avatar)
            location.href='/manager' //User center    
          }else{
            this.$message( {
              message: res.data.message,
              type: "error"
            })
            this.mobile=''
            this.password=''
          }
        })
      }

2.3 login status display user information

Modify utils/auth.js

export function getUser() {
  return {
    token:Cookies.get(TokenKey),
    name:Cookies.get(NameKey),
    avatar:Cookies.get(AvatarKey)
  }
}

Modify the layouts/default.vue code section

import { getUser } from '@/utils/auth'
export default {
  data() {
    return {
      user:{}
    }
  },
  created() {
     this.user= getUser()     
  }
}

Judge to display the current login user name and avatar in the case of current login

<div class="sui-nav pull-right info" v-if="user.name!==undefined"> 
<li><a href="~/assets/other-notice.html" class="notice">{{user.name}}</a></li>
<li><a href="#" class="homego"><img :src="user.avatar" width="50px" height="50px" :alt="user.name"></a></li> 
</div> 

2.4 login link is displayed in not logged in status

Modify the layouts/default.vue page section

<div class="sui-nav pull-right info" v-if="user.name===undefined"> 
     <router-link to="/login">Land</router-link>
</div>

2.5 log out

Modify utils/auth.js

export function removeUser() {
  Cookies.remove(TokenKey)
  Cookies.remove(NameKey)
  Cookies.remove(AvatarKey)
}

Modify layouts/default.vue import removeUser method

import { getUser,removeUser } from '@/utils/auth'
import userApi from '@/api/user'

Add ways to log out

  methods:{
    logout(){      
      removeUser()//Clear login user information 
      location.href='/'        
    }
  }

Add a link to log out

<li><a @click="logout" class="notice">Logout</a></li>

3 wechat code scanning login

3.1 account application

(1) Open wechat open platform: https://open.weixin.qq.com/ register account first

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-O1ZSvwqA-1584002743698)(image/6-3.png))

(2) Developer qualification

[external link picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-nDpZ9YRV-1584002743705)(image/6-4.png))

(3) Create site app

[failed to transfer the pictures in the external chain. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-xmoahji-1584002743710) (image / 6-5. PNG))

Fill in information about the application

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-XFEYCetp-1584002743714)(image/6-6.png))

After the application passes the audit, it will get the AppID and AppSecret, which will be used later in the coding.

AppID : wx3bdb1192c22883f3
AppSecret : db9d6b88821df403e5ff11742e799105

3.2 wechat third party login process

1. After the third party initiates the wechat authorization login request, and the wechat user allows to authorize the third party application, wechat will pull up the application or redirect to the third party website, and bring the code parameter of the authorization temporary bill;
2. Through the code parameter plus AppID and AppSecret, access_token is exchanged through API;
3. Call the interface through access_token to obtain the basic data resources of users or help users realize basic operations.

Obtain the access? Token sequence diagram:

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-bzVe8AzL-1584002743718)(image/6-7.png))

3.3 get code

(1) Modify login.vue and add a div under the login form to display the wechat login QR code

<div id="weixin"></div> 

(2) Modify login.vue and introduce wechat login QR code js

    mounted(){
      var obj = new WxLogin({
        id: "weixin",
        appid: "wx3bdb1192c22883f3",
        scope: "snsapi_login",
        redirect_uri: "http://note.java.itcast.cn/weixinlogin"
      });    
    },
    head:{
      script:[
        {src:'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'}
      ]
    }

appid: app unique ID

scope: application authorization acts on

redirect_uri: callback address, which is the page to jump to after wechat login success

(3) Test: http://localhost:3000/login browser display

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-zV6zCzLO-1584002743723)(image/6-1.png))

When we open the mobile phone and scan the QR code with wechat, the following prompt will appear

[failed to transfer the pictures in the external link. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-bqhvFMUr-1584002743728)(image/6-2.png))

Click the confirm login button, and the browser will automatically jump to

http://note.java.itcast.cn/weixinlogin?code=02147Yff12Yhgz0ArCef1qabgf147Yf0&state=undefined

This code is a temporary token sent by wechat to users. We can request wechat third-party login interface to get access_token (official token) again according to code

3.4 obtain access_token

3.4.1 API

Access? Token through code

Interface specification

Get the interface of access? Token through code.

Request explanation

http Request mode: GET
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

Parameter description

parameter Is it necessary? Explain
appid yes Application unique identification, obtained after wechat open platform submitted for application review
secret yes AppSecret, the application key, is obtained after the wechat open platform submits the application for approval
code yes Fill in the code parameters obtained in the first step
grant_type yes Fill in the authorization code

Return instructions

Correct return:

{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN","openid":"OPENID",
"scope":"SCOPE"
}

parameter Explain
access_token Interface call credentials
expires_in Timeout time of calling the voucher by access \ token interface, unit (s)
refresh_token User refresh access_token
openid Unique ID of authorized user
scope Scope of user authorization, separated by commas (,)

3.4.2 write node service

Create a new node project weixinlogin to call the wechat third-party login interface project to create server.js

var http = require('http');  
var https = require('https');  
var url = require('url');
http.createServer(function(request,response){   
    var params=url.parse(request.url, true).query;
    var appid='wx3bdb1192c22883f3';
    var secret='db9d6b88821df403e5ff11742e799105';
    if(params.operation==='token'){
        https.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${params.code}&grant_type=authorization_code`, function (res) {
            res.on('data', function (chunk) {  
              response.writeHead(200,{'Content-Type':'application/json;charset=utf-8' ,"Access-Control-Allow-Origin": "*" });        
              response.end(chunk);
            });
        })
    }   
}).listen(8888);
// The terminal prints the following information
console.log('Server running at http://127.0.0.1:8888/');

Enter node server in the console to run the service

Address bar test: http: / / localhost: 8888 /? Code = 02147yff12yhgz0arcef1qabgf147yf0 & operation = token

The results are as follows:

{
  "access_token": "10_zSHADX2JGMivKFfa4nMbZV3ECzY21UY3qrF5ADyjpr_iiLUifo-nlN0GaRnUEN9T7BagiwSC07awplRFIO1Ghw",
  "expires_in": 7200,
  "refresh_token": "10__zl8gcJz0RXVDKtksbNTQJZ2uK1HiLJZ3I5PcSkA2VB3b6WXi2CR3R_htW6B8kKOmj-91p08SJMfVKkL84vP1w",
  "openid": "oypcC1u9r-mxVsRGSLFqE65lysVI",
  "scope": "snsapi_login",
  "unionid": "o6JuL1gaIwnVsZC5BpRYImTHKTm8"
}

3.4.3 calling node service

After the completion of the node service, we call the node service in the ten party front office project.

(1) Write API and create api/weixin.js

import axios from 'axios'
export default {
    getAccessToken(code){
        return axios.get(`http://localhost:8888?operation=token&code=${code}`)
    }
}

(2) Create utils/param.js (to get browser address bar parameters)

export function getUrlParam(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  var r = window.location.search.substr(1).match(reg);
  if(r != null) return unescape(r[2]);
  return null;
}

(3) Create pages / weixinlog.vue

<template>
    <div></div>
</template>
<script>
import {getUrlParam} from '@/utils/param'
import weixin from '@/api/weixin'
import {setUser} from '@/utils/auth'
export default {
    mounted(){
      let code=getUrlParam('code')
      if(code!==null){//If it's wechat login
        //Get access_token according to code
        weixin.getAccessToken(code).then( res=>{
          let access_token= res.data.access_token
          let openid= res.data.openid
          console.log('access_token:'+access_token+ 'openid:'+openid)
        })
      }
    }
}
</script>

3.5 get user nicknames and avatars

3.5.1 API

http request method: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

parameter Is it necessary? Explain
access_token yes Calling credential
openid yes The ID of an ordinary user, unique to the current developer account
lang no Country / region language version, Zh CN simplified, Zh TW traditional, en English, default is zh cn

Return instructions

Correct Json return result:

{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"

}
parameter Explain
openid The ID of an ordinary user, unique to the current developer account
nickname Common user nickname
sex General user gender, 1 male, 2 female
province Province filled in by personal data of ordinary users
city City filled in by personal data of ordinary users
country Country, if China is CN
headimgurl User's head image. The last value represents the size of square head image (0, 46, 64, 96, 132 values are optional, 0 represents 640 * 640 square head image). This item is empty when the user does not have a head image
privilege User privilege information, json array, for example, wechat Walker user is (chinaunicom)
unionid Unified user identification. For an application under an account of wechat open platform, the unionid of the same user is unique.

3.5.2 write node service

Modify the server.js of weixinlog in the node project, and add new code

.....
    if(params.operation==='userinfo'){
        https.get(`https://api.weixin.qq.com/sns/userinfo?access_token=${params.access_token}&openid=${params.openid}`, function (res) {
            res.on('data', function (chunk) {  
              // Send response data "Hello World"
              response.writeHead(200,{'Content-Type':'application/json;charset=utf-8' ,"Access-Control-Allow-Origin": "*" });        
              response.end(chunk);
            });
        })
    }  
.....

3.5.3 calling node service

(1) Write API, modify api/weixin.js new method to obtain user information according to access_token and openid

    getUserinfo(access_token,openid){
        return axios.get(`http://localhost:8888?operation=userinfo&access_token=${access_token}&openid=${openid}`)
    }

(2) Modify pages / weixinlog.vue

import {setUser} from '@/utils/auth'

After obtaining the access_token and openid, request the interface again, obtain the nickname and avatar, and save them in the cookie

    mounted(){
      let code=getUrlParam('code')
      if(code!==null){//If it's wechat login
        //Get access_token according to code
        weixin.getAccessToken(code).then( res=>{
          let access_token= res.data.access_token
          let openid= res.data.openid
          weixin.getUserinfo( access_token, openid ).then( res => {
            //Extract user nicknames and avatars**********************
            let nickname= res.data.nickname
            let headimgurl= res.data.headimgurl
            setUser(access_token,nickname,headimgurl)
            location.href='/'
          })
        })
      }
    }

3.6 domain name and port settings

We just need to manually change the url to complete the test, mainly because the callback address is the domain name and our project is the local address. In fact, it's not difficult for us to achieve a one-off effect, as long as we set the domain name and port.

3.6.1 domain name pointing

We can configure the domain name to point to

127.0.0.1 note.java.itcast.cn

In this way, our project can be accessed through http://note.java.itcast.cn:3000

3.6.2 NUXT port setting

Modify package.json and add configuration

  "config": {
    "nuxt": {
      "port": "80"
    }
  },

Restart the project, and you can access it through http://note.java.itcast.cn.

After the above modifications, we test wechat code scanning login again, and you can see the same operation effect as the production environment.

4 user center nesting layout

4.1 sub layout page

(1) Create pages/manager.vue, which is the layout page of user center

<template>
<div>
  <div class="myhome-personinfo" style="background-image: url('~/assets/img/widget-homebg.png');"> 
   <div class="wrapper"> 
    <div class="person-baseinfo"> 
     <!--Head information--> 
     <div class="photo"> 
      <img src="~/assets/img/widget-myphoto.jpg" alt="" class="person" /> 
      <div class="share"> 
       <span><img src="~/assets/img/asset-QQ.png" alt="" width="34" height="28" /></span> 
       <span><img src="~/assets/img/asset-weixin.png" alt="" width="28" height="28" /></span> 
       <span><img src="~/assets/img/asset-weibo.png" alt="" width="28" height="28" /></span> 
      </div> 
     </div> 
     <!--Character information--> 
     <div class="info"> 
      <h1>Web Amateur<span class="allinfo"><a href="~/assets/person-myfile.html" target="_blank">View full profile</a></span></h1> 
      <ul class="fill"> 
       <li> <i class="fa fa-map-marker" aria-hidden="true"></i> <span class="edit-item"> Fill in the current city</span> 
        <form action="" class="sui-form form-inline"> 
         <input type="text" placeholder="Residential city" /> 
         <button class="sui-btn btn-danger save-btn">Preservation</button> 
        </form> </li> 
       <li> <i class="fa fa-graduation-cap" aria-hidden="true"></i> <span class="edit-item"> Fill in Graduate School</span> 
        <form action="" class="sui-form form-inline"> 
         <input type="text" placeholder="Name of institution" /> 
         <input type="text" placeholder="Major studied" /> 
         <button class="sui-btn btn-danger save-btn">Preservation</button> 
        </form> </li> 
       <li> <i class="fa fa-shopping-bag" aria-hidden="true"></i> <span class="edit-item"> Fill in the company/organization</span> 
        <form action="" class="sui-form form-inline"> 
         <input type="text" placeholder="company/Organization name" /> 
         <input type="text" placeholder="Job Title" /> 
         <button class="sui-btn btn-danger save-btn">Preservation</button> 
        </form> </li> 
       <li> <i class="fa fa-link" aria-hidden="true"></i> <span class="edit-item"> Fill in personal website</span> 
        <form action="" class="sui-form form-inline"> 
         <input type="text" placeholder="Personal website" /> 
         <button class="sui-btn btn-danger save-btn">Preservation</button> 
        </form> </li> 
      </ul> 
     </div> 
    </div> 
    <!--Right editor--> 
    <div class="edit-info"> 
     <h4>Personal profile<span class="addedit"><img src="~/assets/img/widget-edit.png" width="12" height="12" />edit</span></h4> 
     <div class="info-box"> 
      <div class="edit-intro">
       No profile
      </div> 
     </div> 
    </div> 
    <div class="clearfix"></div> 
   </div> 
  </div> 
   <!--Two column layout--> 
  <div class="wrapper  myhome"> 
   <div class="left-list"> 
    <div class="myhome-list"> 
     <ul class="home-list"> 
      <li class="active"><a href="~/assets/person-homepage.html">My homepage</a></li> 
      <li><a href="~/assets/person-myanswer.html">My answer</a></li> 
      <li><a href="~/assets/person-myquestion.html">My questions</a></li> 
      <li><a href="~/assets/person-myshare.html">My sharing</a></li> 
     </ul> 
     <ul class="home-list bottom"> 
      <li><a href="~/assets/person-dynamic.html">Personal dynamics</a></li> 
      <li><a href="~/assets/person-myfocus.html">My concern</a></li> 
      <li><a href="~/assets/person-mycollect.html">My collection</a></li> 
      <li><a href="~/assets/person-myreaded.html">Browse record</a></li> 
      <li><a href="~/assets/person-account.html">Account settings</a></li> 
     </ul> 
    </div> 
   </div> 
   <div class="right-content"> 
    <nuxt-child/>
   </div> 
   <div class="clearfix"></div> 
  </div> 
</div>
</template>
<script>
import '~/assets/css/page-sj-person-homepage.css'
</script>

Note: we use the < nuxt child / > label

(2) Create the manager folder under pages and index.vue under manager (the default home page of user center)

<template>
   <div class="home-content"> 
     <ul class="sui-nav nav-tabs nav-large"> 
      <li class="active"><a href="#one" data-toggle="tab">My questions</a></li> 
      <li><a href="#two" data-toggle="tab">My answer</a></li> 
     </ul> 
     <div class="tab-content tab-wraped"> 
      <div id="one" class="tab-pane active"> 
       <ul class="question-list"> 
        <li> <span class="fl good"><span class="num">12</span> Useful</span> <span class="title"><a href="#">Of PHP The problem of primary advanced</a></span> <span class="fr date">4 6 June</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"><span class="num">12</span> Useful</span> <span class="title"><a href="#">Of JAVA The problem of primary advanced</a></span> <span class="fr date">4 6 June</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"><span class="num">12</span> Useful</span> <span class="title"><a href="#">Of HTML5 The problem of primary advanced</a></span> <span class="fr date">4 6 June</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"><span class="num">12</span> Useful</span> <span class="title"><a href="#">Of C++The problem of primary advanced</a></span> <span class="fr date">4 6 June</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"><span class="num">12</span> Useful</span> <span class="title"><a href="#">Of python The problem of primary advanced</a></span> <span class="fr date">4 6 June</span> <span class="clearfix"></span> </li> 
       </ul> 
      </div> 
      <div id="two" class="tab-pane"> 
       <ul class="question-list"> 
        <li> <span class="fl good"> <span class="num">8</span> Useful</span> <span class="title"><a href="#">Of PHP The problem of primary advanced</a></span> <span class="fr date">2017-07-05 15:08</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"> <span class="num">7</span> Useful</span> <span class="title"><a href="#">Of JAVA The problem of primary advanced</a></span> <span class="fr date">2017-07-05 15:08</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"> <span class="num">6</span> Useful</span> <span class="title"><a href="#">Of HTML5 The problem of primary advanced</a></span> <span class="fr date">2017-07-05 15:08</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"> <span class="num">12</span> Useful</span> <span class="title"><a href="#">Of C++The problem of primary advanced</a></span> <span class="fr date">2017-07-05 15:08</span> <span class="clearfix"></span> </li> 
        <li> <span class="fl good"> <span class="num">12</span> Useful</span> <span class="title"><a href="#">Of python The problem of primary advanced</a></span> <span class="fr date">2017-07-05 15:08</span> <span class="clearfix"></span> </li> 
       </ul> 
      </div> 
     </div> 
     <div class="activities"> 
      <h4 class="tit"><span>My dynamics</span></h4> 
      <ul class="activities-content"> 
       <li> 
        <div class="index-title"> 
         <span class="author">Benjamin</span> 
         <span class="operate">Tag focused</span> &middot; 
         <span class="time">3 Hours ago</span> 
        </div> 
        <div class="guanzhuname"> 
         <span class="tag">php</span> 
         <span class="tagnum">100</span> follow 
        </div> 
        <div class="intro">
          PHP,It is an English hypertext preprocessing language Hypertext Preprocessor Abbreviation. PHP It is an open source general computer scripting language, especially suitable for network development and embeddable HTML Used in. PHP Grammar reference and absorption of C Language, Java and Perl And other popular computer language features, easy for general programmers to learn. 
        </div> </li> 
       <li> 
        <div class="index-title"> 
         <span class="author">Benjamin</span> 
         <span class="operate">Answered the question</span> &middot; 
         <span class="time">3 Hours ago</span> 
        </div> 
        <div class="question"> 
         <p class="title">How to open WeChat directly and enter the official account page</p> 
         <p class="content">Now that WeChat is shielded, you can choose to connect to a public official account.</p> 
        </div> 
        <div class="qa-num"> 
         <span>follow<i>1</i></span> 
         <span>Answer<i>2</i></span> 
        </div> </li> 
       <li> 
        <div class="index-title"> 
         <span class="author">Benjamin</span> 
         <span class="operate">Collected articles</span> &middot; 
         <span class="time">3 Hours ago</span> 
        </div> 
        <div class="question"> 
         <p class="title">How to open WeChat directly and enter the official account page</p> 
        </div> 
        <div class="qa-num"> 
         <span><a href="#">http://baidu.com</a></span> 
        </div> </li> 
       <li> 
        <div class="index-title"> 
         <span class="author">Benjamin</span> 
         <span class="operate">Collected articles</span> &middot; 
         <span class="time">3 Hours ago</span> 
        </div> 
        <div class="question"> 
         <p class="title">How to open WeChat directly and enter the official account page</p> 
        </div> 
        <div class="qa-num"> 
         <span><a href="#">http://baidu.com</a></span> 
        </div> </li> 
       <li> 
        <div class="index-title"> 
         <span class="author">Benjamin</span> 
         <span class="operate">Answered the question</span> &middot; 
         <span class="time">3 Hours ago</span> 
        </div> 
        <div class="question"> 
         <p class="title">How to open WeChat directly and enter the official account page</p> 
         <p class="content">Now that WeChat is shielded, you can choose to connect to a public official account.</p> 
        </div> 
        <div class="qa-num"> 
         <span>follow<i>1</i></span> 
         <span>Answer<i>2</i></span> 
        </div> </li> 
      </ul> 
     </div> 
    </div> 
</template>

4.2 sub pages of user center

(1) Create pages/manager/myanswer.vue (my Q & A)

(2) Create pages/manager/myquestion.vue (my question)

(3) Create pages/manager/myshare.vue (my share)

(4) Create pages/manager/dynamic.vue

(5) Create pages/manager/myfocus.vue (my focus)

(6) Create pages/manager/mycollect.vue (my favorite)

(7) Create pages / Manager / myread.vue (browse record)

(8) Create pages / Manager / account.vue (account settings)

4.3 menu style processing

Modify the link address in pages/manager.vue

    <div class="myhome-list"> 
     <ul class="home-list"> 
       <router-link to="/manager" active-class="active" tag="li" exact ><a>My homepage</a></router-link>
       <router-link to="/manager/myanswer" active-class="active" tag="li" exact ><a>My answer</a></router-link>
       <router-link to="/manager/myquestion" active-class="active" tag="li" exact ><a>My questions</a></router-link>
       <router-link to="/manager/myshare" active-class="active" tag="li" exact ><a>My sharing</a></router-link>     
     </ul> 
     <ul class="home-list bottom">
       <router-link to="/manager/dynamic" active-class="active" tag="li" exact ><a>Personal dynamics</a></router-link>
       <router-link to="/manager/myfocus" active-class="active" tag="li" exact ><a>My concern</a></router-link>
       <router-link to="/manager/mycollect" active-class="active" tag="li" exact ><a>My collection</a></router-link>
       <router-link to="/manager/myreaded" active-class="active" tag="li" exact ><a>Browse record</a></router-link>
       <router-link to="/manager/account" active-class="active" tag="li" exact ><a>Account settings</a></router-link>
     </ul> 
    </div> 

4.4 user center authentication

Modify the code part of pages/manager.vue

import '~/assets/css/page-sj-person-homepage.css'
import {getUser} from '@/utils/auth'
export default {
    created(){
        if(getUser().name===undefined){
            this.$router.push('/login')
        }
    }
}

Test: entering http://localhost:3000/manager in the address field without logging in will automatically jump to the login page

Modify the user name and avatar of layouts/default.vue and link to the user center

<li><a href="/manager" class="notice">{{user.name}}</a></li>     
...
<li><a href="/manager"  class="homego"><img :src="user.avatar" width="50px" height="50px" :alt="user.name" /></a></li>
Published 13 original articles, won praise 1, visited 126
Private letter follow

Keywords: Vue Mobile Java PHP

Added by mdojet on Thu, 12 Mar 2020 11:42:48 +0200