搜索页面布局

1, 创建一个搜索页,在首页点击'搜索',然后跳转到搜索页
复制代码
{
	path: "search",
	name: "Search",
	components: () => import("../views/Search.vue")
},
2, 在 views 下创建一个 Search.vue 文件
首先找到Home.vue中的Header标签,然后找到components/home/Header.vue文件,然后给他添加一个点击事件,去跳转到 Search.vue页面
复制代码
1, 在 components/home/Header.vue 文件中添加如下代码

html:
<div class="search" @click="goSearch">
    <i class="iconfont icon-fangdajing"></i>
    <span>搜你喜欢的...</span>
</div>

script:
methods: {
    goSearch() {
        this.$router.push('/search')
    }
}



2, 在 views 目录下新建 Search.vue 文件 引入 Tabbar 公共底部组件

import Tabbar from '@/components/common/Tabbar.vue'



3, 去 components 目录下创建 search 文件夹,在 search 目录下创建 Header.vue文件,即 components/search/Header.vue 文件
搜索页面布局 实现代码如下:
复制代码
1, server/routes/index.js (server开头是后端代码)
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
	res.render('index', {
		title: 'Express'
	});
});

// 首页推荐的数据  0==> 推荐  1==> 第一塀数据
router.get('/api/index_list/0/data/1', function(req, res, next) {
	res.send({
		code: 0,
		data: {
			topBar: [{
				id: 0,
				label: '推荐'
			}, {
				id: 1,
				label: '大红袍'
			}, {
				id: 2,
				label: '绿茶'
			}, {
				id: 3,
				label: '铁观音'
			}, {
				id: 4,
				label: '普洱'
			}, {
				id: 5,
				label: '茶具'
			}, {
				id: 6,
				label: '花茶'
			}, {
				id: 7,
				label: '设计'
			}, ],
			// 这是我们的swiper
			data: [{ // 这是swiper数据
				id: 0,
				type: 'swiperList',
				data: [{
					id: 0,
					imgUrl: './images/swiper4.png'
				}, {
					id: 1,
					imgUrl: './images/swiper5.png'
				}, {
					id: 2,
					imgUrl: './images/swiper6.png'
				}],
			}, { // 这是Icons数据
				id: 1,
				type: 'iconsList',
				data: [{
					id: 1,
					title: '自饮茶',
					imgUrl: './images/icons1.png'
				}, {
					id: 2,
					title: '茶具',
					imgUrl: './images/icons2.png'
				}, {
					id: 3,
					title: '茶礼盒',
					imgUrl: './images/icons3.png'
				}, {
					id: 4,
					title: '领取福利',
					imgUrl: './images/icons4.png'
				}, {
					id: 5,
					title: '官方验证',
					imgUrl: './images/icons5.png'
				}],
			}, { // 爆款推荐
				id: 2,
				type: 'recommendList',
				data: [{
					id: 1,
					name: '龙井1号铁观音250g',
					content: '鲜爽甘醇 口粮首先',
					price: '68',
					imgUrl: './images/recommend2.png'
				}, {
					id: 2,
					name: '龙井2号铁观音250g',
					content: '鲜爽甘醇 口粮首先',
					price: '58',
					imgUrl: './images/recommend2.png'
				}]
			}, {
				// 猜你喜欢
				id: 3,
				type: 'likeList',
				data: [{
					id: 1,
					imgUrl: './images/like8.png',
					name: '建盏茶具套装 红色芝麻毫 12件套',
					price: 299,
				}, {
					id: 2,
					imgUrl: './images/like8.png',
					name: '建盏茶具套装 红色芝麻毫 12件套',
					price: 299,
				}, {
					id: 3,
					imgUrl: './images/like8.png',
					name: '建盏茶具套装 红色芝麻毫 12件套',
					price: 299,
				}]
			}]
		}
	})
});

// 首页大红袍的数据  1==> 大红袍  1==> 第一塀数据
router.get('/api/index_list/1/data/1', function(req, res, next) {
	res.send({
		code: 0,
		data: [{
			id: 1,
			type: 'adList',
			data: [{
				id: 1,
				imgUrl: './images/dhp.png'
			}, {
				id: 2,
				imgUrl: './images/dhp.png'
			}]
		}, {
			// 猜你喜欢
			id: 2,
			type: 'likeList',
			data: [{
				id: 1,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}, {
				id: 2,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}, {
				id: 3,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}]
		}]
	})
});

// 首页绿茶的数据  2==> 绿茶  1==> 第一塀数据
router.get('/api/index_list/2/data/1', function(req, res, next) {
	res.send({
		code: 0,
		data: [{
			id: 1,
			type: 'adList',
			data: [{
				id: 1,
				imgUrl: './images/dhp.png'
			}, {
				id: 2,
				imgUrl: './images/dhp.png'
			}]
		}, {
			// 猜你喜欢
			id: 2,
			type: 'likeList',
			data: [{
				id: 1,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}, {
				id: 2,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}, {
				id: 3,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}]
		}]
	})
});

// 首页铁观音的数据  3==> 铁观音  1==> 第一塀数据
router.get('/api/index_list/3/data/1', function(req, res, next) {
	res.send({
		code: 0,
		data: [{
			id: 1,
			type: 'adList',
			data: [{
				id: 1,
				imgUrl: './images/dhp.png'
			}, {
				id: 2,
				imgUrl: './images/dhp.png'
			}]
		}, {
			// 猜你喜欢
			id: 2,
			type: 'likeList',
			data: [{
				id: 1,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}, {
				id: 2,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}, {
				id: 3,
				imgUrl: './images/like8.png',
				name: '建盏茶具套装 红色芝麻毫 12件套',
				price: 299,
			}]
		}, { // 这是Icons数据
			id: 3,
			type: 'iconsList',
			data: [{
				id: 1,
				title: '自饮茶',
				imgUrl: './images/icons1.png'
			}, {
				id: 2,
				title: '茶具',
				imgUrl: './images/icons2.png'
			}, {
				id: 3,
				title: '茶礼盒',
				imgUrl: './images/icons3.png'
			}, {
				id: 4,
				title: '领取福利',
				imgUrl: './images/icons4.png'
			}, {
				id: 5,
				title: '官方验证',
				imgUrl: './images/icons5.png'
			}]
		}]
	})
});

// 首页普洱的数据  4==> 普洱  1==> 第一塀数据
router.get('/api/index_list/4/data/1', function(req, res, next) {});

// 首页茶具的数据  5==> 茶具  1==> 第一塀数据
router.get('/api/index_list/5/data/1', function(req, res, next) {});

// 首页花茶的数据  6==> 话茶  1==> 第一塀数据
router.get('/api/index_list/6/data/1', function(req, res, next) {});

// 首页设计的数据  7==> 设计  1==> 第一塀数据
router.get('/api/index_list/7/data/1', function(req, res, next) {});

// 测试
// router.get('/api/home', function(req, res, next) {
// 	res.send({
// 		code: 0,
// 		a: 1
// 	})
// });

module.exports = router;











2, src/assets/css/common.css
* {
	margin: 0;
	padding: 0;
}

ul {
	list-style: none;
}

input {
	background: none;
	border: none;
	/* box-shadow:none; */
	outline: none;
}

input:focus {
	border: none;
}

/* 删除input自动填充背景 */
/* input:-webkit-autofill {
	transition: background-color 5000s ease-in-out 0s;
} */

/* 颜色是设置成你需要的颜色 */
/* input {
	-webkit-text-fill-color: #9cc5ec; 
} */









3, src/assets/css/iconfont.css

@font-face {
	font-family: "iconfont";
	/* Project id 5021940 */
	src: url('../fonts/iconfont.woff2?t=1758671296908') format('woff2'),
		url('../fonts/iconfont.woff?t=1758671296908') format('woff'),
		url('../fonts/iconfont.ttf?t=1758671296908') format('truetype');
}

.iconfont {
	font-family: "iconfont" !important;
	font-size: 16px;
	font-style: normal;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

.icon-time:before {
	content: "\e656";
}

.icon-icon-test:before {
	content: "\e61d";
}

.icon-a-huaban1fuben44:before {
	content: "\e601";
}

.icon-remen:before {
	content: "\e649";
}

.icon-kefu:before {
	content: "\ec2e";
}

.icon-fangdajing:before {
	content: "\e848";
}








4, src/assets/js/flexible.js
(function flexible(window, document) {
	var docEl = document.documentElement
	var dpr = window.devicePixelRatio || 1

	// adjust body font size
	function setBodyFontSize() {
		if (document.body) {
			document.body.style.fontSize = (12 * dpr) + 'px'
		} else {
			document.addEventListener('DOMContentLoaded', setBodyFontSize)
		}
	}

	setBodyFontSize();

	// set 1rem = viewWidth / 10
	function setRemUnit() {
		var rem = docEl.clientWidth / 10
		docEl.style.fontSize = rem + 'px'
	}

	setRemUnit()

	// reset rem unit on page resize
	window.addEventListener('resize', setRemUnit)
	window.addEventListener('pageshow', function(e) {
		if (e.persisted) {
			setRemUnit()
		}
	})

	// detect 0.5px supports
	if (dpr >= 2) {
		var fakeBody = document.createElement('body')
		var testElement = document.createElement('div')
		testElement.style.border = '.5px solid transparent'
		fakeBody.appendChild(testElement)
		docEl.appendChild(fakeBody)
		if (testElement.offsetHeight === 1) {
			docEl.classList.add('hairlines')
		}
		docEl.removeChild(fakeBody)
	}
}(window, document))

// module.exports = {
// 	plugins: {
// 		'postcss-px-to-viewport': {
// 			viewportWidth: 750, // 设计稿宽度
// 			unitPrecision: 5,
// 			viewportUnit: 'vw',
// 			selectorBlackList: [],
// 			minPixelValue: 1
// 		}
// 	}
// }

// 淘宝无线适配文件








5, src/components/common/Tabbar.vue
<template>
	<!-- 获取数据并将数据渲染到视图层 -->
	<div class="tabbar">
		<ul>
			<li v-for="(item,index) in routerList" :key="index" @click="switchTab(item.path)">
				<img :src="$route.path.includes(item.path) ? item.selected : item.active" alt="" />
				<span :class="$route.path.includes(item.path) ? 'active' : ''">{{item.title}}</span>
			</li>
		</ul>
	</div>
</template>

<script>
	export default {
		// 构建数据渲染到视图层
		data() {
			return {
				routerList: [{
					title: "首页",
					path: "/home",
					active: "./images/home.png",
					selected: "./images/home-select.png",
				}, {
					title: "分类",
					path: "/list",
					active: "./images/list.png",
					selected: "./images/list-select.png",
				}, {
					title: "购物车",
					path: "/cart",
					active: "./images/cart.png",
					selected: "./images/cart-select.png",
				}, {
					title: "我的",
					path: "/my",
					active: "./images/my.png",
					selected: "./images/my-select.png",
				}]
			}
		},
		methods: {
			switchTab(path) {
				// 判断是否点击的是同一个路由 判断点击时路径等于当前路径,直接返回就OK
				if (this.$route.path == path) return;
				// this.$router.push(path);
				// 对应跳转页面
				this.$router.replace(path);
			}
		}
	}
</script>

<style scoped>
	.tabbar {
		/* 定位在页面最下方 */
		position: fixed;
		left: 0;
		bottom: 0;
		z-index: 999;
		width: 100%;
		height: 50px;
		background-color: #fff;
	}

	.tabbar ul {
		display: flex;
		justify-content: space-around;
		align-items: center;
		width: 100%;
		height: 100%;
	}

	.tabbar ul li {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}

	.tabbar ul li img {
		width: 31px;
		height: 31px;
	}

	.tabbar ul li span {
		text-align: center;
		font-size: 16px;
	}

	.active {
		color: red;
	}
</style>







6, src/components/home/Ad.vue
<template>
	<div class="ad">
		<ul>
			<li v-for="(item,index) in adList" :key="index">
				<img :src="intem.imgUrl" alt="" />
			</li>
		</ul>
	</div>
</template>

<script>
	export default { // 子组件(父组件传值给子组件)
		// 子组件接收父组件传递过来的数据
		props: {
			adList: Array
		},
	}
</script>

<style scoped>
	.ad {
		width: 100%;
		/* height: 112px; */
	}

	.ad {
		width: 100%;
		height: 100%;
	}
</style>









7, src/components/home/Card.vue
<template>
	<div class="title">
		<!-- 插槽 -->
		<slot></slot>
		<slot name="like"></slot>
	</div>
</template>

<script>
</script>

<style scoped>
	.title {
		padding: 10px 0;
		width: 100%;
		text-align: center;
		font-size: 16px;
	}

	.title span {
		position: relative;
	}

	.title span::after {
		content: "";
		display: block;
		position: absolute;
		top: 50%;
		right: -0.5rem;
		margin-top: -4px;
		width: 8px;
		height: 8px;
		border-radius: 50%;
		background: #d4c0a7;
	}

	.title span::before {
		content: "";
		display: block;
		position: absolute;
		top: 50%;
		left: -0.5rem;
		margin-top: -4px;
		width: 8px;
		height: 8px;
		border-radius: 50%;
		background: #d4c0a7;
	}
</style>








8, src/components/home/Footer.vue
<template>
	<div id="m-footer" class="m-footer" style="">
		<div class="m-footertxt">到底啦,你还可以看看这里</div>
		<div class="m-footerbtn">
			<span>
				<a href="/categeryList?comefrom=index">更多茶叶</a>
			</span>
			<span>
				<a href="/zhuanti/teaset?comefrom=index">更多茶具</a>
			</span>
		</div>
		<div class="m-footertxt" style="margin-top: 20px;">
			Copyright 2016 茶七网 TEA7.com
		</div>
		<div class="m-footertxt">
			服务时间: 8:30-21:00 客服热线: 400-8993-513
		</div>
		<div class="m-footertxt">
			备案号
			<a href="http://beian.miit.gov.cn?comefrom=index">闽ICP备14011677号-2</a>
		</div>
	</div>
</template>

<script>
</script>

<style>
</style>








9, src/components/home/Header.vue
<template>
	<Header>
		<h1>
			<img src="@/assets/images/logo.png" alt="" />
		</h1>
		<div class="search" @click="goSearch">
			<i class="iconfont icon-fangdajing"></i>
			<span>搜你喜欢的...</span>
		</div>
		<div class="kefu">
			<i class="iconfont icon-kefu"></i>
		</div>
	</Header>
</template>

<script>
	export default {
		data() {
			return {
				//
			}
		},
		methods: {
			goSearch() {
				// 进入到search页面
				this.$router.push('/search')
			}
		}
	}
</script>

<style scoped>
	header {
		display: flex;
		justify-content: space-around;
		align-items: center;
		width: 100%;
		height: 60px;
		background-color: #b0352f;
	}

	header h1 {
		padding-right: 10px;
		width: 120px;
		height: 52px;
	}

	header h1 img {
		padding-right: 10px;
		width: 100%;
		height: 100%;
	}

	.search {
		display: flex;
		align-items: center;
		width: 246px;
		height: 30px;
		background-color: #FFFFFF;
		border-radius: 12px;
	}

	.search i {
		padding: 0 16px;
		color: #ccc;
	}

	.search span {
		font-size: 14px;
		color: gray;
	}

	.kefu i {
		font-size: 30px;
		color: #fff;
	}
</style>








10, src/components/home/Icons.vue
<template>
	<ul class="icons">
		<li v-for="(item,index) in iconsList" :key="index">
			<img :src="item.imgUrl" alt="" />
			<span>{{item.title}}</span>
		</li>
	</ul>
</template>

<script>
	export default { // 子组件(父组件传值给子组件)
		// 子组件接收父组件传递过来的数据
		props: {
			iconsList: Array
		},
		data() { // 构建数据
			return {
				// iconsList: [{
				// 	id: 1,
				// 	title: '自饮茶',
				// 	imgUrl: './images/icons1.png'
				// }, {
				// 	id: 2,
				// 	title: '茶具',
				// 	imgUrl: './images/icons2.png'
				// }, {
				// 	id: 3,
				// 	title: '茶礼盒',
				// 	imgUrl: './images/icons3.png'
				// }, {
				// 	id: 4,
				// 	title: '领取福利',
				// 	imgUrl: './images/icons4.png'
				// }, {
				// 	id: 5,
				// 	title: '官方验证',
				// 	imgUrl: './images/icons5.png'
				// }]
			}
		}
	}
</script>

<style scoped>
	.icons {
		display: flex;
		justify-content: space-around;
		padding: 10px 0;
	}

	.icons li {
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.icons img {
		width: 38px;
		height: 38px;
	}

	.icons span {
		padding: 6px 0;
		font-size: 16px;
	}
</style>










11, src/components/home/Like.vue
<template>
	<div class="like">
		<Card>
			<base-layout>
				<template #like>
					<span>猜你喜欢</span>
				</template>
			</base-layout>
		</Card>
		<ul>
			<li>
				<h2 v-for="(item,index) in likeList" :key="index">
					<img :src="item.imgUrl" />
				</h2>
				<h3>{{item.name}}</h3>
				<div>
					<span>¥</span>
					<b>{{item.price}}</b>
				</div>
			</li>
		</ul>
	</div>
</template>

<script>
	import Card from '@/components/home/Card.vue'
	export default {
		name: Like,
		// 子组件接收父组件传递过来的数据
		props: {
			likeList: Array
		},
		data() {
			return {
				// likeList: [{
				// 	id: 1,
				// 	imgUrl: './images/like8.png',
				// 	name: '建盏茶具套装 红色芝麻毫 12件套',
				// 	price: 299,
				// }, {
				// 	id: 2,
				// 	imgUrl: './images/like8.png',
				// 	name: '建盏茶具套装 红色芝麻毫 12件套',
				// 	price: 299,
				// }, {
				// 	id: 3,
				// 	imgUrl: './images/like8.png',
				// 	name: '建盏茶具套装 红色芝麻毫 12件套',
				// 	price: 299,
				// }]
			}
		},
		components: {
			Card
		}
	}
</script>

<style scoped>
	.like ul {
		display: flex;
		flex-wrap: wrap;
	}

	.like ul li {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		width: 50%;
		text-align: center;
	}

	.like ul li>div {
		padding: 6px;
		width: 93%;
		text-align: left;
		color: #FF0000;
	}

	.like ul li>div span {
		font-size: 12px;
	}

	.like ul li>div b {
		font-size: 16px;
		font-weight: 600;
	}

	.like h3 {
		padding: 0 6px;
		width: 93%;
		font-size: 14px;
		font-weight: 400;
		color: #222;
		/* 文字超出的部分隐藏 */
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.like img {
		width: 176px;
		height: 176px;
	}
</style>









12, src/components/home/Recommend.vue
<template>
	<div class="recommend">
		<!-- 插槽 -->
		<Card>
			<span>爆款推荐</span>
		</Card>
		<ul>
			<li v-for="(item,index) in recommendList" :key="index">
				<h2>
					<img :src="item.imgUrl" alt="" />
					<div>
						<h3>{{item.name}}</h3>
						<p>{{item.content}}</p>
						<div class="price">
							<span>¥</span>
							<b>{{item.price}}</b>
						</div>
					</div>
				</h2>
			</li>
		</ul>
	</div>
</template>

<script>
	import Card from '@/components/home/Card.vue'
	export default {
		// 子组件接收父组件(Home)传递过来的数据
		props: {
			recommendList: Array
		},
		data() {
			return {
				// recommendList: [{
				// 	id: 1,
				// 	name: '龙井1号铁观音250g',
				// 	content: '鲜爽甘醇 口粮首先',
				// 	price: '68',
				// 	imgUrl: './images/recommend2.png'
				// }, {
				// 	id: 2,
				// 	name: '龙井2号铁观音250g',
				// 	content: '鲜爽甘醇 口粮首先',
				// 	price: '58',
				// 	imgUrl: './images/recommend2.png'
				// }]
			}
		},
		components: {
			Card
		}
	}
</script>

<style scoped>
	.recommend ul li {
		position: relative;
	}

	.recommend ul li h2 {
		display: flex;
		flex-direction: row;
		text-align: center;
	}

	.recommend ul li img {
		width: 360px;
		height: 144px;
		border-radius: 12px;
	}

	.recommend ul li < div {
		position: absolute;
		right: 0;
		top: 0;
	}

	.recommend ul li < div {
		/* 将div里面的内容定位到最右边 */
		position: absolute;
		right: 0;
		top: 0;
		display: flex;
		flex-direction: column;
		padding: 20px;
	}

	.recommend ul li < div h3 {
		font-size: 12px;
	}

	.recommend ul li < div p {
		font-size: 16px;
	}

	.price {
		margin-top: 25px;
		text-align: right;
		color: red;
	}

	.price span {
		font-size: 14px;
	}
</style>











13, src/components/home/Swiper.vue
<template>
	<div class="swiper-main">
		<swiper :options="swiperOption">
			<swiper-slide v-for='(item,index) in swiperList' :key='index'>
				<img :src="item.imgUrl" alt="" />
			</swiper-slide>
			<!-- 分页器 -->
			<div class="swiper-pagination" slot="pagination"></div>
		</swiper>
		<!--以下看需要添加-->
		<!-- <div class="swiper-scrollbar"></div> -->
		<!-- <div class="swiper-button-next"></div> -->
		<!-- <div class="swiper-button-prev"></div> -->

	</div>
</template>

<script>
	import 'swiper/dist/css/swiper.css'
	import {
		swiper,
		swiperSlide
	} from 'vue-awesome-swiper'
	export default {
		name: 'Swiper',
		// 子组件接收父组件传递过来的数据
		props: {
			swiperList: Array
		},
		data() {
			return {
				// swiperList: [{
				// 		id: 1,
				// 		imgUrl: './images/swiper4.png'
				// 	},
				// 	{
				// 		id: 2,
				// 		imgUrl: './images/swiper5.png'
				// 	},
				// 	{
				// 		id: 3,
				// 		imgUrl: './images/swiper6.png'
				// 	}
				// ],
				swiperOption: { // 展示小圆点
					autoplay: {
						delay: 3000
					},
					loop: true,
					speed: 1000,
					pagination: {
						el: '.swiper-pagination'
					}
				}
			}
		},
		components: {
			swiper,
			swiperSlide
		}
		// async created() {
		// 	// 动态获取数据(示例)
		// 	this.swiperList = await fetch('/api/swiperList').then(res => res.json())
		// }
	}
</script>

<style scoped>
	/* 必须引入的样式 */
	@import 'swiper/dist/css/swiper.css';

	.swiper-main {
		position: relative;
		width: 100%;
		height: 165px;
		/* margin-top: 120px; */
	}

	.swiper-main img {
		width: 100%;
		height: 165px;
	}

	.swiper-container {
		width: 100%;
		height: 165px;
	}

	.swiper-pagination {
		width: 100%;
		/* background-color: red; */
		bottom: 0px;
	}

	::v-deep .swiper-pagination-bullet-active {
		background-color: #b0352f;
	}

	::v-deep .swiper-pagination-bullet {
		margin: 0 10px;
	}
</style>













14, src/components/search/Header.vue
<template>
	<header>
		<!-- 左 -->
		<div class="search-return" @click="goBack">
			<i class="iconfont icon-a-huaban1fuben44"></i>
		</div>
		<!-- 中 -->
		<div class="search-main">
			<i class="iconfont icon-fangdajing"></i>
			<form action="" onsubmit="return false">
				<input type="search" placeholder="搜索你喜欢的..." />
			</form>
		</div>
		<!-- 右 -->
		<div class="search-btn">搜索</div>
	</header>
</template>

<script>
	export default {
		data() {
			return {
				//
			}
		},
		methods: {
			goBack() {
				// 返回
				this.$router.back();
			}
		}
	}
</script>

<style scoped>
	header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 100%;
		height: 44px;
		color: #fff;
		background-color: #b0352f;
	}

	.search-return,
	.search-btn {
		padding: 0 10px;
	}

	.search-return i {
		font-size: 28px;
	}

	.search-main {
		display: flex;
		align-items: center;
		width: 260px;
		height: 30px;
		/* padding: 6px 30px; */
		/* 圆角 */
		border-radius: 12px;
		background-color: #FFFFFF;
	}

	.search-main i {
		padding: 0 10px;
		color: #666666;
	}

	.search-main form {
		display: flex;
		justify-content: center;
		align-items: center;
		width: 100%;
	}

	.search-main form input {
		width: 100%;
	}

	.search-btn {
		font-size: 16px;
	}
</style>












15, src/router/index.js

16, src/store/index.js


17, src/views/Cart.vue
<template>
	<div class="cart">
		这是购物车
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	import Tabbar from '@/components/common/Tabbar.vue'
	export default {
		name: "Cart",
		components: { // 挂载
			Tabbar
		}
	};
</script>

<style>
</style>







18, src/views/Home.vue
<template>
	<div class="home">
		<div class="headers">
			<div class="headers-main">
				<Header></Header>
				<ly-tab v-model="selectId" :items="items" :options="options" @change="changeTab"></ly-tab>
			</div>
		</div>

		<!-- 滚动区域 -->
		<section ref="wrapper">
			<div>
				<div v-for="(item,index) in newData" :key="index">
					<!-- {{item.type}} -->
					<!-- {{item.data}} -->
					<!-- 父组件传值给子组件 -->
					<Swiper v-if="item.type == 'swiperList'" :swiperList="item.data"></Swiper>
					<Icons v-if="item.type == 'iconsList'" :iconsList="item.data"></Icons>
					<Recommend v-if="item.type == 'recommendList'" :recommendList="item.data"></Recommend>
					<Ad v-if="item.type == 'adList'" :adList="item.data"></Ad>
					<Like v-if="item.type == 'likeList'" :likeList="item.data"></Like>
				</div>
			</div>
		</section>
		<Footer></Footer>
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	// import 'ly-tab/lib/ly-tab.css'; // 引入默认样式
	import Header from '@/components/home/Header.vue'
	import Swiper from '@/components/home/Swiper.vue'
	import Icons from '@/components/home/Icons.vue'
	import Recommend from '@/components/home/Recommend.vue'
	import Like from '@/components/home/Like.vue'
	import Ad from '@/components/home/Ad.vue'
	import Footer from '@/components/home/Footer.vue'
	import Tabbar from '@/components/common/Tabbar.vue' // 引入

	// 引入插件
	import BetterScroll from 'better-scroll'
	import axios from 'axios'

	export default {
		name: "Home",
		data() {
			return {
				selectId: 0,
				items: [],
				newData: [],
				oBetterScroll: '',
				tBetterScroll: '',
				// topBar: [],
				// items: [{
				// 		label: '推荐'
				// 	},
				// 	{
				// 		label: '大红袍'
				// 	},
				// 	{
				// 		label: '绿茶'
				// 	},
				// 	{
				// 		label: '铁观音'
				// 	},
				// 	{
				// 		label: '普洱'
				// 	},
				// 	{
				// 		label: '茶具'
				// 	},
				// 	{
				// 		label: '花茶'
				// 	},
				// 	{
				// 		label: '设计'
				// 	}
				// ],
				options: {
					activeColor: "#b0352f", // 激活状态的颜色
					// fixBottom: false, // 是否固定在底部
					// reBoundExponent: 100, // 回弹指数
					// reBoundingDuration: 360 // 回弹持续时间
				}
			}
		},
		components: { // 挂载
			Header,
			Swiper,
			Icons,
			Recommend,
			Like,
			Ad,
			Footer,
			Tabbar
		},
		// 接口请求放到create(){}里面
		create() {
			this.getData();
			// axios({
			// 	url: '/api/home'
			// }).then(res => {
			// 	console.log(res);
			// })
		},
		// mounted() {
		// 	console.log(this.$refs.wrapper) // 获取DOM节点
		// 	let bs = new BetterScroll(this.$refs.wrapper, {
		// 		movable: true,
		// 		zoom: true
		// 	})
		// },
		methods: {
			async getData() {
				let res = await axios({
					url: '/api/index_list/0/data/1'
				});

				this.items = Object.freeze(res.data.data.topBar);
				this.newData = Object.freeze(res.data.data.data);
				// console.log(Object.freeze(res.data.data.data)); // []
				// this.topBar = res.data.data.topBar;
				// console.log(res.data.data.topBar);

				// 当 dom 都加载完毕再去执行
				this.$nextTick(() => {
					this.oBetterScroll = new BetterScroll(this.$refs.wrapper, {
						movable: true,
						zoom: true
					})
				})
			},
			// 负责点击请求
			async addData(index) {
				let res = await axios({
					url: '/api/index_list/' + index + '/data/1'
				});
				// console.log(res);

				if (res.data.data.constructor != Arrat) {
					this.newData = res.data.data.data;
				} else {
					this.newData = res.data.data;
				}
				// 当 dom 都加载完毕再去执行
				this.$nextTick(() => {
					this.tBetterScroll = new BetterScroll(this.$refs.wrapper, {
						movable: true,
						zoom: true
					})
				})
			},
			changeTab(item, index) {
				this.addData(index)
				// console.log(index);
			}
		}
	};
</script>

<style scoped>
	.home {
		display: flex;
		flex-direction: column;
		width: 100vw;
		height: 100vh;
		overflow: hidden;
	}

	section {
		flex: 1;
		margin-top: 120px;
		overflow: hidden;
	}

	.headers {
		/* position: fixed;
		top: 0;
		left: 0; */
		width: 100%;
		height: 108px;
	}

	.headers-main {
		position: fixed;
		top: 0;
		left: 0;
	}

	::v-deep.ly-tabaar {
		box-shadow: none;
		border-bottom: none;
	}
</style>












<template>
	<div class="list">
		这是分类
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	import Tabbar from '@/components/common/Tabbar.vue'
	export default {
		name: "List",
		components: { // 挂载
			Tabbar
		}
	};
</script>

<style>
</style>19, src/views/List.vue













20, src/views/My.vue
<template>
	<div class="my">
		这是我的
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	import Tabbar from '@/components/common/Tabbar.vue'
	export default {
		name: "My",
		components: { // 挂载
			Tabbar
		}
	};
</script>

<style>
</style>













<template>
	<div class="search">
		<header>
			<Header></Header>
		</header>
		<section>
			<div class="search-history">
				<h2>
					<i class="iconfont icon-time"></i>
					<span>历史搜索</span>
					<span>清空历史记录</span>
				</h2>
				<ul>
					<li>茶叶</li>
					<li>茶叶</li>
					<li>茶叶</li>
					<li>茶叶</li>
					<li>茶叶</li>
					<li>茶叶</li>
				</ul>
			</div>
			<!-- <hr />
			<h2>清空搜索记录</h2>
			<div>
				<h1>推荐商品</h1>
				<Like></Like>
			</div> -->
		</section>
		<Tabbar></Tabbar>
	</div>
</template>

<script>
	import Header from '@/components/search/Header.vue'
	import Like from '@/components/home/Like.vue'
	import Tabbar from '@/components/common/Tabbar.vue'
	export default {
		data() {
			return {
				//
			}
		},
		components: {
			Header,
			Like,
			Tabbar
		}
	}
</script>

<style scoped>
	.search {
		display: flex;
		flex-direction: column;
		width: 100vw;
		height: 100vh;
		overflow: hidden;
	}

	section {
		flex: 1;
		background-color: #f5f5f5;
		overflow: hidden;
	}

	.search-history {
		/* padding: 20px; */
	}

	.search-history h2 {
		position: relative;
		padding: 20px;
		font-size: 18px;
		font-weight: 400;
	}

	.search-history h2 i {
		padding-right: 0 3px;
		color: red;
		font-size: 18px;
	}

	.search-history h2 span:last-child {
		/* 固定位置 */
		position: absolute;
		right: 20px;
	}

	.search-history ul {
		display: flex;
		/* 可以换行 */
		flex-wrap: wrap;
		padding: 5px 10px;
	}

	.search-history ul li {
		margin: 10px;
		padding: 3px 6px;
		font-size: 14px;
		border: 1px solid #ccc;
	}
</style>21, src/views/Search.vue











22, App.vue

23, main.js

24, package.json
// const {
// 	defineConfig,
// 	path
// } = require("@vue/cli-service", "path");
// module.exports = defineConfig({
// 	transpileDependencies: true,
// }, devServer: {
// 	// port: 8888, // 修改端口号
// 	proxy: {
// 		'/api': { // 请求前缀,用于匹配请求路径
// 			target: 'http://localhost:3000', // 目标API服务器地址
// 			changeOrigin: true, // 开启代理,改变请求源
// 			pathRewrite: {
// 				'^/api': '' // 重写路径,将前缀'/api'替换为空字符串
// 			}
// 		}
// 	}
// });

let path = require("path");
let webpack = require('webpack');
module.exports = {
	//代理
	devServer: {
		proxy: {
			'/api': {
				target: "http://localhost:3000",
				changeOrigin: true,
				pathRewrite: {
					'^/api': '/api'
				}
			}
		},
	},
	configureWebpack: (config) => {
		config.resolve = {
			extensions: ['.js', '.json', '.vue'],
			alias: {
				'@': path.resolve(__dirname, './src'),
			}
		}
	}
}
25, vue.config.js
// const {
// 	defineConfig,
// 	path
// } = require("@vue/cli-service", "path");
// module.exports = defineConfig({
// 	transpileDependencies: true,
// }, devServer: {
// 	// port: 8888, // 修改端口号
// 	proxy: {
// 		'/api': { // 请求前缀,用于匹配请求路径
// 			target: 'http://localhost:3000', // 目标API服务器地址
// 			changeOrigin: true, // 开启代理,改变请求源
// 			pathRewrite: {
// 				'^/api': '' // 重写路径,将前缀'/api'替换为空字符串
// 			}
// 		}
// 	}
// });

let path = require("path");
let webpack = require('webpack');
module.exports = {
	//代理
	devServer: {
		proxy: {
			'/api': {
				target: "http://localhost:3000",
				changeOrigin: true,
				pathRewrite: {
					'^/api': '/api'
				}
			}
		},
	},
	configureWebpack: (config) => {
		config.resolve = {
			extensions: ['.js', '.json', '.vue'],
			alias: {
				'@': path.resolve(__dirname, './src'),
			}
		}
	}
}
创建子路由
复制代码
children: [{
    path: "list",
    name: "list",
    component: () =>
        import("../views/Search-list.vue"),
}],
相关推荐
_院长大人_3 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
SevgiliD3 小时前
el-table中控制单列内容多行超出省略及tooltip
javascript·vue.js·elementui
Q_Q5110082854 小时前
python+uniapp基于微信小程序的旅游信息系统
spring boot·python·微信小程序·django·flask·uni-app·node.js
哆啦A梦15884 小时前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫4 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
Q_Q5110082854 小时前
python基于web的汽车班车车票管理系统/火车票预订系统/高铁预定系统 可在线选座
spring boot·python·django·flask·node.js·汽车·php
yinuo4 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li5 小时前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
爱看书的小沐5 小时前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine