系列文章目錄
Vue基礎篇一:編寫第一個Vue程式
Vue基礎篇二:Vue元件的核心概念
Vue基礎篇三:Vue的計算屬性與偵聽器
Vue基礎篇四:Vue的生命周期(秒殺案例實戰)
Vue基礎篇五:Vue的指令
Vue基礎篇六:Vue使用JSX進行動态渲染
Vue提高篇一:使用Vuex進行狀态管理
Vue提高篇二:使用vue-router實作靜态路由
Vue提高篇三:使用vue-router實作動态路由
Vue提高篇四:使用Element UI元件庫
Vue提高篇五:使用Jest進行單元測試
Vue提高篇六: 使用Vetur+ESLint+Prettier插件提升開發效率
Vue實戰篇一: 使用Vue搭建注冊登入界面
Vue實戰篇二: 實作郵件驗證碼發送
Vue實戰篇三:實作使用者注冊
Vue實戰篇四:建立多步驟表單
Vue實戰篇五:實作檔案上傳
Vue實戰篇六:表格渲染動态資料
Vue實戰篇七:表單校驗
Vue實戰篇八:實作彈出對話框進行互動
Vue實戰篇九:使用省市區級聯選擇插件
Vue實戰篇十:響應式布局
Vue實戰篇十一:父元件擷取子元件資料的正常方法
Vue實戰篇十二:多項選擇器的實際運用
Vue實戰篇十三:實戰分頁元件
Vue實戰篇十四:前端excel元件實作資料導入
Vue實戰篇十五:表格資料多選在實際項目中的技巧
Vue實戰篇十六:導航菜單
Vue實戰篇十七:用樹型元件實作一個知識目錄
Vue實戰篇十八:搭建一個知識庫架構
Vue實戰篇十九:使用printjs列印表單
Vue實戰篇二十:自定義表格合計
Vue實戰篇二十一:實戰Prop的雙向綁定
Vue實戰篇二十二:生成二維碼
Vue實戰篇二十三:卡片風格與清單風格的切換
Vue實戰篇二十四:分頁顯示Vue實戰篇二十五:使用ECharts繪制疫情折線圖Vue實戰篇二十六:建立動态儀表盤Vue實戰篇二十七:實作走馬燈效果的商品輪播圖Vue實戰篇二十八:實作一個手機版的購物車
文章目錄
- 系列文章目錄
- 一、背景
- 二、留言闆功能
- 三、留言闆搭建
- 3.1 留言區
- 3.2 釋出區
- 四、前端完整源碼
- 五、效果示範
一、背景
- 前兩周有位同學,在背景發私信,希望能實作一個簡易的留言闆,這周就帶領大家來進行實戰。

二、留言闆功能
- 本次實戰我們先模拟一個簡易的留言闆,主要模拟訪客的留言釋出與浏覽。
- 後續會提供後端管理者功能的實作。
三、留言闆搭建
3.1 留言區
- 我們用el-card元件來搭建留言展示塊
<el-card class="el-card-m">
<span class="el-card-m-content">{{ item.content }}</span>
<div />
<span class="el-card-m-nick-name">{{ item.nickName }} 送出于 {{ item.createTime }}</span>
</el-card>
– 用el-timeline時間線元件呈現留言區的時間資訊
<el-timeline infinite-scroll-disabled="disabled">
<div v-if="pagemessages.length > 0">
<el-timeline-item
v-for="(item, index) in pagemessages"
:key="index"
:timestamp="item.createDate"
placement="top"
>
<el-card class="el-card-m">
<span class="el-card-m-content">{{ item.content }}</span>
<div />
<span class="el-card-m-nick-name">{{ item.nickName }} 送出于 {{ item.createTime }}</span>
</el-card>
</el-timeline-item>
</div>
<div v-else>
<el-timeline-item placement="top">
<el-card class="el-card-m">
<p class="el-card-m-nick-name"> 沒有任何留言</p>
</el-card>
</el-timeline-item>
</div>
</el-timeline>
– 用分頁元件分解資料,翻頁浏覽
<el-pagination
background
:current-page="currentPage"
:page-size="pagesize"
layout="prev, pager, next"
:total="allmessages.length"
:hide-on-single-page="true"
@current-change="handleCurrentChange"
/>
3.2 釋出區
– 輸入昵稱
– 輸入留言内容
– 點選留言按鈕進行釋出
<div class="el-card-messages">
<el-input v-model="nickName" size="mini" class="message-nick-name">
<template slot="prepend">昵稱:</template>
</el-input>
<el-input
slot="prepend"
v-model="message"
type="textarea"
:rows="2"
class="message-text"
placeholder="輸入留言"
maxlength="200"
/>
<el-button
type="info"
round
class="submit-message"
size="mini"
@click="submitMessage"
>留言</el-button>
</div>
四、前端完整源碼
- 注意,本實戰并未與後端進行互動,資料隻在前端模拟展示
<template>
<div>
<el-card class="el-card-d" shadow="always">
<el-timeline infinite-scroll-disabled="disabled">
<div v-if="pagemessages.length > 0">
<el-timeline-item
v-for="(item, index) in pagemessages"
:key="index"
:timestamp="item.createDate"
placement="top"
>
<el-card class="el-card-m">
<span class="el-card-m-content">{{ item.content }}</span>
<div />
<span class="el-card-m-nick-name">{{ item.nickName }} 送出于 {{ item.createTime }}</span>
</el-card>
</el-timeline-item>
</div>
<div v-else>
<el-timeline-item placement="top">
<el-card class="el-card-m">
<p class="el-card-m-nick-name"> 沒有任何留言</p>
</el-card>
</el-timeline-item>
</div>
</el-timeline>
<el-pagination
background
:current-page="currentPage"
:page-size="pagesize"
layout="prev, pager, next"
:total="allmessages.length"
:hide-on-single-page="true"
@current-change="handleCurrentChange"
/>
</el-card>
<div class="el-card-messages">
<el-input v-model="nickName" size="mini" class="message-nick-name">
<template slot="prepend">昵稱:</template>
</el-input>
<el-input
slot="prepend"
v-model="message"
type="textarea"
:rows="2"
class="message-text"
placeholder="輸入留言"
maxlength="200"
/>
<el-button
type="info"
round
class="submit-message"
size="mini"
@click="submitMessage"
>留言</el-button>
</div>
</div>
</template>
<script>// 格式化時間函數
import { parseTime } from '@/utils/index'
export default {
data() {
return {
nickName: '',
message: '',
pagesize: 3,
currentPage: 1,
pagemessages: [],
allmessages: []
}
},
created() {
this.doQuery()
},
methods: {
// 模拟背景查詢
doQuery() {
const start = (this.currentPage - 1) * this.pagesize
const end = start + this.pagesize
for (var i = start; i < end; i++) {
if (i < this.allmessages.length) {
this.pagemessages.push(this.allmessages[i])
}
}
},
// 翻頁
handleCurrentChange(val) {
this.currentPage = val
this.pagemessages = []
this.doQuery()
},
// 送出留言
submitMessage() {
if (this.nickName === '' || this.nickName.replace(/(^\s*)|(\s*$)/g, '') === '') {
this.$message('請輸入昵稱')
return
}
if (this.message === '' || this.message.replace(/(^\s*)|(\s*$)/g, '') === '') {
this.$message('留言不能為空')
return
}
// 模拟儲存資料
var timestamp = Date.parse(new Date())
this.allmessages.push({ createTime: parseTime(timestamp), createDate: parseTime(timestamp, '{y}-{m}-{d}'), nickName: this.nickName, content: this.message })
this.nickName = ''
this.message = ''
// 翻頁到最後一頁
this.currentPage = Math.ceil(this.allmessages.length / this.pagesize, 0)
this.handleCurrentChange(this.currentPage)
}
}
}</script>
<style scoped>.el-card-d {
float: left;
margin-top: 20px;
margin-left: 10%;
width: 80%;
height: 500px;
background: rgb(252, 250, 250);
}
.el-card-m{
height: 100px;
}
.el-card-m-content{
display: block;
font-weight: bold;
}
.el-card-m-nick-name{
display: block;
font-size: x-small;
margin-top: 15px;
color: gray;
}
.el-card-messages {
float: left;
margin-top: 20px;
margin-left: 10%;
width: 70%;
}
.message-nick-name {
width: 50%;
}
.message-text {
margin-top: 10px;
display: block;
width: 50%;
}
.submit-message {
margin-top: 10px;
width: 80px;
background: rgb(235, 245, 247);
color: cadetblue;
text-align: center;
letter-spacing: 20px;
}</style>