通过vue方法制作瀑布布局-学习笔记

一、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')

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值