5.ベースアドレスのカプセル化
1.ダウンロードしてインストールします
npm i axios
2.パッケージファイルを追加して、axiosのパッケージを実現します
// 封装文件为:@/utils/myaxios.js
import axios from 'axios'
// 设置基准路径
axios.defaults.baseURL = 'http://localhost:3000'
// ......还有一大坨代码
export default axios
5.1ログインインターフェイスをカプセル化する
// @/apis/user.js
---------------------------
// 引入的axios已经配置好基准路径
import axios from '@/utils/myaxios.js'
// 1.登陆
export const login = (data) => {
return axios({
method:'post',
url:'/login',
data
})
}
5.2ユーザー名とパスワードの検証の規則性
if (/^1\d{4}$|^1[35789]\d{9}$/.test(this.user.username) && /^.{3,16}$/.test(this.user.password)) {
console.log(22);
5.3トークンの保存
// 获取token,待会去验证是否可以登录
localStorage.setItem('token',res.data.data.token)
5.3完全なログイン効果:IDを持参
this.$router.push({ path: `/personal/${res.data.data.user.id}` })
2つのキーワード:asyncとawait
非同期メソッドを同期的に呼び出すことができます。つまり、非同期操作の戻り結果を直接取得し、その結果に従って次のステップに進むことができます。
awaitはasync関数内にある必要があります。asyncでマークされた関数は、awaitキーワードが配置されている関数です。
methods:{
// login(){
// console.log(this.user.username,this.user.password);
// login(this.user)
// .then((res)=>{
// console.log(res);
// })
// .catch((err)=>{
// console.log(err);
// })_
// }
// 发起axios请求:async+函数变成异步:先接收data回来再发请求
async login(){
if (/^1\d{4}$|^1[35789]\d{9}$/.test(this.user.username) && /^.{3,16}$/.test(this.user.password)) {
console.log(22);
let res = await login(this.user)
console.log(res);
if(res.data.message === '用户不存在'){
// 给出用户提示
this.$toast.fail(res.data.message)
}
else{
// 实现页面的跳转
this.$toast.success('登录成功');
// 获取token,待会去验证是否可以登录
localStorage.setItem('token',res.data.data.token)
// 为了后期的操作,将当前用户数据也存储到本地
// window.location.href='#/personal'
this.$router.push({
path: `/personal/${
res.data.data.user.id}` })
}
}else if(this.user.username==''||this.user.password==''){
this.$toast.fail('请输入用户名或密码')
}
else{
this.$toast.fail('用户或密码不正确')
}
}
}
}
6.パーソナルハブページ
ログインに成功したら、パーソナルセンターページにジャンプする必要があります
6.1新しい単一ファイルコンポーネント
@ / views / personal.vue
6.2ルーティングを構成する
this。$ route.params.idからIDを取得します
{
name: 'personal',
path: '/personal/:id',
// 异步组件:请求login页面的时候再引入文件
component: () =>
import ('@/views/personal.vue')
}
6.3パッケージインターフェース
// 获取用户详情
// 接口类型:【GET】
// 需要验证:【Authorization 】
// 接口地址:/user/:id
// xhr.setRequestHeader('Conent-Type','applicatio/x-www-form-urlencoded')
export const getUserInfo = (id) => {
return axios({
url: `/user/${
id}`,
// headers: { Authorization: localStorage.getItem('hm_toutiao_56') }
})
}
6.4ログインページ設定ジャンプ
// 实现页面的跳转(嵌套路由)
this.$router.push({
path: `/personal/${
res.data.data.user.id}` })
// window.location.href='#/personal'
前者はURLにIDを持ち、後者はthis。$ route.params.idを使用してIDを取得します
6.5新しいmycellサブコンポーネント
</style><template>
<div class="mycell">
<div class="left">{
{title}}</div>
<div class="right">{
{desc}}<span class="iconfont iconjiantou1"></span></div>
</div>
</template>
<script>
export default {
props:['title','desc']
}
</script>
<style lang='less' scoped>
.mycell{
padding: 20px 10px;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ccc;
> .right{
font-size: 13px;
color: #888;
}
}
</style>
6.7ボタンサブコンポーネントの紹介
<mycell title='我的关注' desc='关注的用户'></mycell>
<mycell title='我的跟帖' desc='跟帖/回复'></mycell>
<mycell title='我的收藏' desc='文章/视频'></mycell>
<mycell title='设置'></mycell>
<hmbutton type='warning'>退出</hmbutton>
6.8新しい日付サブコンポーネント:
パッケージ日付フィルターsrc / utils / myfilter.js
// 封装项目中所需要使用的全局过滤器
// 过滤器的本质是函数
export const dateFormat = (value, spe) => {
console.log(typeof value)
value = new Date(value) // 将value字符串转换为日期格式
let year = value.getFullYear()
let month = value.getMonth() + 1
let day = value.getDate()
return `${
year}${
spe}${
month}${
spe}${
day}`
}
import {
dateFormat } from '@/utils/myfilter.js'
// 由于我们封装是函数,所以得进行注册,确定它是用于过滤器
filters: {
dateFormat
},
<div class="time">{
{
userinfo.create_date | dateFormat('-')}}</div>
6.9アバターのレンダリング
新しいユーザーはアバターを持っておらず、デフォルトのアバターを使用し、古いユーザーは編集ユーザー情報に保存されているアバターを使用します。
if(this.userinfo.head_img){
this.userinfo.head_img=axios.defaults.baseURL+this.userinfo.head_img
}else{
this.userinfo.head_img=axios.defaults.baseURL+'/uploads/image/timg.gif'
}
6.10ページ全体の効果を完成させる
フック機能を使用して、デフォルトでデータをレンダリングします:アバター、ユーザー名、日付
<template>
<div class="personal">
<!-- 渲染头部 -->
<router-link :to="'/edit_profile/'+userinfo.id">
<div class="profile">
<img :src="userinfo.head_img" alt />
<div class="profile-center">
<div class="name">
<span class="iconfont" :class='userinfo.gender===0?"iconxingbienv":"iconxingbienan"'></span>{
{userinfo.nickname}}
</div>
<div class="time">{
{userinfo.create_date | dateFormat}}</div>
<!-- 渲染头部结束 -->
</div>
<span class="iconfont iconjiantou1"></span>
</div>
</router-link>
<mycell title='我的关注' desc='关注的用户'></mycell>
<mycell title='我的跟帖' desc='跟帖/回复'></mycell>
<mycell title='我的收藏' desc='文章/视频'></mycell>
<mycell title='设置'></mycell>
<hmbutton type='warning' @click="exit">退出</hmbutton>
</div>
</template>
<script>
// 个人中心页,待会登录页验证成功需要跳过来
// 操作:把个人中心页的结构和样式复制过来
// 配置路由然后实现跳转到个人中心,如果判断登录了放进来给数据 没有:回去登录页
// 使用导航守卫判断带是否登录过,有就放进来,没有:回去登录页
// 使用请求拦截器,在发送请求之前把token带上
import mycell from '@/components/mycell.vue'
import hmbutton from '@/components/hmbutton.vue'
import { getUserInfo } from '@/apis/user.js'
import axios from '@/utils/myaxios.js'
import { dateFormat } from '@/utils/myfilter.js'
export default {
data () {
return {
userinfo:{}
}
},
components:{
mycell,hmbutton
},
// 由于我们封装是函数,所以得进行注册,确定它是用于过滤器
filters:{
dateFormat
},
methods:{
exit(){
localStorage.removeItem('tokens')
this.$router.push({path:'/index'})
}
},
async mounted () {
// 一进来渲染数据:头部
let id = this.$route.params.id
let res = await getUserInfo(id)
console.log(res)
this.userinfo=res.data.data
console.log(this.userinfo);
if(this.userinfo.head_img){
this.userinfo.head_img=axios.defaults.baseURL+this.userinfo.head_img
}else{
this.userinfo.head_img=axios.defaults.baseURL+'/uploads/image/timg.gif'
}
}
};
7.ルートナビゲーションガード:
チケットを確認するの:個人がログインしているかどうかを判断し、ログインしている場合は入力します。ログインしていない場合は入力します。ログインページに戻ります。
ナビゲーションガードの役割は、ナビゲーションをガードすることです
一部のページに移動するときは、現在のユーザーがログインしているかどうかを判断する必要があります。ログインしている場合はジャンプできます。そうでない場合は、ログインページにリダイレクトされます。
ナビゲーションガードはルートのナビゲーションガードです
// 路由的跳转:就是去另外一个组件,页面
// 添加路由守卫,判断是否可以跳转,它是通过进行路由的跳转时自动触发的,不是人为调用的
// 所有路由跳转请求都会经过这个导航守卫
// to:目标路由
// from:源路由
// next:下一步的操作,就是用户当前需要进行的操作
router.beforeEach((to, from, next) => {
// 并不是每个页面的访问都需要先登陆
if (to.name == 'personal') {
// 这里说明你要访问个人中心页
// 如果用户登陆过,则进行路由的跳转,否则重定向到登陆页
let token = localStorage.getItem('token')
if (token) {
// 如果有token说明你登陆过了
next()
} else {
Toast('请先登录')
// 如果是访问需要授权的页面且没有登陆过,则重定向到登陆页
next({
name: 'Login' })
}
} else {
// 如果不是访问需要授权的页面,如新闻页,那么不需要判断是否登陆
next()
}
})
// 暴露
export default router
8.axiosインターセプター
8.1リクエストインターセプター:検査のためにチケットを出します
リクエストを送信する前に、現在のリクエストをインターセプトし、それに応じてリクエストメッセージを処理します
// 添加请求拦截器:所有请求都会经过这个拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// 获取token
let token = localStorage.getItem('toutiao_52_token')
// 判断是否有token如果有,则以请求头的方式进行传递
if(token){
config.headers.Authorization = token
}
// 可以拦截请求对报文进行处理,但是拦截器并不会代替你来发请求,只是对发送请求时所传递的报文 数据进行必要的处理
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});