vue美食杰 个人空间


效果图

在这里插入图片描述

router文件下的index.js

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

import Home from '@/views/home/Home.vue'

const login = () => import( '../views/user-login/index.vue' );
const detail = () => import( '../views/detail/detail.vue' );

const space = () => import( '../views/user-space/space.vue' );
const fans = () => import( '../views/user-space/fans.vue' );
const MenuList = () => import( '../views/user-space/menu-list.vue' );

import { userInfo } from '@/service/api';
import Store from '@/store'
// import { Store } from "vuex"
const router = new Router({
    mode: "history",
    routes: [{
        path: '/',
        name: "Home",
        title: '首页',
        component: Home 
    },
    {
        path: '/login',
        name: "login",
        title: '登录页',
        component: login,
    }, 
    {
        path: '/detail',
        name: "detail",
        title: '',
        component: detail,
        meta: {
            login: true
        }
   
    }, 
    //个人空间的路由信息
    {
        path: '/space',
        name: "space",
        title: '个人空间',
        component: space,
        meta: {
            login: true
        },
        children:[
            {
                path: 'works',
                name: "works",
                title: '作品',
                component: MenuList,
                meta: {
                    login: true
                }
        
            }, {
                path: 'fans',
                name: "fans",
                title: '粉丝',
                component: fans,
                meta: {
                    login: true
                }
        
            }, {
                path: 'following',
                name: "following",
                title: '关注',
                component: fans,
                meta: {
                    login: true
                }
        
            }, {
                path: 'collection',
                name: "collection",
                title: '收藏',
                component: MenuList,
                meta: {
                    login: true
                }
        
            },
        ]
    }]
});
// var islogin = true
// var isLogin = true; // 是否登录
// 
// redirect:{
//     name:"works"
// },
router.beforeEach(async (to, from, next) => {
    // 进入路由守卫时,向后端发送 token,验证是否合法 mes
    let data = await userInfo(); 
    Store.commit("chnageUserInfo", data.data);
    // this.$store.commit("chnageUserInfo",data.data);
    if (to.matched.some(item => item.meta.login)) {  //判断一下是否需要登录
        // console.log("需要登录");
        const token = localStorage.getItem("token");
        // !!将数据类型转换为布尔值
        const isLogin = !!token;
        // console.log(isLogin);
        // console.log(data);
        if (isLogin) {
            if (data.error === 400) { // 后端告诉你,token不合法
                next({ name: 'login' });
                localStorage.removeItem('token');
                return;
            }
            next();
            return;
        }
        // 没登录, 但是要进入登录页
        if (!isLogin && to.name === 'login') {
            next();
        }

        // 没登录, 要进入的页面也不是登录
        if (!isLogin && to.name !== 'login') {
            next({ name: 'login' });
        }
    } else {
        next();
    }
})

export default router;

点击进行路由跳转,query里面的是传的用户id
<router-link  :to="{ path: '/space' }"  >
</router-link><router-link  :to="{ path: '/space', query: { userId: item.userId } }"  >
</router-link>

space.vue

<template>
  <div class="space">
    <h2>欢迎来到我的美食空间</h2>
    <div class="user-info">
      <div class="user-avatar">
        <img :src="userInfo.avatar" alt="" />
      </div>
      <div class="user-main">
        <h1>{{ userInfo.name }}</h1>

        <span class="info">
          {{ userInfo.createdAt }} <em>加入美食杰</em>
          |
          <router-link to="" v-show="!isOwner">编辑个人资料</router-link>
        </span>
        <div class="tools" v-show="!isOwner">
          <!-- follow-at  no-follow-at    {{followUserId?关注:取消关注}}-->
          <a
            href="javascript:;"
            class="follow-at"
            :calss="{ 'no-follow-at': userInfo.isFollowing }"
            @click="toggleHandler()"
          >
            {{ userInfo.isFollowing ? "已关注" : "+关注" }}
          </a>
        </div>
      </div>

      <ul class="user-more-info">
        <li>
          <div>
            <span>关注</span>
            <strong>{{ userInfo.following_len }}</strong>
          </div>
        </li>
        <li>
          <div>
            <span>粉丝</span>
            <strong>{{ userInfo.follows_len }}</strong>
          </div>
        </li>
        <li>
          <div>
            <span>收藏</span>
            <strong>{{ userInfo.collections_len }}</strong>
          </div>
        </li>
        <li>
          <div>
            <span>发布菜谱</span>
            <strong>{{ userInfo.work_menus_len }}</strong>
          </div>
        </li>
      </ul>
    </div>
    <!-- v-model="activeName" -->
    <el-tabs class="user-nav" v-model="activeName" @tab-click="tabClickHandler">
      <el-tab-pane label="作品" name="works"></el-tab-pane>
      <el-tab-pane label="粉丝" name="fans"></el-tab-pane>
      <el-tab-pane label="关注" name="following"></el-tab-pane>
      <el-tab-pane label="收藏" name="collection"></el-tab-pane>
    </el-tabs>
    <div class="user-info-show">
      <!-- 作品 & 收藏 布局 -->
      <!-- <menu-card :margin-left="13"></menu-card> -->
      <!-- 粉丝 & 关注 布局 -->
      <!-- <Fans></Fans> -->
      <!--:info="list"传的是数据 :activeName="activeName" 二级路由-->
      
      <router-view :info="list" :activeName="activeName"></router-view>
    </div>
  </div>
</template>
<script>
import {
  userInfo,
  toggleFollowing,
  getMenus,
  following,
  fans,
  collection,
} from "@/service/api";
//封装的请求方法
const getOtherInfo = {
  async works(params) {
    let data = (await getMenus(params)).data;
    data.flag = "works";
    return data;
  },
  async following(params) {
    let data = (await following(params)).data;
    data.flag = "following";
    return data;
  },
  async fans(params) {
    let data = (await fans(params)).data;
    data.flag = "fans";
    return data;
  },
  async collection(params) {
    let data = (await collection(params)).data;
    data.flag = "collection";
    return data;
  },
};
export default {
  name: "Space",
  data() {
    return {
      userInfo: {},
      isOwner: false,
      getMenus: [],
      activeName: "works",
      list: [],
    };
  },
  watch: {
    $route: {
      async handler(item) {
        // 入则id
        let { userId } = item.query;
        //先判断是不是空,在判断是不是自己的userId 
      // deep:true
        this.isOwner = !userId || userId === this.$store.state.userInfo.userId;
        // console.log(this.isOwner);
        if (!userId) {
          this.userInfo = this.$store.state.userInfo;
        } else {
          const data = await userInfo({ userId });
          this.userInfo = data.data;
        }
        this.getInfo();
      },
      immediate: true,
    },
  },
  methods: {
    async getInfo() {
      var data = await getOtherInfo[this.activeName]({ userId: this.userInfo.userId });
      // 问题二:切换tab过快时,依然报错key重复。并且数据显示不正常
      // 原因:因为ajax返回数据 快慢的问题,显示的最后一次ajax返回的数据
      // 解决:在请求中定义一个标识,在返回的数据中添加标识,如果返回的数据和当前的标识相同,再渲染
      if (this.activeName === data.flag) {
        this.list = data.list;
        console.log(this.list);
      }
    },
    async toggleHandler() {
      await toggleFollowing({ followUserId: this.userInfo.userId }).then((item) => {
        //因为关注后,要更新的数据还有粉丝,所以整体赋值数据
        this.userInfo = item.data;
      });
    },
    //点击切换tab
    tabClickHandler() {
      // 问题1:因为各个二级路由接收的手段,全是info ,所有会造成数据重复。
      // 解决:第一次保护数据到数组中时,没有问题,所以,每次保存前,都清空一下数组
      this.$router.push({
        name: this.activeName,
        query: {
          ...this.$route.query,
        },
      });
    },
  },
};
</script>

<style lang="stylus">

MenuList

<template>
  <div class="menu-list">
    <div class="info-empty" v-show="activeName=='works'&&info.length==0" >
      <div>
        <p>私房菜不要偷偷享用哦~~制作成菜谱与大家分享吧!</p>
        <a href="">发布菜单</a>
      </div>
    </div>
    <div class="info-empty" v-show="activeName=='collection'&&info.length==0">
      <div>
        <p>还没有收藏任何的菜谱,去搜自己喜欢的菜谱,收藏起来吧。</p>
        <a href="">菜谱大全</a>
      </div>
    </div>
    <menu-card :margin-left="13"  :info="info"></menu-card>
  </div>
  <!--  -->
</template>
<script>
import MenuCard from "@/components/menu-card.vue";
export default {
  components: { MenuCard },
  props: {
    info: {
      type: Array,
      default: () => {},
    },
    activeName:{

      type: String,
      default:"works",
    }
  },
};
</script>

fans

<template>
  <div class="fans">
    <div class="info-empty">
      <div>
        <p v-show="activeName=='fans'&&info.length==0">还没有被关注哦!多发布菜谱,更容易被找到。</p>
        <p v-show="activeName=='following'&&info.length==0">还没有关注别人哦!可以预览菜谱,找到别人</p>
      </div>
    </div>
    <ul class="fans clearfix">
      <router-link to="" tag="li" v-for="(item, index) in info" :key="index">
        <a href="javascript:;" class="img"> <img :src="item.avatar" /></a>
        <div class="c">
          <strong class="name">
            <router-link
              :to="{ path: '/space', query: { userId: item.userId } }"
              tag="em"
              >{{ item.name }}</router-link
            >
          </strong>
          <em class="info">
            <span>粉丝:</span> {{ item.follows_len }} |   <span>关注:</span
            >{{ item.following_len }}
          </em>
          <em class="info"><span>简介:</span> {{item.sign? item.sign: "这个人太懒啦!还没有介绍自己"}}</em>
        </div>
      </router-link>
    </ul>
  </div>
</template>

如果一直报这个

在这里插入图片描述
可以在router文件下的index.js,export default router前面写入



const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
  return originalPush.call(this, location).catch(err => err)
}
export default router;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值