一、create vue l8_1 配置route babel css 安装axios
二、总体构建
三、
1.src中assets-font (iconfont中保存的图标,百度搜索阿里巴巴矢量库)
assert-images(本地的照片)
2.component-list.vue
<template>
<div class="content">
<div v-for="(item,index) in list" :key="index" class="item">
<div>
<img :src="item.pic" />
<div class="name-text">{{item.name}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['list']
};
</script>
<style scoped="scoped">
.content {
width: 100%;
height: 100%;
display: flex;
flex-flow: row wrap;
flex: 2;
}
.item {
width: 150px;
margin-bottom: 20px;
}
.name-text {
margin-top: -20px;
color:red;
}
img{
width: 150px;
}
</style>
imgdetail-list.vue
<template>
<div class="content">
<div v-for="(item,index) in list" :key="index" class="item">
<div>
<img :src="item.pic" />
<div class="name-text">{{item.name}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['list'],
methods: {
// 滚动
scroll() {
let clientHeight = document.documentElement.clientHeight || document.body.clientHeight
// 设备/屏幕高度
let scrollObj = document.querySelector('.content') // 滚动区域
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
let scrollHeight = scrollObj.scrollHeight // 滚动条的总高度
console.log("window.pageYOffset="+window.pageYOffset);
console.log("document.documentElement.scrollTop="+document.documentElement.scrollTop)
console.log("document.body.scrollTop="+document.body.scrollTop)
// if (scrollTop + clientHeight === scrollHeight) {
// // div 到头部的距离 + 屏幕高度 = 可滚动的总高度
// // 滚动条到底部的条件
// if (this.hasMore && !this.isLoading) {
// this.isLoading = true
// // 请求后台数据
// let getstr = `?_page=${this.pageIndex}&_limit=${this.pageSize}`
// this.axios.get("/students" + getstr)
// .then(res => {
// // 请求成功调用 getMoreCallback 方法
// this.getMoreCallback(res.data);
// })
// }
// }
}
},
created: function() {
window.addEventListener('scroll', this.scroll)
}
};
</script>
<style scoped="scoped">
.content {
width: 100%;
height: 100%;
}
.item {
width: 100%;
margin-bottom: 50px;
}
.name-text {
color: red;
}
img {
max-width: 350px;
object-fit: contain;
justify-items: center;
}
</style>
photo2.vue
<template>
<div >
<img :style="{width:width}" class="image-wrap" :src="url" />
</div>
</template>
<script>
export default{
props:['url'],
data(){
return{
width:''
}
},
created() {
let img=new Image();
img.src=this.url;
let screenWidth=screen.availWidth;
this.width=`${screenWidth/2-10}px`;
}
}
</script>
<style scoped="scoped">
.image-wrap{
padding: 0;
border-radius: 5px;
}
</style>
photo-flow.vue
<template>
<div class="images-wrap" :list="list">
<div>
<div v-for="(item,index) in list1" :key="index">
<photo :url="item"></photo>
</div>
</div>
<div>
<div v-for="(item,index) in list2" :key="index">
<photo :url="item"></photo>
</div>
</div>
</div>
</template>
<script>
import Photo from "./photo2.vue"
export default{
components:{
Photo
},
props:['list'],
data(){
return{
list1:[],
list2:[]
}
},
created(){
for(let i=0;i<this.list.length;i++){
if((i+1)%2==0){
this.list2.push(this.list[i])
}else{
this.list1.push(this.list[i])
}
}
}
}
</script>
<style scoped="scoped">
.images-wrap{
width: 100%;
display: flex;
flex-direction: row;
flex: 2;
justify-content: space-around;
flex-wrap:wrap;
/* column-gap: 20px; */
}
</style>
search-input.vue
<template>
<div class="header">
<div class="header-wrap">
<slot name="left"></slot>
<div class="search-box">
<div class="iconfont icon-baseline-search-px"></div>
<input class="input" type="search" placeholder="请输入查询的内容" />
</div>
<slot name="right" :heartNum="heartNum">
{{heartNum}}
</slot>
</div>
</div>
</template>
<script>
export default{
data: function() {
return {
heartNum: 10,
}
}
}
</script>
<style scoped="scoped">
.header {
width: 100%;
}
.header-wrap {
width: 100%;
display: flex;
flex-direction: row;
height: 30px;
margin-left: 15px;
margin-top: 20px;
}
.search-box{
width: 60%;
display: flex;
flex-direction: row;
align-items: center;
vertical-align: middle;
background-color: white;
border-radius: 15px;
}
.input {
outline: none;
border: none;
}
</style>
student.vue
<template>
<div>
<img :src="imgurl" />
<div class="name-text">{{name}}</div>
</div>
</template>
<script>
export default {
props: ['imgurl','name']
};
</script>
<style scoped="scoped">
.name-text{
margin-top: -80px;
}
</style>
student-list.vue
<template>
<div class="content">
<div v-for="(item,index) in list" :key="index" class="item">
<student :imgurl="item.pic" :name="item.name"></student>
</div>
</div>
</template>
<script>
import student from "./student.vue"
export default {
components:{
student
},
props: ['list']
};
</script>
<style scoped="scoped">
.content{
width: 100%;
height: 100%;
display: flex;
flex-flow: row wrap;
flex: 2;
}
.item{
width: 200px;
margin-bottom: 80px;
}
</style>
tab-bars.vue
<template>
<div class="tab-wrap">
<router-link to="/" class="iconfont icon-home tab-item"/>
<router-link to="/home/男" class="iconfont icon-fenlei_ tab-item"/>
<router-link to="/home/女" class="iconfont icon-plussign tab-item"/>
<router-link to="/aaa" class="iconfont icon-message1 tab-item"/>
<router-link to="/bbb" class="iconfont icon-user-plus tab-item"/>
</div>
</template>
<script>
export default{
}
</script>
<style scoped="scoped">
.tab-wrap{
display: flex;
flex-direction: row;
justify-content: space-around;
}
.tab-item{
font-size: 24px;
line-height: 24px;
margin-top: 8px;
text-decoration: none;
}
a:visited {
color: black;
}
</style>
top-menu.vue
<template>
<div class="menu-wrap">
<div v-for="(item,index) in menus"
@click="menuClick(index)" :key="index"
:class="menuIdx==index?'item-active':'item'">
{{item}}
</div>
</div>
</template>
<script>
export default {
name: "topMenu",
props: ['menus'],
data: function() {
return {
menuIdx: 0
}
},
methods: {
menuClick(e) {
this.menuIdx = e;
this.$emit("MenuClick",e);
}
}
};
</script>
<style>
.menu-wrap {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.item {
font-size: 18px;
line-height: 18px;
margin-left: 15px;
margin-top: 10px;
}
.item-active {
font-size: 24px;
line-height: 24px;
margin-left: 15px;
margin-top: 10px;
padding-bottom: 2px;
border-bottom: 1px solid;
}
</style>
3.route-index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/home',
// component: Home
redirect:'/'
},
{
path: '/home/:gender',
component:Home,
props:true
},
{
path: '/aaa',
component: () => import('../views/aaa.vue')
},
{
path: '/bbb',
component: () => import('../views/bbb.vue')
}
]
const router = new VueRouter({
routes
})
export default router
4.views
aaa.vue
<template>
<div>
<div class="head-wrap">
<search-input class="search-input">
<template #left>
<div class="iconfont icon-share myslot"></div>
</template>
<template v-slot:right="slotPro">
<div class="iconfont icon-heart1 myslot"></div>
<div v-show="slotPro.heartNum!=0" class="heart-num"> {{slotPro.heartNum}} </div>
</template>
</search-input>
<top-menu :menus="mymenus"></top-menu>
</div>
<div class="body-content">
<photo-flow :list="imgs"></photo-flow>
</div>
<div class="footer">
<tab-bars></tab-bars>
</div>
</div>
</template>
<script>
import topMenu from "../components/top-menu.vue"
import searchInput from "../components/search-input.vue"
import PhotoFlow from "../components/photo-flow.vue"
import TabBars from "../components/tab-bars.vue"
export default{
components:{
topMenu,
searchInput,
TabBars,
PhotoFlow
},
data () {
return {
mymenus: ['动态', '热门', '推荐', '精选'],
menuIdx: 0,
imgs:[
require('../assets/images/专辑10.jpg'),
require('../assets/images/专辑11.jpg'),
require('../assets/images/专辑14.jpg'),
require('../assets/images/专辑15.jpg'),
require('../assets/images/专辑21.jpg'),
require('../assets/images/专辑24.jpg'),
require('../assets/images/专辑25.jpg'),
require('../assets/images/专辑26.jpg'),
require('../assets/images/专辑27.jpg'),
]
}
}
}
</script>
<style scoped="scoped">
.head-wrap {
width: 100%;
position: fixed;
height: 100px;
top: 0;
left: 0;
background: #708090;
}
.search-input {
margin-bottom: 10px;
}
.myslot {
font-size: 24px;
line-height: 24px;
margin-top: 10px;
}
.heart-num {
color: pink;
}
.body-content {
height: 100%;
margin-top: 100px;
}
</style>
bbb.vue
<template>
<div>
bbb
<div class="footer">
<tab-bars></tab-bars>
</div>
</div>
</template>
<script>
import TabBars from "../components/tab-bars.vue"
export default{
components:{
TabBars
}
}
</script>
<style>
</style>
Home.vue
<template>
<div id="app" class="content">
<div class="head-wrap">
<search-input class="search-input">
<template #left>
<div class="iconfont icon-share myslot"></div>
</template>
<template v-slot:right="slotPro">
<div class="iconfont icon-heart1 myslot"></div>
<div v-show="slotPro.heartNum!=0" class="heart-num"> {{slotPro.heartNum}} </div>
</template>
</search-input>
<top-menu :menus="mymenus"></top-menu>
</div>
<div class="body-content">
<image-list :list="imglist"></image-list>
</div>
<div class="footer">
<tab-bars></tab-bars>
</div>
</div>
</template>
<script>
import topMenu from "../components/top-menu.vue"
import TabBars from "../components/tab-bars.vue"
import searchInput from "../components/search-input.vue"
import imageList from "../components/image-list.vue"
import imgdetailList from "../components/imgdetail-list.vue"
import studentList from "../components/student-list.vue"
export default {
name: 'App',
components: {
topMenu,
TabBars,
searchInput,
imageList,
imgdetailList,
studentList
},
props: ['gender'],
data: function() {
return {
mymenus: ['动态', '热门', '推荐', '精选'],
menuIdx: 0,
list: [],
imglist: [{
pic: require('../assets/images/1.jpg'),
name: '一休来了'
},
{
pic: require('../assets/images/2.jpg'),
name: '我是传说'
},
{
pic: require('../assets/images/3.jpeg'),
name: '不怕热的北极熊'
},
{
pic: require('../assets/images/4.jpg'),
name: '酷姐一枚'
}
]
}
},
methods: {
},
watch:{
$route: {
handler(newVal, oldVal) {
this.gender=this.$route.params.gender
let uri=''
if(this.gender==''||this.gender==undefined) uri='/students'
else uri="/students?gender="+this.gender;
this.axios.get(uri).then(res=>{
this.list=res.data.data;
console.log(this.list)
})
}
}},
created() {
// if(this.gender=='男'){
// // //if(this.$route.params.gender=='男'){
// this.list.push(this.imglist[0])
// this.list.push(this.imglist[2])
// return;
// }
// if(this.gender=='女'){
// // //if(this.$route.params.gender=='女'){
// this.list.push(this.imglist[1])
// this.list.push(this.imglist[3])
// return;
// }
// // this.list=this.imglist
let uri = ''
if (this.gender == '' || this.gender == undefined)
uri = '/students'
else uri = "/students?gender=" + this.gender;
// this.axios.get(uri).then(res => {
// this.list = res.data.data;
// console.log(this.list)
// })
}
}
</script>
<style scoped="scoped">
.content {
width: 100%;
height: 100%;
}
.head-wrap {
width: 100%;
position: fixed;
height: 100px;
top: 0;
left: 0;
background: #708090;
}
.search-input {
margin-bottom: 10px;
}
.myslot {
font-size: 24px;
line-height: 24px;
margin-top: 10px;
}
.heart-num {
color: pink;
}
.body-content {
height: 100%;
margin-top: 100px;
}
</style>
5.App.vue
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
export default {
name: 'app',
components: {
},
data(){
return{
}
}
}
</script>
<style lang="less">
.router-link-exact-active{
font-size: 32px;
line-height: 32px;
}
.footer{
width: 100%;
height: 40px;
position: fixed;
bottom: 0;
left: 0;
background: #708090;
}
</style>
6.main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import axios from "axios"
import VueAxios from "vue-axios"
import "./assets/font/iconfont.css"
Vue.config.productionTip = false
axios.defaults.baseURL="http://localhost:3000"
Vue.use(VueAxios,axios)
new Vue({
router,
render: h => h(App)
}).$mount('#app')