導航欄實現
之前寫過使用element-ui進行前端頁面開發,不過只用了一部分功能,這一次做一下首頁頁面的前端部分。
目前導航欄選單還是使用的element-ui給的樣例的選單。後期需要新增功能在進一步完善,一步一步來,這樣比較有計劃性。
VUE的app.vue是頁面入口,導航欄在大部分頁面都需要使用,所以我們就把導航欄當作一個元件放在app.vue裡面
<template>
<div id="app">
<my-header v-if="$route.meta.keepAlive"></my-header>
<router-view/>
</div>
</template>
<script>
import MyHeader from './components/header.vue'
export default {
name: 'app',
components: {
MyHeader
}
}
</script>
<style>
*{
margin: 0;
padding: 0;
}
body{
font-family:Arial,"STHeiti", Helvetica, sans-serif;
background:#efefef;
font-size:14px;
color:#444!important;
min-height:100vh;
width:100%;
overflow-x: hidden;
-webkit-overflow-x: hidden;
-webkit-tap-highlight-color: transparent;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.container{
max-width: 80%;
margin:0 auto;
padding:0 10px;
/*verflow-x: hidden;*/
/* -webkit-overflow-x: hidden;*/
}
a{
text-decoration:none;
color:#000;
}
p{
display: block;
}
ol, ul {
list-style: none;
}
</style>
路由配置,將登陸頁面的頭部不顯示導航欄
import Vue from 'vue' //引入 Vue
import VueRouter from 'vue-router' //引入 Vue 路由
import Login from '../views/login/login'
import Home from '../views/home/home'
Vue.use(VueRouter); //安裝外掛
export const constantRouterMap = [
//配置預設的路徑,預設顯示登入頁
{
path: '/login',
name: 'Login',
component: Login,
meta: {
keepAlive: false
}
},
{
path: '/home',
name: 'Home',
component: Home,
meta: {
keepAlive: true
}
}
]
export default new VueRouter({
mode: 'history', //後端支援可開
scrollBehavior: () => ({y: 0}),
routes: constantRouterMap //指定路由列表
})
2.使用NavMenu元件
<template>
<div class="myHeader">
<div class="headBack">
<el-row class="container">
<el-col :span="24">
<div class="headBox">
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal"
@select="handleSelect" text-color="#fff" :router="true">
<el-menu-item index="/Home"><i class="fa fa-wa fa-home"></i>首頁</el-menu-item>
<el-submenu index="2" >
<template slot="title">我的工作臺</template>
<el-menu-item index="2-1">選項1</el-menu-item>
<el-menu-item index="2-2">選項2</el-menu-item>
<el-menu-item index="2-3">選項3</el-menu-item>
</el-submenu>
<div index="" class="pcsearchbox">
<i class="el-icon-search pcsearchicon"></i>
<div class="pcsearchinput" :class="input?'hasSearched':''">
<el-input placeholder="搜尋" icon="search" v-model="input" :on-icon-click="searchEnterFun" @keyup.enter.native="searchEnterFun" @change="searchChangeFun">
</el-input>
</div>
</div>
<div class="userInfo">
<div v-show="!haslogin" class="nologin">
</div>
<div v-show="haslogin" class="haslogin">
<i class="fa fa-fw fa-user-circle userImg"></i>
<ul class="haslogin-info">
<li>
</li>
<li>
</li>
<li>
</li>
<li>
</li>
</ul>
</div>
</div>
</el-menu>
</div>
</el-col>
</el-row>
</div>
<div class="headImgBox" :style="{background: 'url(' + img + ')' }">
<div class="scene">
<div><span id="luke"></span></div>
</div>
<div class="h-information">
<img :src="this.$store.state.themeObj.head_portrait?this.$store.state.themeObj.head_portrait:tou" alt="">
</a>
<h2 class="h-description">
{{this.$store.state.themeObj.autograph?this.$store.state.themeObj.autograph:"Write the Code. Change the World."}}
</a>
</h2>
</div>
</div>
</div>
</template>
<script>
import {
Typeit
} from '../plugins/plug.js'
import imgurl from '../assets/img/headbg05.jpg'
import tou from '../assets/img/tou.png'
export default {
name: "",
data() { //選項 / 資料
return {
tou: tou, //使用者資訊,
userInfo: '', //使用者資訊
haslogin: false, //是否已登入
classListObj: '', //技術分類
activeIndex: '/', //當前選擇的路由模組
pMenu: true, //手機端選單開啟
// path:'',//當前開啟頁面的路徑
input: '', //input輸入內容
img: imgurl, //頭部背景圖
headTou: '', //頭像
projectList: '' //專案列表
}
},
methods:{
searchEnterFun: function() { //input 輸入 enter
// var keyCode = window.event? e.keyCode:e.which;
// console.log('CLICK', this.input, keyCode)
// console.log('回車搜尋',keyCode,e);
if(this.input){
// this.$router.push({path:'/Share?keywords='+this.input});
}
},
searchChangeFun() { //input change 事件
// console.log(e)
if (this.input == '') {
// this.$router.push({path:'/'});
}
},
handleSelect(key, keyPath) { //pc選單選擇
console.log(key, keyPath);
}
},
mounted() { //頁面元素載入完成
// console.log('是否是慧慧',this.$store.state.themeObj.user_start);
var that = this;
var timer = setTimeout(function() {
Typeit(that.$store.state.themeObj.user_start, "#luke"); //打字機效果
clearTimeout(timer);
}, 500);
}
}
</script>
<style lang="scss">
@import "../assets/css/header.scss";
</style>
在 <el-menu> 標籤中開啟了 router 模式,解釋如下
頭部頁面效果如下
下面就需要完善左邊列表頁面,我們繼續把左邊列表頁面當成一個元件來完成
新建檔案temSharelist.vue
<template>
<el-row class="sharelistBox">
<div v-if="this.$route.name==='Home'" class="shareTitle">
<div class="ui label">
</div>
<ul v-if="sonclassList" class="shareclassTwo" >
<li v-for="(citem) in sonclassList" :key="citem">
</li>
</ul>
</div>
<el-col :span="24" class="s-item tcommonBox" v-for="i in 10" :key="i">
<span class="s-round-date">
<span class="month">4月</span>
<span class="day">21</span>
</span>
<header class="clearfloat">
<h1>
</h1>
<h2>
<i class="fa fa-fw fa-user"></i>發表於
<i class="fa fa-fw fa-clock-o"></i><span v-html="'2020-04-21'"></span> •
<i class="fa fa-fw fa-eye"></i>123 次圍觀 •
<i class="fa fa-fw fa-comments"></i>活捉 234 條 •
<span class="rateBox">
<i class="fa fa-fw fa-heart"></i>22點贊 •
<i class="fa fa-fw fa-star"></i>99收藏
</span>
</h2>
<div class="ui label">
</div>
</header>
<div class="article-content">
<p style="text-indent:2em;">
學而思的數獨小遊戲,H5版本的小遊戲,使用vue 構建專案,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。目,簡單方便,開發打包都超級方便。
</p>
<p >
<img :src="tou" alt="" class="maxW">
</p>
</div>
<div class="viewdetail">
閱讀全文>>
</a>
</div>
</el-col>
</el-row>
</template>
<script>
import tou from '../assets/img/tou.png'
export default {
name: "",
data() { //選項 / 資料
return {
tou:tou,
artId:0,
classId:0,
sendId:'',
className:'',
sonclassList:'',//二級分類
classtwoId:5,
keywords:'',
hasMore:true,
level:1,
shareClass:[
],
queryClass:1,
articleList:'',
}
},
}
</script>
<style scoped>
/**文章列表*/
.sharelistBox{
transtion: all 0.5s ease-out;
font-size: 15px;
}
/** 文章列表盒子*/
.tcommonBox{
background:#fff;
white-space: normal;
word-wrap: break-spaces;
word-break: break-all;
position: relative;
padding: 15px;
border-radius: 16px;
margin-bottom: 40px;
font-size: 15px;
}
.tcommonBox header{
white-space: normal;
word-wrap: break-spaces;
word-break: break-all;
}
.tcommonBox header h1{
margin: 10px 0;
font-size: 25px;
font-weight: 700;
text-align: center;
color:#000;
line-height: 30px;
}
.tcommonBox header h2{
font-size: 14px;
line-height: 24px;
text-align: center;
font-weight: 700;
margin: 10px 0;
}
.s-round-date{
top:-20px;
left:-35px;
height:60px;
width:70px;
background: #64609E;
position: absolute;
padding-top:10px;
border-radius: 100px;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
}
.s-round-date span{
text-align: center;
display: block;
}
.s-round-date .day{
font-size: 30px;
font-weight: 700;
}
.article-content{
font-size: 16px;
white-space: normal;
word-wrap: break-word;
word-break: break-all;
display: flex;
}
.article-content p{
margin:10px 0;
line-height: 24px;
margin-left: 10px;
}
.s-item .viewdetail a{
color:#fff;
font-size: 12px;
padding:5px 10px;
border-radius: 5px;
background: #97dffd;
}
.maxW{
max-height:300px;
overflow:hidden;
text-align:center;
}
.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}
.clearfloat{zoom:1}
/*公共標籤*/
.ui.label{
float: left;
border-color:#97dffd;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
background-color: #97dffd;
margin:5px 0 15px 2px;
font-size: 14px;
position: relative;
left:-32px;
border-radius: 0 4px 4px 0;
padding:7px 11.2px 7px 32px;
display: inline-block;
color:#fff;
}
.ui.label::after{
position: absolute;
content: '';
top:100%;
left:0;
border-top: 0 solid transparent;
border-right-width:1em;
border-right-color:#48456D;
border-right-style:solid;
border-bottom: 1em solid transparent;
border-left: 0 solid transparent;
width:0;
height:0;
}
.ui.label a{
color:#fff;
line-height: 100%;
}
</style>
這裡用到的element-ui都比較基礎,就不介紹了,直接看官方文件即可
完成一個然後寫個迴圈即可
左邊完成後,開始完成右邊的卡片欄,這裡繼續抽成一個元件模組
新建檔案temRightlist.vue
<template>
<div class="rightlistBox">
<section >
<div class="r1-head">
<img :src="headImg">
<h1 v-if="this.$store.state.themeObj.user_start!=0">
<span>王</span>先僧
</h1>
</div>
<div class="r1-body">
<p>你能抓到我麼?</p>
<div class="catch-me" >
<div class="">
<el-tooltip class="item" content="Github" placement="top" >
</el-tooltip>
<el-tooltip class="item" effect="dark" content="QQ" placement="top">
</el-tooltip>
<el-tooltip class="item" effect="dark" content="微博" placement="top">
</el-tooltip>
</div>
<div class="">
<el-tooltip class="item" effect="dark" content="微信" placement="top">
</el-tooltip>
<el-tooltip class="item" effect="dark" content="CSDN" placement="top">
</el-tooltip>
<el-tooltip class="item" effect="dark" content="簡歷" placement="top">
</el-tooltip>
<el-tooltip class="item" effect="dark" content="更多" placement="top">
</el-tooltip>
</div>
</div>
</div>
</section>
<section class="rs2">
<h1>
Do you like me?
</h1>
<div>
<i :class="loveme?'heart active':'heart'"/>
<span>123</span>
</div>
</section>
<section class="rs3" >
<h2 class="ui label">
這些人都排著隊來跟我說話
</h2>
<ul class="rs3-textwidget">
<li class="rs3-item" v-for="(item,index) in artCommentList" :key="'artCommentList'+index">
<div class="rs3-photo">
<img :src="item.avatar?item.avatar:touImg" :onerror="$store.state.errorImg">
</div>
<div class="rs3-inner">
<p class="rs3-author">{{item.nickname}} 在「{{item.title}}」中說:</p>
<p class="rs3-text">{{item.content}}</p>
</div>
</a>
</li>
</ul>
</section>
</div>
</template>
<script>
import headImg from '../assets/img/headtou02.jpg'
import touImg from '../assets/img/tou.jpg'
export default {
name: "",
data(){
return {
headImg:headImg,
touImg:touImg,
loveme:false,
artCommentList:[
{
id:1,
nickname:"遊客",
title:"這篇文章很不錯",
content:"寫的太棒了"
}
catchMeObj:{//抓住我 個人資訊
Qinlh:{
git:'https://gitee.com/qinlh',
qq: 'static/img/qinlh/qq.jpg',
sina: 'https://weibo.com/u/2313631533',
wechat: 'static/img/qinlh/wechat.jpg',
csdn: 'http://www.qinlinhui.cn',
job: 'http://qinlh.mangoya.cn/MyResume/'
},
Aimee:{
git: 'https://github.com/Aimee1608',
qq: 'static/img/aimee/QQ.jpg',
sina: 'https://weibo.com/u/2242812941',
wechat: 'static/img/aimee/erwm.jpg',
csdn: 'http://blog.csdn.net/Aimee1608',
job: 'http://aimee.mangoya.cn'
}
},
isAimee:this.$store.state.themeObj.user_start!=0?"Aimee":"Qinlh"//判斷是哪個的部落格
}
}
}
</script>
<style scoped>
.rightlistBox{
position: relative;
}
.rightlistBox section {
transition: all 0.2s linear;
position: relative;
background: #fff;
padding:15px;
margin-bottom: 20px;
border-radius: 5px;
}
.rightlistBox section:hover{
transform: translate(0,-2px);
box-shadow:0 15px 30px rgba(0,0,0,.1);
}
/*第一個section*/
.rightlistBox .r1-head{
text-align: center;
border-radius: 4px 4px 0 0 ;
text-align: center;
position: relative;
/*box-shadow: inset 0 -70px 100px -50px rgba(0,0,0,.5);*/
}
.rightlistBox .r1-head img{
width:100%;
min-height: 100px;
}
.rightlistBox .r1-head h1{
position: absolute;
margin: 0 0 0 -65px;
font-size: 20px;
letter-spacing: 0.5px;
color: #ffffff;
text-shadow: 1px 1px 1px rgba(0,0,0,.7);
font-weight: 700;
width: 130px;
left: 50%;
bottom: 5px;
}
.rightlistBox .r1-body p{
font-size: 14px;
margin: 5px 0 8px 0;
font-weight: 700;
text-align: center;
}
.rightlistBox .r1-body .catch-me{
text-align: center;
}
.rightlistBox .r1-body .catch-me a{
display: inline-block;
margin-bottom: 7px;
position: relative;
text-decoration: none;
}
.rightlistBox .r1-body .catch-me a:hover i{
color:#fff;
background: #F4692C;
}
.rightlistBox .r1-body .catch-me a i{
display: inline-block;
font-size: 18px;
width:42px;
height:42px;
line-height: 42px;
border-radius: 42px;
color:rgba(0,0,0,0.5);
background: rgba(0,0,0,0.1);
transition: all 0.3s ease-in-out;
font-style: normal;
margin:0 3.2px;
}
/*************do you like me*******************/
.rs2{
min-height: 100px;
}
.rs2 h1{
color:red;
cursor: pointer;
font-size: 20px;
margin-bottom: 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis; /*顯示省略符號來代表被修剪的文字。*/
text-align: center;
margin-top:10px;
font-weight: 700;
}
.rs2 div{
color: #DF2050;
cursor: pointer;
font-size: 40px;
position: absolute;
width: 100%;
height: 100px;
line-height: 100px;
left: 0;
top: 30px;
}
.rs2 div i.heart{
display: inline-block;
background-image: url(../assets/img/heart.png);
background-position:0 0 ;
text-align: center;
width: 100px;
height: 100px;
margin-left: -20px;
margin-top: -5px;
cursor: pointer;
vertical-align: middle;
-webkit-transition: background-position 1s steps(28);
transition: background-position 1s steps(28);
-webkit-transition-duration: 0s;
transition-duration: 0s;
}
/**第三個section*/
.rightlistBox .rs3 .rs3-item{
font-size: 13px;
line-height: 20px;
}
.rightlistBox .rs3 .rs3-item a{
display:block;
padding:5px;
transition: all .3s ease-out;
border-bottom: 1px solid #ddd;
margin:5px 0;
}
.rightlistBox .rs3 .rs3-item a:hover{
background: rgba(230,244,250,.5);
border-radius: 5px;
}
.rightlistBox .rs3 .rs3-photo{
float:left;
}
.rightlistBox .rs3 .rs3-photo img{
border-radius: 50%;
width:32px;
height:32px;
/*object-fit CSS 屬性指定可替換元素的內容應該如何適應到其使用的高度和寬度確定的框。*/
/*您可以通過使用 object-position 屬性來切換被替換元素的內容物件在元素框內的對齊方式。*/
/*fill*/
/* 被替換的內容正好填充元素的內容框。整個物件將完全填充此框。如果物件的寬高比與內容框不相匹配,那麼該物件將被拉伸以適應內容框。
cover
被替換的內容在保持其寬高比的同時填充元素的整個內容框。如果物件的寬高比與內容框不相匹配,該物件將被剪裁以適應內容框。*/
object-fit: cover;
}
.rightlistBox .rs3 .rs3-inner{
margin-left: 40px;
}
.rightlistBox .rs3 .rs3-inner p.rs3-author{
font-weight: 700;
padding: 0;
text-align: left;
}
.rightlistBox .rs3 .rs3-inner .rs3-text{
font-size: 12px;
text-align: justify;
}
.rightlistBox .rs3 .rs3-item:last-child a{
border-bottom: none;
}
/************排隊看這些***************/
.rightlistBox .rs4 li{
padding:8px 0;
text-align: justify;
}
.rightlistBox .rs4 li a{
font-weight: 600;
}
.rightlistBox .rs4 li a:hover {
color: #64609E;
}
</style>
顯示效果
這樣模組都寫完了下面就組合到home.vue頁面即可
<template>
<div>
<div class="container">
<el-row :gutter="30">
<el-col :sm="24" :md="16" style="transition:all .5s ease-out;margin-bottom:30px;">
<tem-sharelist></tem-sharelist>
</el-col>
<el-col :sm="24" :md="8" >
<tem-rightlist></tem-rightlist>
</el-col>
</el-row>
</div>
{{$store.state.user.userDetail.token}}
</div>
</template>
<script>
import temSharelist from '../../components/temSharelist';
import temRightlist from '../../components/temRightlist';
export default {
name: 'Login',
components:{
temSharelist,
temRightlist
},
data () {
return {
loginForm: {
username: '',
password: ''
},
responseResult: []
}
},
methods: {
login () {
this.$axios
.post('/login', {
username: this.loginForm.username,
password: this.loginForm.password
})
.then(successResponse => {
if (successResponse.data.code === 200) {
this.$router.replace({path: '/index'})
}
})
.catch(failResponse => {
console.log(failResponse)
})
}
}
}
</script>
<style>
</style>
這裡使用el-row主要是打算做成響應式的
接著訪問http://localhost:4000/home
前端部落格首頁完成,後期需要在新增即可