Vue2.0PC官网0到1 | 造轮子之制作一个信息详情卡

383 阅读6分钟

最近在制作一个基于vue2.0的pc端官网,已经制作了一大半了才想起来可以把制作过程分享出来,于是就从今天刚做的入手吧,后续会把前面已经完成的部分补上,等项目完成后会进行开源。

下面正式开始吧!

一、需求

基于vue2.0制作一个展示详情的组件,包括图片、标题和具体介绍。

二、效果展示

image.png

三、开始制作

3.1 基础布局

<div class="item">
  <div class="item_head">
 </div>
 <div class="item_text"></div>
</div>

整个容器分为上下两个div,上部分‘item_head’包含了图片和标题,下部分‘item_text’为具体介绍。 首先我们先定义一下容器的样式,这里使用 [rem] 为单位(当然也可以自己定义):

.item{
  padding: 2rem 0;
  width: 100%;
  height: 55rem;
  background: rgba(211, 219, 220, 0.147);
}

3.2 基础样式

3.2.1 基本布局

有了容器,接下来我们就要来进行布局,首先将容器分为上下两个部分,分别对应着head和text,效果如下:

image.png

.item_head{
  width: 100%;
  height: 65%;
  position: relative; // 由于后续还需要在里面进行布局,先设置position,以下同理
  background: orange;
}
.item_text{
  width: 70%;
  height: 35%;
  background: pink;
  margin: 0 auto;
  border-radius: 2rem;
  position: relative;
}

3.2.2 head 布局

布局完基本样式,就要进行head部分的布局,这里我们需要在head中实现三个效果,分别是 图片、贯穿图片的横线 以及 标题:

<div class="item_head">
      <span class="head_line"></span>
      <div class="head_image">
          <img src="xxx.png" alt=""> 
      </div>
          <div class="head_title">标题</div>
    </div>

首先,来制作贯穿图片的这条横线,实际上可以看做一个高度为50%的盒子的下边框,样式如下:

.head_line{
  width: 100%;
  height: 50%;
  position: absolute;
  box-sizing: border-box;
  border-bottom: 0.4rem solid;
  border-color: rgb(115, 151, 155);
}

效果:

image.png

图片框和title的制作相对简单,给图片加上链接,写入标题,更换好看的背景颜色,顺便给图片添加上hover后放大的动画:

.head_image{
  width: 25%;
  height: 80%;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 15%;
  border: 0.4rem solid;
  border-color: rgb(115, 151, 155);
  border-radius: 2rem;
  overflow: hidden;
}
.head_image img{
  width: 100%;
  height: 100%;
  cursor: pointer;
  transform: scale(1);
  transition: all 1s ease-in-out;
}
.head_image img:hover{
  transform: scale(1.2);
}
.head_title{
  font-size: 3.5rem;
  font-weight: 800;
  position: absolute;
  top: 75%;
  transform: translate(-50%,-100%);
  left: 65%;
}

效果如下:

CPT2109091640-1362x490.gif

此时基本完成布局,接下来就是将详细介绍填入text框内。当然,为了美观,也需要对text进行样式布局:

.item_text{
  width: 70%;
  height: 35%;
  background: rgb(223, 241, 243);
  margin: 0 auto;
  border-radius: 2rem;
  display: flex; // flex布局,让文本盒子居中
  align-items: center;
  justify-content: center;
}
.item_text article{
  width: 90%;
  height: 12rem;
  font-size: 2rem;
  line-height: 3rem;
  letter-spacing: 0.1rem;
  cursor: pointer;
  display: -webkit-box; // 文字溢出显示 “...”
  overflow: hidden;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
}

布局如下:

<template>
  <div class="item">
    <div class="item_head">
      <span class="head_line"></span>
      <div class="head_image">
        <img src="../../public/case/zzy.png" alt="">
      </div>
      <div class="head_title">崇明岛紫竹园</div>
    </div>
    <div class="item_text">
      <article title="崇明岛紫竹园是由中国500强企业通州建总集团有限公司投资开发,项目坐落于崇明岛(南通·海门)永隆路与万年路交汇处,面朝月季花海,背靠海门永临汽渡,紧邻启东商业圈。项目占地49528平方米,总建筑面积77103平方米,绿化面积超35%。楼层均为6层电梯美宅,超2000元/平米精装,打造长三角最美精工洋房。">
        崇明岛紫竹园是由中国500强企业通州建总集团有限公司投资开发,项目坐落于崇明岛(南通·海门)永隆路与万年路交汇处,面朝月季花海,背靠海门永临汽渡,紧邻启东商业圈。项目占地49528平方米,总建筑面积77103平方米,绿化面积超35%。楼层均为6层电梯美宅,超2000元/平米精装,打造长三角最美精工洋房。
      </article>
      </div>
  </div>
</template>

其中,设置title内容其实是投机取巧的方式,为了便于溢出隐藏时,鼠标悬停可以看到完整的内容。

到这里,最基本的样式布局就完成了,最终效果如下:

image.png

到这里,我们只是完成了最基础的部分,要实现组件化,加下来才是重点!!

四、组件化之路

4.1 改造一下

这里也是真正利用到vue的地方,为了最大程度实现组件的可复用性,我们对该组件的高度、线条颜色(border-color)、文本背景(background)、图片和标题的水平位置(left)、以及图片、标题、详情介绍内容进行组件化定制。

先来看看改造后的布局吧:

<template>
  <div
      class="item"
      :style="{'height':itemStyle.itemHeight}"> //定义组件高度
    <div class="item_head">
      <span
        class="head_line"
        :style="{'borderColor':itemStyle.bdColor}" // 线条颜色
        ></span>
      <div
        class="head_image"
        :class="item.left?'':'image_right'" //图片水平位置
        :style="{'borderColor':itemStyle.bdColor}" // 图片框颜色
        >
          <img :src="item.imgUrl" alt="">
      </div>
      <div
        class="head_title"
        :class="item.left?'':'title_left'" // 标题水平位置
        >{{item.titile}}</div>
    </div>
    <div class="item_text"
        :style="{'backgroundColor':itemStyle.bgColor}">//文本框背景颜色
      <article :title="item.text">
        {{item.text}}
      </article>
      </div>
  </div>
</template>

<script>
  export default {
    name:"latestItem",
    data(){
      return{
        item:{
            imgUrl: "./case/zzy.png", // 图片地址
            titile: "崇明岛紫竹园",
            text: "崇明岛紫竹园是由中国500强企业通州建总集团有限公司投资开发,项目坐落于崇明岛(南通·海门)永隆路与万年路交汇处,面朝月季花海,背靠海门永临汽渡,紧邻启东商业圈。项目占地49528平方米,总建筑面积77103平方米,绿化面积超35%。楼层均为6层电梯美宅,超2000元/平米精装,打造长三角最美精工洋房。",
            left: false, // 图片是否水平靠左显示
          },
        itemStyle:{
          "itemHeight":"50rem", //组件高度
          "bdColor":"rgb(115, 151, 155)", //线条颜色
          "bgColor":"rgb(223, 241, 243)" //文本框背景色
        }
      }
    }
  }
</script>

其中 itemStyle 定义了组件的高度、线条颜色和文本框背景色(Css中需要设置默认值);

items 定义了组件图片地址、标题、内容、图片是否水平居左显示;

为了保证图片居左时,标题居右,图片居右时,标题居左,还需要增加 title_left 和 image_right 两个样式:

.image_right{
  left: 55%;
}
.title_left{
  left: 35%;
}

这里重点需要注意一下水平位置和颜色的动态绑定方式:

<div
:class="item.left?'':'image_right'" //图片水平位置 
:style="{'borderColor':itemStyle.bdColor}" // 图片框颜色
>
<script>
  export default {
    data(){
      return{
        item:{
            left: false,
            imgUrl: "./case/zzy.png",
          },
        itemStyle:{
          "bdColor":"rgb(115, 151, 155)",
        }
      }
    }
  }
</script>

水平位置的动态绑定由于需要判断传入的left值是否为true,因此采用三目运算符对class进行更新;

线条颜色(包括背景颜色)是固定的值,直接对style进行赋值即可。

此外,细心的朋友可以发现,imgUrl 在这个数据结构中发生了变化:

// 现在
<img :src="items.imgUrl" alt="">
<script>
  export default {
    data(){
      return{
        item:{
            imgUrl: "./case/zzy.png",
          }
        }
      }
    }
// 原来直接引用时
<img src="../../public/case/zzy.png" alt="">

这是因为我们将图片资源放在了pubic文件夹中,在json数据结构中引用,直接以“./”代表public目录。

image.png

至此,我们完成了组件化开发。但是,到这里就结束了吗?NO!!接下来要对数据进行抽离,现在我们是直接将数据写在了data中,企业开发中,我们都是获取数据进行渲染,自然不能是写死的数据了。

4.2 终极一步

itemStyle 和 item 未来将是由父组件传入,因此,本组件中只需要接收itemStyle 和 item两个参数即可。

<script>
  export default {
    name:"latestItem",
    props:['item','itemStyle']
  }
</script>

至此,组件化正式完成,接下来在父组件中引入该组件,父组件的基础结构这里就不进行赘述了。

假设上面封装的组件文件名为“latestItem.vue”,父组件代码如下:

<template>
  <div>
        <latestItem
          :itemStyle="itemStyle"
          v-for="(item,index) in items"
          :item="item"
          :key="index"
          ></latestItem>
  </div>
</template>

<script>
import data from '../api/info.json'
import latestItem from '../components/latestItem.vue';
  export default {
    name:"Latest",
    components:{
      latestItem
    },
    data(){
      return{
        itemStyle:{
          "itemHeight":"50rem",
          "bdColor":"rgb(115, 151, 155)",
          "bgColor":"rgb(223, 241, 243)"
        },
        item:[]
      }
    },
    created(){
      this.items = data.items
    }
  }
</script>

我们直接在父组件中定义 itemStyle ,并传给子组件。在父组件中请求后端接口获取数据,之后利用v-for进行渲染。这里为了方便演示,同样采用本地静态资源,数据在created时获取。数据结构如下:

  "items":[
    {
      "imgUrl": "./case/zzy.png",
      "titile": "崇明岛紫竹园",
      "text": "崇明岛紫竹园是由中国500强企业通州建总集团有限公司投资开发,项目坐落于崇明岛(南通·海门)永隆路与万年路交汇处,面朝月季花海,背靠海门永临汽渡,紧邻启东商业圈。项目占地49528平方米,总建筑面积77103平方米,绿化面积超35%。楼层均为6层电梯美宅,超2000元/平米精装,打造长三角最美精工洋房。",
      "left": false
    },
    {
      "imgUrl": "./case/dalw.png",
      "titile": "三亚·东岸蓝湾",
      "text": "东岸蓝湾由海南和鑫地产开发有限公司开发,位于三亚市吉阳区荔枝沟路社区公园特色夜市旁,总占地面积约为31000平方米,建筑面积为110000平方米,绿化率为43%,建设总户数为702户,规划车位数828个。",
      "left": true
    }
]

OK,完成!展示吧!

CPT2109091918-1275x814.gif

下集预告

下一篇文章将为大家介绍如何利用纯Css制作一个提示鼠标滚动的组件,希望不会鸽太久....先看效果吧~

CPT2109091926-235x159.gif