一,效果展示
二,效果概要
tab切换
获取api中的数据
点击换css样式
渲染页面
三,技术要求
熟悉element组件库
掌握vue-cli脚手架
掌握vue-router路由
掌握vuex库
vue中v-for的使用
vscode编辑器
四,实现效果
1.首先调用后端给的借口api中的方法,将data数据拿到
getClassify().then(({data}) => {
// console.log(data);
this.classify = data;
if(!this.$route.query.classify){
this.classifyType = this.classify[0].list[0].type; // 1-1
this.classifyName = this.classify[0].parent_type; // 1
this.$router.push({
query:{
classify: this.classifyType,
page:1
}
})
}
});
getProperty().then(({data})=>{
this.properties = data;
// console.log(data)
const {query} = this.$route;
this.propertyType = this.properties.reduce((o,item)=>{
// item.title : 工艺,难度,口味,人数
o[item.title] = query[item.title] ? query[item.title]: "";
if(o[item.title]){
this.propertiesActivName.push(o[item.title][0]);
}
return o;
},{});
});
2.v-for渲染页面
<div class="recipe">
<!-- 菜谱分类 start -->
<el-tabs type="border-card"
v-model="classifyName"
>
<el-tab-pane
v-for="item in classify"
:key="item.parent_type"
:label="item.parent_name"
:name="item.parent_type"
>
<div class="recipe-link">
<router-link
:to="{query:{...$router.query,classify:option.type}}"
v-for="option in item.list"
:key="option.type"
:class="{active:classifyType === option.type}"
>
{{option.name}}
</router-link>
</div>
</el-tab-pane>
</el-tabs>
<!-- 菜谱分类 end -->
<h2>家常好味道,给你家一般的温暖</h2>
<!-- 容器 -->
<!-- 左侧列表 -->
<!-- 右侧显示 -->
<!-- 容器 -->
<el-container>
<el-aside width="220px" class="recipe-aside">
<div class="filter-box">
<h4>筛选</h4>
<!-- v-model="activeName" -->
<!-- 筛选 start -->
<el-collapse v-model="propertiesActivName">
<el-collapse-item
v-for="item in properties"
:key="item.parent_type"
:title="item.parent_name"
:name="item.parent_type"
>
<div class="filter-tags">
<el-tag type="info"
v-for="option in item.list"
:key="option.type"
@click="selectedTag(option)"
:class="{'tag-selected': propertyType[item.title] === option.type}"
>
{{option.name}}
</el-tag>
</div>
</el-collapse-item>
</el-collapse>
<!-- 筛选 end -->
</div>
</el-aside>
<el-main class="filter-menus-box">
<menu-card style="min-height: 75%;" :info="list"></menu-card>
<div style="text-align: right;">
<el-pagination
style="display: inline-block;"
:page-size="10"
layout="total, prev, pager, next"
:total="50">
</el-pagination>
</div>
</el-main>
</el-container>
</div>
3.点击效果的实现
selectedTag(option){
let query = {...this.$route.query};
// 判断是否点击, 如果点击过:取消、 否则,选中
if(this.propertyType[option.title] === option.type){
this.propertyType[option.title] = "";
delete query[option.title];
}else{
this.propertyType[option.title] = option.type;
query[option.title] = option.type;
}
this.$router.push({
query
})
},
4.刷新不掉的实现
在data中添加 propertiesActivName:[],取为空
if(o[item.title]){
this.propertiesActivName.push(o[item.title][0]);
}
5.整体代码如下
<template>
<div class="recipe">
<!-- 菜谱分类 start -->
<el-tabs type="border-card"
v-model="classifyName"
>
<el-tab-pane
v-for="item in classify"
:key="item.parent_type"
:label="item.parent_name"
:name="item.parent_type"
>
<div class="recipe-link">
<router-link
:to="{query:{...$router.query,classify:option.type}}"
v-for="option in item.list"
:key="option.type"
:class="{active:classifyType === option.type}"
>
{{option.name}}
</router-link>
</div>
</el-tab-pane>
</el-tabs>
<!-- 菜谱分类 end -->
<h2>家常好味道,给你家一般的温暖</h2>
<!-- 容器 -->
<!-- 左侧列表 -->
<!-- 右侧显示 -->
<!-- 容器 -->
<el-container>
<el-aside width="220px" class="recipe-aside">
<div class="filter-box">
<h4>筛选</h4>
<!-- v-model="activeName" -->
<!-- 筛选 start -->
<el-collapse v-model="propertiesActivName">
<el-collapse-item
v-for="item in properties"
:key="item.parent_type"
:title="item.parent_name"
:name="item.parent_type"
>
<div class="filter-tags">
<el-tag type="info"
v-for="option in item.list"
:key="option.type"
@click="selectedTag(option)"
:class="{'tag-selected': propertyType[item.title] === option.type}"
>
{{option.name}}
</el-tag>
</div>
</el-collapse-item>
</el-collapse>
<!-- 筛选 end -->
</div>
</el-aside>
<el-main class="filter-menus-box">
<menu-card style="min-height: 75%;" :info="list"></menu-card>
<div style="text-align: right;">
<el-pagination
style="display: inline-block;"
:page-size="10"
layout="total, prev, pager, next"
:total="50">
</el-pagination>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import MenuCard from '@/components/menu-card.vue'
import {getClassify, getProperty, getMenus} from '@/service/api';
export default {
components: {MenuCard},
data() {
return {
classify:[], // 存储tab切换的所有数据
classifyType:"1-1", // tab切换的选中项(二级路由)
classifyName:'1', // 定义刷新tab时的值(一级路由)
// 属性
properties:[], // 存储属性中的所有数据
propertyType:{}, // 存储属性的分类. 例如: {craft:1-4, flavor=2-1}
propertiesActivName:[],
list:[]
}
},
watch: {
$route: {
handler(){
const {classify} = this.$route.query;
if(classify){
this.classifyType = classify; // 1-1
this.classifyName = classify[0]; // 1
}
},
immediate:true
}
},
mounted() {
getClassify().then(({data}) => {
// console.log(data);
this.classify = data;
if(!this.$route.query.classify){
this.classifyType = this.classify[0].list[0].type; // 1-1
this.classifyName = this.classify[0].parent_type; // 1
this.$router.push({
query:{
classify: this.classifyType,
page:1
}
})
}
});
getProperty().then(({data})=>{
this.properties = data;
// console.log(data)
const {query} = this.$route;
this.propertyType = this.properties.reduce((o,item)=>{
// item.title : 工艺,难度,口味,人数
o[item.title] = query[item.title] ? query[item.title]: "";
if(o[item.title]){
this.propertiesActivName.push(o[item.title][0]);
}
return o;
},{});
});
this.ThisgetMenus()
},
methods: {
selectedTag(option){
let query = {...this.$route.query};
// 判断是否点击, 如果点击过:取消、 否则,选中
if(this.propertyType[option.title] === option.type){
this.propertyType[option.title] = "";
delete query[option.title];
}else{
this.propertyType[option.title] = option.type;
query[option.title] = option.type;
}
this.$router.push({
query
})
},
ThisgetMenus(){
const query = {...this.$route.query}
const params = {
page:query.page || '1',
classify:query.classify
}
getMenus(params).then(({data}) =>{
console.log(data);
this.list = data.list
})
}
}
}
</script>
<style lang="stylus">
.recipe-link
font-size 0;
margin-top 5px
a
display inline-block
font-size 12px
padding 0px 8px
height 28px
line-height 28px
.active
background #ff3232
color #fff
.recipe
h2
text-align center
line-height 150px
.el-main
padding 0
.filter-box
background #fff
padding 10px
width 100%
float left
box-sizing border-box
.filter-tags
display flex
flex-wrap wrap
justify-content space-around
.tag-selected
background-color #ff3232 !important
color #fff !important
.menu-empty
width 100%
text-align center
font-size 20px
</style>
五,总结
- 本文讲了美食杰菜谱大全功能的实现,界面的布局介绍,如果您还有更好地理解,欢迎沟通
- 定位:分享 &知识点,有兴趣可以继续关注 vue.js html
- 下一篇是对菜谱大全右侧的完善