美文网首页Vuevue实践大前端
vue实践二:页面区块化与组件封装

vue实践二:页面区块化与组件封装

作者: 左木北鱼 | 来源:发表于2018-12-12 22:45 被阅读0次

本文示例代码:查看源码    查看运行
参考书籍:《Vue2 实践揭秘》第四章:页面区块化与组件封装

本文代码从之前文章:vue-router:路由与页面间导航开始

一、文章目的

1、简单了解并学习vue页面区块化与组件的封装;
2、学习了解常用vue插件:

二、需求梳理

效果图1
效果图2

逻辑分析

  • 当前页面是Home.vue,我们在src/components新建home文件夹存放当前页专用组件;

布局分析

  • 热门推荐:Slider.vue
  • 快讯:Announcement.vue
  • 新书上架:BookList.vue
  • 编辑推荐:BookList.vue
  • 图书弹层:Dialog.vue

三、书写代码

  1. 搭架子
  • components下新建home文件夹,并新建四个vue组件;
  • Home.vue文件中引入组件,并在页面中占位;
    搭架子
  1. 热门推荐图片轮播实现:Swiper.vue
  • 2.1 安装依赖包


    安装swiper
  • 2.2 初始化 Swiper.vue
    • 这里图片使用图片占用官网 或者 这里
    • 使用ref属性定位,替换css选择器
    • 在js代码前加注释:// eslint-disable-next-line,阻止Do not use 'new' for side effects报错
<template>
  <div class="swiper-container" ref="slider">
    <div class="swiper-wrapper">
      <div class="swiper-slide"><img src="http://via.placeholder.com/300x120?text=1" alt=""></div>
      <div class="swiper-slide"><img src="http://via.placeholder.com/300x120?text=2" alt=""></div>
      <div class="swiper-slide"><img src="http://via.placeholder.com/300x120?text=3" alt=""></div>
    </div>
    <div class="swiper-pagination" ref="pagination"></div>
  </div>
</template>
<script>
import Swiper from 'swiper'
import 'swiper/dist/css/swiper.css'
export default {
  props: ['slides'],
  mounted () {
    this.swiperInit()
  },
  methods: {
    swiperInit () {
      // eslint-disable-next-line
      new Swiper(this.$refs.slider, {
        pagination: {
          el: this.$refs.pagination,
          clickable: true
        },
        spaceBetween: 0,
        centeredSliders: true,
        autoplay: {
          delay: 2000
        },
        autoplayDisabledOninteraction: true,
        initialSlide: 0,
        loop: true,
        speed: 900
      })
    }
  }
}
</script>
  • 2.3 父组件Home.vue传递数据
    • 修改Home.vueSwiper.vue
    • 注意:通过接口获取数据时,组件引用加v-if判断,防止数据未加载完页面渲染造成bug
      数据传递
  • 2.4 实现效果


    效果
  1. 快讯实现:Announcement.vue
    快讯
  2. 新书上架和编辑推荐:BookList.vue
  • 4.1 初始化BookList.vue
<template>
  <div class="book-list">
    <div class="header">
      <div class="heading">最新更新</div>
      <div class="more">更多...</div>
    </div>
    <div class="book-item">
      <div class="book">
        <div class="cover"><img src="http://via.placeholder.com/100x150?text=1" alt=""></div>
        <div class="title">揭开数据真相:从小白到数据分析达人</div>
        <div class="author">Edward Zaccaro, Daniel Zaccaro</div>
      </div>
      <div class="book">
        <div class="cover"><img src="http://via.placeholder.com/100x150?text=1" alt=""></div>
        <div class="title">揭开数据真相:从小白到数据分析达人</div>
        <div class="author">Edward Zaccaro, Daniel Zaccaro</div>
      </div>
    </div>
  </div>
</template>
<script>
import './BookList.less'
export default {}
</script>

BookList.less

.book-list {
  margin: 0 14px;
  & > .header {
    display: table;
    width: 100%;
    border-bottom: 1px solid #efefef;

    & > .heading {
      display: table-cell;
      padding: 12px;
    }

    & > .more {
      display: table-cell;
      text-align: right;
      vertical-align: middle;
      font-size: 10px;
      color: #cccccc;
      padding-right: 14px;
    }
  }

  & .book-items {
    display: table;
    width: 100%;
    padding-top: 12px;
  }

  & .book {
    font-size: 10px;
    text-align: center;
    float: left;
    width: 33%;
    height: 207px;
    margin: 12px auto;
    cursor: pointer;
    & .cover {
    }

    & .title, & .authors {
      margin: 5px auto;
      width: 100px;
      text-overflow: ellipsis;
      overflow: hidden;
      white-space: nowrap;
    }

    & .authors {
      color: #898989;
      margin-top: 10px;
      text-align: left;
    }
  }
}
  • 4.2 父组件Home.vue传递数据

    • 更改Home.vueBookList.vue
    • 作者多个,加filters过滤器,用,拼接
      传递数据
  • 4.3 实现效果


    实现效果
  1. 弹出层:Dialog.vue
  • 5.1 Dialog.vue组件和Dialog.less
<template>
  <div class="dialog-wrapper" :class="{ 'open': is_open }">
    <div class="overlay" @click="close"></div>
    <div class="dialog">
      <!-- 头部及标题 -->
      <slot name="header"></slot>
      <!-- 内容区域 -->
      <slot></slot>
    </div>
  </div>
</template>
<script>
import './Dialog.less'
export default {
  data () {
    return {
      is_open: false
    }
  },
  methods: {
    open () {
      this.is_open = true
    },
    close () {
      if (this.is_open) {
        this.$emit('dialogClose')
      }
      this.is_open = false
    }
  }
}
</script>
.dialog-wrapper {
  &.open {
    display: block;
  }
  height: 100%;
  display: none;
  &>.overlay {
    background: rgba(0, 0, 0.3, 0.2);
    z-index: 1;
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
  }
  &>.dialog {
    z-index: 10;
    background: #fff;
    position: fixed;
    top: 24px;
    right: 24px;
    left: 24px;
    bottom: 24px;
    padding: 24px 14px;
    box-shadow: rgba(0, 0, 0, .8);
    & heading {
      padding: 12px;
    }
  }
}
  • 5.2 修改BookList.vue,添加点击事件@click="$emit('onBookSelect', book)"
    点击事件
  • 5.3 修改Home.vue,响应点击事件
    • book-list组件上添加@onBookSelect="preview($event)"响应BookList.vue的点击事件,并触发preview方法打开弹出层;
    • Dialog.vue@click="close"关闭弹层类似逻辑;
      Home.vue
  1. data数据改为接口获取
  • 6.1 安装vue-resource

    安装vue-resource
    • main.js中引入,并添加配置
      修改main.js
    • Home.vuecreated中通过vue-resource测试请求
      vue-resource
  • 6.2 安装axios

    image.png
    • main.js中引入
      修改main.js
    • Home.vuecreated中测试请求
      测试axios
  1. 没有正式的接口,下面通过mockjs拦截模拟接口请求
  • 7.1 安装mockjs
    image.png
  • 7.2 修改Home.vuedata
    image.png
  • 7.3 在src目录下新建api/home.json文件,加入json数据
{
  "slides": [
    { "id": 1, "img_url": "1.png" },
    { "id": 2, "img_url": "2.png" },
    { "id": 3, "img_url": "3.png" }
  ],
  "announcement": "今日上架的图书全部8折",
  "latestUpdated": [
    {
      "id": 1,
      "title": "揭开数据真相:从小白到数据分析达人",
      "authors": [ "Edward Zaccaro", "Daniel Zaccaro" ],
      "img_url": "http://via.placeholder.com/100x150?text=1"
    },
    {
      "id": 2,
      "title": "Android高级进阶",
      "authors": ["顾浩鑫"],
      "img_url": "http://via.placeholder.com/100x150?text=2"
    },
    {
      "id": 3,
      "title": "淘宝天猫电商运营与数据化选品完全手册",
      "authors": ["老夏"],
      "img_url": "http://via.placeholder.com/100x150?text=3"
    },
    {
      "id": 4,
      "title": "大数据架构详解:从数据获取到深度学习",
      "authors": ["朱洁", "罗华霖"],
      "img_url": "http://via.placeholder.com/100x150?text=4"
    },
    {
      "id": 5,
      "title": "Meteor全栈开发",
      "authors": ["杜亦舒"],
      "img_url": "http://via.placeholder.com/100x150?text=5"
    }
  ],
  "recommended": [
    {
      "id": 1,
      "title": "自己动手做大数据系统",
      "authors": ["张粤磊"],
      "img_url": "http://via.placeholder.com/100x150?text=1"
    },
    {
      "id": 2,
      "title": "智能硬件安全",
      "authors": ["刘建皓"],
      "img_url": "http://via.placeholder.com/100x150?text=2"
    },
    {
      "id": 3,
      "title": "实战数据库营销--大数据时代轻松赚钱之道(第2版)",
      "authors": ["罗安林"],
      "img_url": "http://via.placeholder.com/100x150?text=3"
    },
    {
      "id": 4,
      "title": "大数据思维--从掷骰子到纸牌屋",
      "authors": ["马继华"],
      "img_url": "http://via.placeholder.com/100x150?text=4"
    },
    {
      "id": 5,
      "title": "从零开始学数据营销",
      "authors": ["韩布韦"],
      "img_url": "http://via.placeholder.com/100x150?text=5"
    },
    {
      "id": 6,
      "title": "数据化营销",
      "authors": ["龚正", "吴治辉", "王伟", "崔秀龙", "闫建勇"],
      "img_url": "http://via.placeholder.com/100x150?text=6"
    }
  ]
}
  • 7.4 在src下新建mock.js,并在main.js中引入
    mock.js
import Mock from 'mockjs'
import HomePageData from '@/api/home.json'

let sliderImages = require.context('./assets/sliders', false, /\.(png|jpg|gif|svg)$/)
HomePageData.slides.forEach((slide) => {
  slide.img_url = sliderImages('./' + slide.img_url)
})

Mock.mock('/api/home', 'post', HomePageData)
Mock.mock('https://api.coindesk.com/v1/bpi/currentprice.json', 'get', HomePageData)
在main.js中添加mock.js
  • 7.5 在src/assets下新建slides文件夹,并加入三张图片
    slides图片
  • 7.6 通过mock拦截接口请求,给data数据重新赋值


    mock模拟接口
  • 7.7 实现效果


    效果图

结语:当前示例很简单,入门学习理清思路可以。

相关文章

  • vue实践二:页面区块化与组件封装

    本文示例代码:查看源码 查看运行参考书籍:《Vue2 实践揭秘》第四章:页面区块化与组件封装 本文代码从之前文章...

  • vue-router 路由

    组件化之后才能路由化 (一定要先安装路由) 单页面路由封装router.js mian.js中引用 App.vue...

  • vue周期函数

    1.vue中的组件 -vue中所有页面由组件组成-vue可以将公共的部分封装成组件在其他地方使用-App.vue是...

  • vue 星星评分组件

    一、组件(star.vue)代码 二、页面调用此组件( star.vue ):

  • vue 30分钟入门秘笈(二)——组件化开发

    1、组件模块化 header子组件,比如某个页面 header.vue footer子组件,比如某个页面 foot...

  • [Vue warn]: Error in mounted hoo

    写完第一个vue组件之后,第二个组件与之相似,所以在初始化vue单页面文件后对钩子函数mounted也进行了添加,...

  • vue

    1、什么是组件化、有什么好处、vue如何创建组件、vue组件之间如何通信 什么是组件化。任何一个页面我们都可以抽象...

  • 2018-09-18 vue第六章

    组件:组件可以扩展 HTML 元素,封装可重用的代码。组件是可复用的 Vue 实例,所以它们与 new Vue 接...

  • Vue组件

    定义 组件化开发指的是:根据封装的思想,把页面上可复用的UI结构封装为组件,从而方便项目的开发和维护。 vue是一...

  • Vue基础

    Vue简介 Vue是数据驱动组件,为现代化的Web页面而生,与ReactJS的中心思想一样,都是一切皆是组件。他是...

网友评论

    本文标题:vue实践二:页面区块化与组件封装

    本文链接:https://www.haomeiwen.com/subject/zsguhqtx.html