vue3项目实战---知乎日报----个人中心

目录

登录态校验

header组件

个人中心

修改个人信息

FormData

FormData操作方法


登录态校验

通过 beforeEach 路由导航守卫实现 (to 从哪来,from:去哪, next执行)

通过to.path 判断要去的页面 为个人中心,编辑个人信息,收藏 做拦截

判断vuex中 isLogin是否为登录 true不做拦截 false跳转到登录页

如果为null 跳转登录页  同时调取接口校验是否登录 通过commi同步vuex管理的状态

import { createRouter, createWebHashHistory, } from "vue-router";
import routes from './routes';
const router = createRouter({
    //createWebHistory-->History路由 createWebHashHistory-->HASH路由
    //基于Hash指定模式
    history: createWebHashHistory(),
    routes,
})
import store from '../store/index'
import { CheckLogin } from '../api/index'
import { Toast } from 'vant'
//路由前置导航守卫 to去哪 from从哪来 next必须执行
router.beforeEach(async (to, from, next) => {
    //个人中心,编辑个人信息,收藏
    const arr = ['/person', '/update', '/store']
    if (arr.includes(to.path)) {
        //校验是否登录
        let isLogin = store.state.isLogin
        if (isLogin) {
            next();
            return
        }
        if (isLogin == false) {
            Toast('小主,请先登录哦~')
            next('/login')
            return
        }
        if (isLogin == null) {
            // 不可以派发任务  只会执行一次,应该发送请求访问
            // store.dispatch('changeIsLoginAsync')
            try {
                let { code, data } = await CheckLogin()
                if (code != 0) {
                    Toast('小主,请先登录哦~')
                    next('/login')
                    return
                }
                store.commit('changeIsLogin', true)
                store.commit('changeInfo', data)
                next()
            } catch (err) { }
            return
        }
        return
    }
    next()
})
export default router

header组件

首页header组件

通过 计算属性  决定头象的显示

增加代码严谨性在初次渲染完毕后校验vuex状态是否为空 为空派发任务更新状态

<template>
  <header class="header-box">
    <div class="left">
      <div class="time">
        <span>{{ time.day }}</span>
        <span>{{ time.month }}</span>
      </div>
      <h1 class="title">知乎日报</h1>
    </div>
    <div class="pic-box">
      <router-link :to="`/person`"> <img :src="pic" alt="" /></router-link>
    </div>
  </header>
</template>

<script>
import { reactive, ref, toRefs, computed, onBeforeMount } from "vue";
import { formatTime } from "../assets/utils";
import timg from "../assets/images/timg.jpg";
import { useStore } from "vuex";
export default {
  name: "Header",

  setup() {
    //状态
    let state = reactive({
      today: formatTime(null, "{0}{1}{2}"),
    });
    const store = useStore();
    // 派发获取登录状态和用户信息的方法
    onBeforeMount(() => {
      let { isLogin, info } = store.state;
      if (isLogin === null) store.dispatch("changeIsLoginAsync");
      if (info === null) store.dispatch("changeInfoAstnc");
    });

    //基于计算属性,处理时间
    let time = computed(() => {
      let { today } = state;
      let [month, day] = formatTime(today, "{1}-{2}").split("-");
      let newMonth = month.slice(1, 2);
      let arr = [
        "",
        "一",
        "二",
        "三",
        "四",
        "五",
        "六",
        "七",
        "八",
        "九",
        "十",
        "十一",
        "十二",
      ];
      return {
        day,
        month: arr[newMonth] + "月",
      };
    });
    //通过计算属性,决定头像
    let pic = computed(() => {
      let { isLogin, info } = store.state;
      if (isLogin && info) {
        return info.pic || timg;
      }
      return timg;
    });
    return {
      ...toRefs(state),
      time,
      pic,
    };
  },
};
</script>

<style lang="less" scoped>

个人中心

实现安全退出 应该清除token vuex 跳转到首页

replace和piush的区别 :piush为压栈增加一条历史记录,返回上一级,replace为替换返回两级

<template>
  <Nav></Nav>
  <div class="base-info" v-if="info">
    <router-link :to="`/Update`">
      <img :src="info.pic" alt="" />
    </router-link>
    <p>{{ info.name }}</p>
  </div>
  <van-cell-group>
    <van-cell title="我的收藏" is-link url="#/store"></van-cell>
    <van-cell title="退出登录" @click="signout"></van-cell>
  </van-cell-group>
</template>

<script>
import { computed, onBeforeMount } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { Toast } from "vant";
import Nav from "../components/Nav.vue";
export default {
  name: "Person",
  setup() {
    const router = useRouter();
    const store = useStore();
    //清除token、 清空vuex状态
    const signout = () => {
      Toast("小主,您已安全退出");
      localStorage.removeItem("token");
      store.commit("changeIsLogin", null);
      store.commit("changeInfo", null);
      router.replace("/login");
    };
    // 派发获取登录状态和用户信息的方法
    onBeforeMount(() => {
      let { isLogin, info } = store.state;
      if (isLogin === null) store.dispatch("changeIsLoginAsync");
      if (info === null) store.dispatch("changeInfoAstnc");
    });
    //通过计算属性,获取用户信息
    let info = computed(() => {
      let { isLogin, info } = store.state;
      if (isLogin && info) {
        return info;
      }
      return null;
    });
    return { signout, info };
  },
  components: { Nav },
};
</script>

<style lang="less" scoped>
.base-info {
  img {
    width: 80px;
    height: 80px;
    display: block;
    margin: 10px auto;
    border-radius: 50%;
  }
  p {
    text-align: center;
  }
}
</style>

修改个人信息

api

使用FormData 格式发送

//修改用户信息  
export const Userupdate = (username, file) => {
    let fm = new FormData()
    fm.append('username', username)
    fm.append('file', file);
    return axios.post('/api/user_update', fm)
}

 van-uploader组件 返回file文件对象

<template>
  <Nav></Nav>
  <div class="from-box">
    <van-cell-group inset>
      <van-field v-model="name" label="用户名" label-width="60px"></van-field>
      <van-field label="用户头像" label-width="60px">
        <template #input>
          <van-uploader v-model="pic" max-count="1"></van-uploader>
        </template>
      </van-field>
    </van-cell-group>
    <div style="margin: 20px 40px">
      <van-button round block type="primary" @click="submit"
        >修改信息
      </van-button>
    </div>
  </div>
</template>


<script>
import { useStore } from "vuex";
import { reactive, toRefs } from "vue";
import { Toast } from "vant";
import { useRouter } from "vue-router";
import Nav from "../components/Nav.vue";
import { Userupdate } from "../api/index";
export default {
  components: { Nav },
  name: "UpdataPerson",
  setup() {
    const router = useRouter();
    const store = useStore();
    let { name } = store.state.info;
    let state = reactive({
      name,
      pic: [],
    });
    const submit = async () => {
      let { name, pic } = state;
      //格式检验
      let reg = /^[\w\u4e00-\u9fa5]+$/;
      if (!reg.test(name)) {
        Toast("小主,用户名输入错误~");
        return;
      }
      if (pic.length == 0) {
        Toast("小主,必须上传一张图片~");
        return;
      }
      console.log(pic[0].file);
      let { code, data } = await Userupdate(name, pic[0].file);
      if (code != 0) {
        Toast("小主,信息修改失败,请稍后再试~");
        return;
      }
      Toast("小主太棒了,信息修改成功");
      store.commit("changeInfo", data);
      router.replace("/person");
    };
    return {
      ...toRefs(state),
      submit,
    };
  },
};
</script>

FormData

1.创建一个空对象

var formData = new FormData();//通过append方法添加数据

2、使用已有表单来初始化对象

//表单示例
<form id="myForm" action="" method="post">
    <input type="text" name="name">名字
    <input type="password" name="psw">密码
    <input type="submit" value="提交">
</form>

//方法示例
// 获取页面已有的一个form表单
var form = document.getElementById("myForm");
// 用表单来初始化
var formData = new FormData(form);
// 我们可以根据name来访问表单中的字段
var name = formData.get("name"); // 获取名字
var psw = formData.get("psw"); // 获取密码
// 当然也可以在此基础上,添加其他数据
formData.append("token","kshdfiwi3rh");

formData里面存储的数据是以健值对的形式存在的,key是唯一的,一个key可能对应多个value。
如果是使用表单初始化,每一个表单字段对应一条数据,它们的HTML name属性即为key值,它们value属性对应value值。

FormData操作方法

  • formData.append:添加数据
  • formData.set 设置值
  •  formData.has 判断是否存在对应数据
  • delete(key)删除数据
//通过get(key)/getAll(key)来获取对应的value
formData.get("name"); // 获取key为name的第一个值
formData.getAll("name"); // 返回一个数组,获取key为name的所有值


//通过append(key, value)来添加数据,如果指定的key不存在则会新增一条数据,如果key存在,则添加到数据的末尾
formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v3");
formData.get("k1"); // "v1"
formData.getAll("k1"); // ["v1","v2","v3"]


//set(key, value)来设置修改数据,如果指定的key不存在则会新增一条,如果存在,则会修改对应的value值
formData.append("k1", "v1");
formData.set("k1", "1");
formData.getAll("k1"); // ["1"]


//has(key)来判断是否对应的key值
formData.append("k1", "v1");
formData.append("k2",null);

formData.has("k1"); // true
formData.has("k2"); // true
formData.has("k3"); // false

//delete(key)删除数据
formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");
formData.delete("k1");

formData.getAll("k1"); // []

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值