IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue项目美食杰--个人信息详情 -> 正文阅读

[JavaScript知识库]vue项目美食杰--个人信息详情

? ? ? ? ? 美食杰项目目前已经进行到白热化阶段,我呢是感觉越写越有劲,越写越有意思了,对于一个开发者而言,最开心的事莫过于写出来一些满意的效果了吧。

? ? ? ? 今日分享接上之前个人信息页,前面已经说过了上半部分,今天分享的就是下半部分的功能(以他人空间为实例,自己空间大致一样),大致东西不是很多,但还是那两句老话没注意细节,上图

? ?

?

?今天的任务就是上面两张图中,我画框框的部分的功能和细节的处理。。。

大致介绍:

1.首先tab切换实现上面tab功能,用二级路由来实现。

2.根据路由的切换来渲染不同的数据到相同的模板中。

tab切换

首先得配置路由,使得进入个人空间时展示默认组件,这里使用到路由重定向,然后配置二级路由,可以在tab切换时变换不同组件:

{
            path:'/space',
            name:'space',
            component:() => import ('@/views/user-space/space'),
            redirect:'/space/works',
            children:[
                {
                    path:'works',
                    name:'works',
                    component: () => import('@/views/user-space/menu-list'),
                    meta: {
                        login: true
                    }
                },
                {
                    path: 'fans',
                    name: 'fans',
                    meta: {
                        login: true
                    },
                    component: () => import('@/views/user-space/fans')
                },
                {
                    path: 'following',
                    name: 'following',
                    meta: {
                        login: true
                    },
                    component: () => import('@/views/user-space/fans')
                },
                {
                    path: 'collection',
                    name: 'collection',
                    meta: {
                        login: true
                    },
                    component: () => import('@/views/user-space/menu-list')
                },

            ]
        },

此时展示默认组件是我的作品组件。此时路由信息显示为

?因为需要在页面加载时初始化一些数据,因此需要使用到watch属性来监听路由的变化,第一个观察自己还是他人空间,第二个加载默认二级路由组件

watch:{
      $route:{
        async handler(){
            let {userId} = this.$route.query
//这里用路由参数来判断是自己还是别人
            this.isMyself = !userId || userId === this.$store.state.userInfo.userId
//根据主人采取不同的数据获取方式
            if(this.isMyself){
                this.userInfo = this.$store.state.userInfo
            }else{
                 const data = await userInfo({userId})
                 this.userInfo = data.data
            }
//将路由上面二级路由渲染到页面
            this.activeName = this.$route.name
            this.getInfo()
         }, 
//将自动开启
         immediate:true
      }
  },

?这里采取element-ui来实现具体的tab切换,利用v-model获取切换的值,再来根据路由切换二级组件,由此,名字和路由的路径相同的好处可见一斑

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

这里的点击事件是为了将名字和路由结合,用到了编程式导航,但是并不是简简单单的将名字给到路由就好,因为我们进入别人空间这样操作的时候,会将userId覆盖掉,根据之前的逻辑,这样会导致跳入自己的空间,因此在编程式导航中还需要将query参数一起放入

 tabClickHandler(){
        this.$router.push({
          name:this.activeName,
          query:{...this.$route.query}
        })
      }

接下来就是模块的展示,根据进入的路由的不同,切换到不同的组件之内,请求不同的数据,渲染模板,

这一块定义在实例之外,目的是简化逻辑处理,可以根据不同的需求来请求不同的数据

const getOtherInfo = {
     async works(params){
       return (await getMenus(params)).data
     },
     async following(params){
       return (await following(params)).data
     },
     async fans(params){
       return (await fans(params)).data
     },
     async collection(params){
       return (await collection(params)).data
     }
}

这里就是数据请求模块,根据tab的切换值来请求上面不同的数据,从而渲染不同模块,这里的调用实在watch中执行?

 async getInfo(){
          let data = await getOtherInfo[this.activeName]({userId:this.userInfo.userId})
          this.data = data.list
          console.log(data);
     },

说明:作品和收藏结构相同,粉丝和关注结构相同,因此可以复用统一模板。

因为所有板块都是使用router-view来渲染,因此可以通过router-view将数据传递给不同模块,来达到渲染的目的。

   <div class="user-info-show">
      <!-- 作品 & 收藏 布局 -->
      <!-- <menu-card :margin-left="13"></menu-card> -->
      <!-- 粉丝 & 关注 布局 -->
      <!-- <Fans></Fans> -->
      <router-view :info='data' :activeName='activeName'></router-view>
    </div>

在粉丝模块中接收参数,info是数据,activeName是名称

export default {
	props:{
        info:{
			type:Array,
			default:[]
		},
		activeName:{
			type:String,
			default:''
		}
	}
}

在粉丝模块中渲染数据

<ul class="fans clearfix">
			<router-link :to="{name:'space',query:{userId:item.userId}}" tag="li" v-for="item in info" :key="item.userId">
				<a href="javascript:;" class="img">
				<img :src="item.avatar"></a>
				<div class="c">
					<strong class="name">
						<router-link :to="{name:'space',query:{userId:item.userId}}">{{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 class="info-empty" v-if="!info.length">
			<div>
				<p v-if='activeName == "fans"'>还没有被关注哦!多发布菜谱,更容易被找到。</p>
				<p v-if="activeName == 'following'">还没有关注别人哦!可以预览菜谱,找到别人</p>
			</div>
		</div>

同理,在作品模块中接收数据

 props: {
        info:{
          type:Array,
          default:[]
        },
        activeName:{
          type:String,
          default:''
        }
  }

根据数据来显示和隐藏提示信息

<div class="menu-list">
    <div class="info-empty" v-if='!info.length'>
			<div v-if='activeName == "works"'>
				<p>私房菜不要偷偷享用哦~~制作成菜谱与大家分享吧!</p>
        	<a href="">发布菜单</a>
			</div>
		</div>
    <div class="info-empty" v-if="!info.length">
			<div v-if="activeName == 'collection'">
				<p>还没有收藏任何的菜谱,去搜自己喜欢的菜谱,收藏起来吧。</p>
        <a href="">菜谱大全</a>
			</div>
		</div>

数据的渲染我这里使用了第三层模板,因此需要在此向下一级传递一次数据

  <menu-card :margin-left="13" :info='info'></menu-card>

在作品列表模板中接受数据,并根据数据和样式渲染数据即可

<el-row class="menu-card" type="flex" justify="start">
    <el-col
      style="flex:none" 
      :style="{'margin-left':marginLeft+'px'}"
      v-for="item in info" :key="item._id"
    >
      <el-card :body-style="{ padding: '0px' }" >
        <router-link :to="{name:'detail'}">
          <img :src="item.product_pic_url" class="image" style="width: 232px;height: 232px;">
          <div style="padding: 14px;" class="menu-card-detail">
            <strong>菜品名称:{{item.title}}</strong>
            <span>{{item.comments_len}} 评论</span>
            <router-link :to="{name:'space',query:{userId:item.userId}}" tag="em">
            作者:{{item.name}}
            </router-link>
          </div>
        </router-link> 
      </el-card>
    </el-col>   
  </el-row>

今天的分享就到此结束了,具体功能不是很难,逻辑思维也不是很绕,需要注意的是有些需要取反的细节请多多留意。。。

祝生活安好

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:11:30  更:2021-10-09 16:13:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:11:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码