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