开始

开头头部的组件。包括背景墙,下面是头像,第三行是昵称和 性别年龄。 第四行是关注。
image.png
最外层一个view组件,然后里面是一个背景图。在背景图的下面是view包裹的头像。

背景图的文件夹:
D:\wjw\学习中\uni-app\网易云课堂 - uni-app实战仿糗事百科app开发\糗事\课时114.个人空间头部组件开发\bgimg\

背景图和头像。
image.png

  1. <view>
  2. <!-- 背景图 + 用户基本信息 -->
  3. <view class="user-space-head">
  4. <image src="../../static/bgimg/1.jpg" mode="widthFix" lazy-load="true"></image>
  5. <view class="user-space-head-info">
  6. <image src="../../static/demo/userpic/11.jpg" mode="widthFix" lazy-load="true"></image>
  7. </view>
  8. </view>
  9. </view>

引入性别和年龄的组件
image.png

image.png

  1. import tagSexAge from '@/components/common/tag-sex-age.vue';
  2. components:{
  3. tagSexAge
  4. },

昵称后面是年龄和性别。
image.png

  1. <view class="">
  2. 昵称<tag-sex-age sex="20" age="0"></tag-sex-age>
  3. </view>

image.png

  1. <view class="icon iconfont icon-zengjia">
  2. 关注
  3. </view>

单独加个样式
image.png

  1. <view class="icon iconfont icon-zengjia user-space-head-btn">
  2. 关注
  3. </view>

先写一些公共的间距等。上下15的外边距
image.png

  1. .user-spaace-margin{
  2. margin: 15upx 0;
  3. }

图片肯定是全屏的。
image.png
让背景图 垂直,水平居中
image.png
水平 垂直居中,并且是column布局
image.png

  1. <!-- 背景图 + 用户基本信息 -->
  2. <view class="user-space-head u-f-ajc">
  3. <image src="../../static/bgimg/1.jpg" mode="widthFix" lazy-load="true"></image>
  4. <view class="user-space-head-info u-f-ajc u-f-column">
  5. <image src="../../static/demo/userpic/11.jpg" mode="widthFix" lazy-load="true"></image>
  6. <view class="">
  7. 昵称<tag-sex-age sex="20" age="0"></tag-sex-age>
  8. </view>
  9. <view class="icon iconfont icon-zengjia user-space-head-btn">
  10. 关注
  11. </view>
  12. </view>
  13. </view>

image.png

  1. .user-space-head{
  2. position: relative;
  3. height: 500upx;
  4. overflow: hidden;
  5. }

头像
image.png

  1. .user-space-head-info{
  2. position: absolute;
  3. top: 150upx;
  4. }
  5. .user-space-head-info>image{
  6. width: 150upx;
  7. height: 150upx;
  8. border-radius: 100%;
  9. }

首先是给昵称加点外边距
image.png

image.png

  1. <view class="user-spaace-margin">
  2. 昵称<tag-sex-age sex="20" age="0"></tag-sex-age>
  3. </view>
  4. <view class="icon iconfont icon-zengjia user-space-head-btn user-spaace-margin">
  5. 关注
  6. </view>

昵称的样式
image.png

  1. .user-space-head-info>view:first-of-type{
  2. color: #FFFFFF;
  3. font-size: 35upx;
  4. font-weight: bold;
  5. text-shadow: 2upx 2upx 10upx #333333;
  6. }

水平居中 flex布局。这样昵称和性别的组件就会在一行上。
image.png
关注按钮
吸取黄色
image.png

边框色和背景色一致,
image.png
上下内边距为0
image.png

  1. .user-space-head-btn{
  2. background:#FFE933;
  3. color: #333333;
  4. border: 1upx solid #FFE933;
  5. padding: 0 15upx;
  6. border-radius: 10upx;
  7. }

image.png
性别和年龄写反了
image.png

  1. <view class="user-spaace-margin u-f-ajc">
  2. 昵称<tag-sex-age sex="0" age="20"></tag-sex-age>
  3. </view>

关注按钮有点大了。
image.png

image.png

  1. .user-space-head-btn{
  2. background:#FFE933;
  3. color: #333333;
  4. border: 1upx solid #FFE933;
  5. padding: 0 15upx;
  6. font-size: 28upx;
  7. border-radius: 10upx;
  8. }

image.png
已关注的状态。背景色去掉。
image.png

  1. .active{
  2. background: none;
  3. }

image.png

  1. .active{
  2. background: none;
  3. color: #FFFFFF;
  4. border: 1upx solid #FFFFFF;
  5. }

image.png
已关注,加好不应该出现。
image.png

构造data

完整的背景图 路径用计算属性来显示
image.png

  1. userinfo:{
  2. bgimg:1
  3. }
  4. computed:{
  5. getBgImg(){
  6. return '../../static/bgimg/'+this.userinfo.bgimg+'.jpg';
  7. }
  8. },

image.png

  1. <view class="user-space-head u-f-ajc">
  2. <image :src="getBgImg" mode="widthFix" lazy-load="true"></image>
  3. <view class="user-space-head-info u-f-ajc u-f-column">
  4. <image :src="userinfo.userpic" mode="widthFix" lazy-load="true"></image>
  5. <view class="user-spaace-margin u-f-ajc">
  6. {{userinfo.username}}<tag-sex-age sex="0" age="20"></tag-sex-age>
  7. </view>
  8. <view class="icon iconfont icon-zengjia user-space-head-btn user-spaace-margin active">
  9. 关注
  10. </view>
  11. </view>
  12. </view>

image.png

image.png

  1. return {
  2. userinfo:{
  3. bgimg:1,
  4. userpic:'../../static/demo/userpic/11.jpg',
  5. username:'昵称',
  6. sex:0,
  7. age:20,
  8. isguanzhu:false
  9. }
  10. }

没有关注的时候才显示加号的图标。
image.png

  1. <!-- 背景图 + 用户基本信息 -->
  2. <view class="user-space-head u-f-ajc">
  3. <image :src="getBgImg" mode="widthFix" lazy-load="true"></image>
  4. <view class="user-space-head-info u-f-ajc u-f-column">
  5. <image :src="userinfo.userpic" mode="widthFix" lazy-load="true"></image>
  6. <view class="user-spaace-margin u-f-ajc">
  7. {{userinfo.username}}<tag-sex-age :sex="userinfo.sex" :age="userinfo.age"></tag-sex-age>
  8. </view>
  9. <view class="icon iconfont icon-zengjia user-space-head-btn user-spaace-margin active">
  10. {{userinfo.isguanzhu?'已关注':'关注'}}
  11. </view>
  12. </view>
  13. </view>

关注事件

取反
image.png

  1. methods: {
  2. guanzhu(){
  3. this.userinfo.isguanzhu=!this.userinfo.isguanzhu;
  4. }
  5. }

image.png

image.png

背景墙点击事件

可以上面那种单独一行的写法。 也可以用if else的方法
image.png

image.png

image.png

赋值
image.png

  1. // 切换背景
  2. changeBgImg(){
  3. let no = parseInt(this.userinfo.bgimg);
  4. // if(no<4){
  5. // no++;
  6. // }else{
  7. // no=1;
  8. // }
  9. this.userinfo.bgimg = no<4?++no:1;
  10. },

添加上点击事件
image.png

  1. @tap.stop="changeBgImg"

点击背景图切换
image.png

image.png

这两个点击事件 目前是单独的还不需要阻止冒泡。
image.png
都加上冒泡的阻止事件,也不受影响
image.png

  1. <view>
  2. <!-- 背景图 + 用户基本信息 -->
  3. <view class="user-space-head u-f-ajc">
  4. <image :src="getBgImg" mode="widthFix" lazy-load="true"
  5. @tap.stop="changeBgImg"></image>
  6. <view class="user-space-head-info u-f-ajc u-f-column">
  7. <image :src="userinfo.userpic" mode="widthFix" lazy-load="true"></image>
  8. <view class="user-spaace-margin u-f-ajc">
  9. {{userinfo.username}}<tag-sex-age :sex="userinfo.sex" :age="userinfo.age"></tag-sex-age>
  10. </view>
  11. <view class="icon iconfont user-space-head-btn user-space-margin"
  12. :class="[userinfo.isguanzhu?'active':'icon-zengjia']" @tap.stop="guanzhu">
  13. {{userinfo.isguanzhu?'已关注':'关注'}}
  14. </view>
  15. </view>
  16. </view>
  17. </view>

封装组件

image.png

image.png

整块html内容和css剪切到组件内

这个是全局的css可以不用剪切过去。
image.png

image.png

  1. <style scoped>
  2. .user-space-head{
  3. position: relative;
  4. height: 500upx;
  5. overflow: hidden;
  6. }
  7. .user-space-head>image{
  8. width: 100%;
  9. }
  10. .user-space-head-info{
  11. position: absolute;
  12. top: 150upx;
  13. }
  14. .user-space-head-info>image{
  15. width: 150upx;
  16. height: 150upx;
  17. border-radius: 100%;
  18. }
  19. /* 昵称 */
  20. .user-space-head-info>view:first-of-type{
  21. color: #FFFFFF;
  22. font-size: 35upx;
  23. font-weight: bold;
  24. text-shadow: 2upx 2upx 10upx #333333;
  25. }
  26. .user-space-head-btn{
  27. background:#FFE933;
  28. color: #333333;
  29. border: 1upx solid #FFE933;
  30. padding: 0 15upx;
  31. font-size: 28upx;
  32. border-radius: 10upx;
  33. }
  34. .active{
  35. background: none;
  36. color: #FFFFFF;
  37. border: 1upx solid #FFFFFF;
  38. }
  39. </style>

image.png
因为不能直接修改传递过来的属性值,所以用一个值去接收 ,再修改。
image.png

image.png

image.png

把事件都复制过来
image.png

image.png
主要这里的isguanzhu。就是调用自己组件内部的了。并不是userInfo对象的内的属性值。
image.png

引入的子组件一块复制进来。
image.png

使用组件

image.png

  1. <user-space-head :userinfo="userinfo"></user-space-head>
  2. import userSpaceHead from '@/components/user-space/user-space-head.vue';
  3. components:{
  4. userSpaceHead
  5. },

image.png

本节代码

user-space-head组件

  1. <template>
  2. <view class="user-space-head u-f-ajc">
  3. <image :src="getBgImg" mode="widthFix" lazy-load="true"
  4. @tap.stop="changeBgImg"></image>
  5. <view class="user-space-head-info u-f-ajc u-f-column">
  6. <image :src="userinfo.userpic" mode="widthFix" lazy-load="true"></image>
  7. <view class="user-spaace-margin u-f-ajc">
  8. {{userinfo.username}}<tag-sex-age :sex="userinfo.sex" :age="userinfo.age"></tag-sex-age>
  9. </view>
  10. <view class="icon iconfont user-space-head-btn user-space-margin"
  11. :class="[isguanzhu?'active':'icon-zengjia']" @tap.stop="guanzhu">
  12. {{isguanzhu?'已关注':'关注'}}
  13. </view>
  14. </view>
  15. </view>
  16. </template>
  17. <script>
  18. import tagSexAge from '@/components/common/tag-sex-age.vue';
  19. export default{
  20. components:{
  21. tagSexAge
  22. },
  23. props:{
  24. userinfo: Object
  25. },
  26. data(){
  27. return {
  28. isguanzhu: this.userinfo.isguanzhu
  29. }
  30. },
  31. computed:{
  32. getBgImg(){
  33. return '../../static/bgimg/'+this.userinfo.bgimg+'.jpg';
  34. }
  35. },
  36. methods: {
  37. // 切换背景
  38. changeBgImg(){
  39. let no = parseInt(this.userinfo.bgimg);
  40. // if(no<4){
  41. // no++;
  42. // }else{
  43. // no=1;
  44. // }
  45. this.userinfo.bgimg = no<4?++no:1;
  46. },
  47. // 关注事件
  48. guanzhu(){
  49. this.isguanzhu=!this.isguanzhu;
  50. }
  51. }
  52. }
  53. </script>
  54. <style scoped>
  55. .user-space-head{
  56. position: relative;
  57. height: 500upx;
  58. overflow: hidden;
  59. }
  60. .user-space-head>image{
  61. width: 100%;
  62. }
  63. .user-space-head-info{
  64. position: absolute;
  65. top: 150upx;
  66. }
  67. .user-space-head-info>image{
  68. width: 150upx;
  69. height: 150upx;
  70. border-radius: 100%;
  71. }
  72. /* 昵称 */
  73. .user-space-head-info>view:first-of-type{
  74. color: #FFFFFF;
  75. font-size: 35upx;
  76. font-weight: bold;
  77. text-shadow: 2upx 2upx 10upx #333333;
  78. }
  79. .user-space-head-btn{
  80. background:#FFE933;
  81. color: #333333;
  82. border: 1upx solid #FFE933;
  83. padding: 0 15upx;
  84. font-size: 28upx;
  85. border-radius: 10upx;
  86. }
  87. .active{
  88. background: none;
  89. color: #FFFFFF;
  90. border: 1upx solid #FFFFFF;
  91. }
  92. </style>

user-space页面

  1. <template>
  2. <view>
  3. <!-- 背景图 + 用户基本信息 -->
  4. <user-space-head :userinfo="userinfo"></user-space-head>
  5. </view>
  6. </template>
  7. <script>
  8. import userSpaceHead from '@/components/user-space/user-space-head.vue';
  9. export default {
  10. components:{
  11. userSpaceHead
  12. },
  13. data() {
  14. return {
  15. userinfo:{
  16. bgimg:1,
  17. userpic:'../../static/demo/userpic/11.jpg',
  18. username:'昵称',
  19. sex:0,
  20. age:20,
  21. isguanzhu:false
  22. }
  23. }
  24. },
  25. methods: {
  26. }
  27. }
  28. </script>
  29. <style>
  30. .user-spaace-margin{
  31. margin: 15upx 0;
  32. }
  33. </style>

结束