本文示例代碼:查看源碼 ?? 查看運(yùn)行
參考書(shū)籍:《Vue2 實(shí)踐揭秘》第四章:頁(yè)面區(qū)塊化與組件封裝
本文代碼從之前文章:vue-router:路由與頁(yè)面間導(dǎo)航開(kāi)始
一、文章目的
1池摧、簡(jiǎn)單了解并學(xué)習(xí)vue頁(yè)面區(qū)塊化與組件的封裝;
2嘱函、學(xué)習(xí)了解常用vue插件:
- 輪播圖插件:swiper炸站;
- 請(qǐng)求數(shù)據(jù)插件:vue-resource;
- 請(qǐng)求數(shù)據(jù)插件:axios抄沮、vue-axios省古;
- 數(shù)據(jù)模擬插件:mockjs
二粥庄、需求梳理
邏輯分析
- 當(dāng)前頁(yè)面是
Home.vue
,我們?cè)?code>src/components新建home
文件夾存放當(dāng)前頁(yè)專(zhuān)用組件豺妓;
布局分析
- 熱門(mén)推薦:
Slider.vue
- 快訊:
Announcement.vue
- 新書(shū)上架:
BookList.vue
- 編輯推薦:
BookList.vue
- 圖書(shū)彈層:
Dialog.vue
三惜互、書(shū)寫(xiě)代碼
- 搭架子
- 在
components
下新建home
文件夾,并新建四個(gè)vue組件琳拭; - 在
Home.vue
文件中引入組件训堆,并在頁(yè)面中占位;
- 熱門(mén)推薦
圖片輪播
實(shí)現(xiàn):Swiper.vue
-
2.1 安裝依賴(lài)包
- 2.2 初始化
Swiper.vue
<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
傳遞數(shù)據(jù)- 修改
Home.vue
和Swiper.vue
- 注意:通過(guò)接口獲取數(shù)據(jù)時(shí)权薯,組件引用加
v-if
判斷姑躲,防止數(shù)據(jù)未加載完頁(yè)面渲染造成bug
- 修改
-
2.4 實(shí)現(xiàn)效果
- 快訊實(shí)現(xiàn):
Announcement.vue
- 新書(shū)上架和編輯推薦:
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">揭開(kāi)數(shù)據(jù)真相:從小白到數(shù)據(jù)分析達(dá)人</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">揭開(kāi)數(shù)據(jù)真相:從小白到數(shù)據(jù)分析達(dá)人</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
傳遞數(shù)據(jù)- 更改
Home.vue
和BookList.vue
- 作者多個(gè),加
filters
過(guò)濾器盟蚣,用,
拼接
- 更改
-
4.3 實(shí)現(xiàn)效果
- 彈出層:
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">
<!-- 頭部及標(biāo)題 -->
<slot name="header"></slot>
<!-- 內(nèi)容區(qū)域 -->
<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
黍析,添加點(diǎn)擊事件@click="$emit('onBookSelect', book)"
- 5.3 修改
Home.vue
,響應(yīng)點(diǎn)擊事件-
book-list
組件上添加@onBookSelect="preview($event)"
響應(yīng)BookList.vue
的點(diǎn)擊事件屎开,并觸發(fā)preview
方法打開(kāi)彈出層阐枣; -
Dialog.vue
中@click="close"
關(guān)閉彈層類(lèi)似邏輯;
-
- 將
data
數(shù)據(jù)改為接口獲取
-
6.1 安裝
vue-resource
- 在
main.js
中引入奄抽,并添加配置
- 在
Home.vue
created中通過(guò)vue-resource
測(cè)試請(qǐng)求
- 在
-
6.2 安裝
axios
- 在
main.js
中引入
- 在
Home.vue
created中測(cè)試請(qǐng)求
- 在
- 沒(méi)有正式的接口蔼两,下面通過(guò)
mockjs
攔截模擬接口請(qǐng)求
- 7.1 安裝
mockjs
- 7.2 修改
Home.vue
data
- 7.3 在
src
目錄下新建api/home.json
文件,加入json數(shù)據(jù)
{
"slides": [
{ "id": 1, "img_url": "1.png" },
{ "id": 2, "img_url": "2.png" },
{ "id": 3, "img_url": "3.png" }
],
"announcement": "今日上架的圖書(shū)全部8折",
"latestUpdated": [
{
"id": 1,
"title": "揭開(kāi)數(shù)據(jù)真相:從小白到數(shù)據(jù)分析達(dá)人",
"authors": [ "Edward Zaccaro", "Daniel Zaccaro" ],
"img_url": "http://via.placeholder.com/100x150?text=1"
},
{
"id": 2,
"title": "Android高級(jí)進(jìn)階",
"authors": ["顧浩鑫"],
"img_url": "http://via.placeholder.com/100x150?text=2"
},
{
"id": 3,
"title": "淘寶天貓電商運(yùn)營(yíng)與數(shù)據(jù)化選品完全手冊(cè)",
"authors": ["老夏"],
"img_url": "http://via.placeholder.com/100x150?text=3"
},
{
"id": 4,
"title": "大數(shù)據(jù)架構(gòu)詳解:從數(shù)據(jù)獲取到深度學(xué)習(xí)",
"authors": ["朱潔", "羅華霖"],
"img_url": "http://via.placeholder.com/100x150?text=4"
},
{
"id": 5,
"title": "Meteor全棧開(kāi)發(fā)",
"authors": ["杜亦舒"],
"img_url": "http://via.placeholder.com/100x150?text=5"
}
],
"recommended": [
{
"id": 1,
"title": "自己動(dòng)手做大數(shù)據(jù)系統(tǒng)",
"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": "實(shí)戰(zhàn)數(shù)據(jù)庫(kù)營(yíng)銷(xiāo)--大數(shù)據(jù)時(shí)代輕松賺錢(qián)之道(第2版)",
"authors": ["羅安林"],
"img_url": "http://via.placeholder.com/100x150?text=3"
},
{
"id": 4,
"title": "大數(shù)據(jù)思維--從擲骰子到紙牌屋",
"authors": ["馬繼華"],
"img_url": "http://via.placeholder.com/100x150?text=4"
},
{
"id": 5,
"title": "從零開(kāi)始學(xué)數(shù)據(jù)營(yíng)銷(xiāo)",
"authors": ["韓布韋"],
"img_url": "http://via.placeholder.com/100x150?text=5"
},
{
"id": 6,
"title": "數(shù)據(jù)化營(yíng)銷(xiāo)",
"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)
- 7.5 在
src/assets
下新建slides
文件夾额划,并加入三張圖片
-
7.6 通過(guò)mock攔截接口請(qǐng)求,給data數(shù)據(jù)重新賦值
-
7.7 實(shí)現(xiàn)效果
結(jié)語(yǔ):當(dāng)前示例很簡(jiǎn)單档泽,入門(mén)學(xué)習(xí)理清思路可以俊戳。