初始化提交

This commit is contained in:
奇趣保罗 2022-11-09 01:22:19 +08:00
commit 850888a244
28 changed files with 3059 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dist

19
README.md Normal file
View File

@ -0,0 +1,19 @@
# vuestudy
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

9
jsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"target": "es6"
},
"exclude": [
"node_modules",
"dist"
]
}

29
package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "vuestudy",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.4",
"font-awesome": "^4.7.0",
"markdown-it": "^10.0.0",
"vue": "^2.6.11",
"vue-router": "^3.1.5",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.2.0",
"@vue/cli-plugin-router": "~4.2.0",
"@vue/cli-plugin-vuex": "~4.2.0",
"@vue/cli-service": "~4.2.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

18
public/index.html Normal file
View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="zh-cmn-hans" class="font-auto">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.png">
<title><%= htmlWebpackPlugin.options.title %></title>
<meta name="theme-color" content="#27a17e"/>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

46
src/App.vue Normal file
View File

@ -0,0 +1,46 @@
<template>
<div id="app">
<header>
<nav class="head-menu">
<router-link to="/">
<i class="the-icon icon-home"></i>首页
</router-link>
<router-link to="/order">
<i class="the-icon icon-order"></i>点菜
</router-link>
<router-link to="/food">
<i class="the-icon icon-list"></i>菜谱
</router-link>
<router-link to="/user">
<i class="the-icon icon-user"></i>
</router-link>
</nav>
<div class="head-title">
<div class="left-back" v-if="$route.meta.back" @click="$router.go(-1)"><i class="the-icon icon-left"></i></div>
<h2>{{$route.meta.title}}</h2>
<div class="right-actions">
<router-link :to="mitem.link" v-for="(mitem, mkey) in $route.meta.menu" :key="mkey"><i class="the-icon" :class="'icon-' + mitem.icon"></i></router-link>
</div>
</div>
</header>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"/>
</div>
</template>
<style>
@import "./assets/kico.css";
@import "//at.alicdn.com/t/font_1856478_p1cunw448wi.css";
@import "./assets/main.css";
</style>
<script>
export default {
methods: {
}
}
</script>

BIN
src/assets/Avatar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

1422
src/assets/kico.css Normal file

File diff suppressed because it is too large Load Diff

173
src/assets/main.css Normal file
View File

@ -0,0 +1,173 @@
body {
background: #f5f5f5;
}
@media screen and (min-width: 769px) {
body {
margin-top: 3.5em;
}
}
.the-icon {
font-size: inherit;
}
.btn {
border-radius: 0.5em;
}
form .btn{
min-width: 10em;
}
@media screen and (max-width: 600px){
form .btn{
width: 100%;
}
}
input[type*="date"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"],
select, textarea{
background: #fff;
border-color: #ddd;
border-radius: .5em;
}
.head-menu {
display: flex;
color: #fff;
background: var(--green);
z-index: 1;
position: fixed;
top: 0;
left: 0;
right: 0;
}
.head-menu a {
color: inherit;
display: block;
padding: 1em;
}
.head-title {
top: 0;
left: 0;
right: 0;
z-index: 1;
display: flex;
position: static;
background: #fff;
box-shadow: 0 0 1em rgba(0, 0, 0, 0.1);
}
.head-title h2 {
flex: 1 1 auto;
height: 3.75rem;
margin-bottom: 0;
padding: 0.75rem 1rem;
}
.head-title a {
color: inherit;
display: block;
padding: 0.75rem 1rem;
}
.head-title .left-back {
cursor: pointer;
padding: 0.75rem 1rem;
font-size: 1.2em;
}
.head-title .left-back ~ h2{
padding-left: 0;
}
.head-title .right-actions {
display: flex;
}
.head-title .the-icon:before {
/* display: block; */
font-size: 1.25em;
}
@media screen and (max-width: 768px) {
.head-menu {
top: auto;
left: 0;
right: 0;
bottom: 0;
position: fixed;
line-height: 1.25;
font-size: 0.875em;
text-align: center;
color: #666;
background: #fff;
}
.head-menu a {
flex: 1 1 25%;
padding: 0.25em;
}
.head-menu .active {
color: var(--green);
}
.head-menu .the-icon {
display: block;
font-size: 2em;
}
.head-title {
display: flex;
position: fixed;
color: #fff;
background: var(--green);
}
}
@media screen and (min-width: 769px) {
.head-menu .the-icon {
margin-right: 0.5em;
}
.head-menu .active {
box-shadow: 0 -4px 0 var(--yellow) inset;
}
}
section {
margin-bottom: 3em;
}
h1,
h2,
h3 {
font-weight: 300;
}
.wrap {
padding: 0 1em;
}
main {
padding: 2em 0;
}
main.full {
padding: 0;
}
@media screen and (max-width: 768px) {
main {
margin-top: 3.75em;
margin-bottom: 4em;
}
section {
margin-bottom: 2em;
}
}
footer {
margin: 3em 0;
text-align: center;
}

105
src/components/AddFood.vue Normal file
View File

@ -0,0 +1,105 @@
<template>
<form class="row">
<fieldset class="col-m-4">
<label for="">
<span>菜名</span>
<input type="text" v-model="name"/>
</label>
<label for="">
<span>菜式</span>
<select v-model="type">
<option value="all">所有</option>
<option value="1">素菜</option>
<option value="2">荤菜</option>
<option value="3">靓汤</option>
<option value="4">饮料</option>
<option value="5">面点</option>
<option value="6">糕点</option>
</select>
</label>
<label for="">
<span>材料</span>
<select v-model="cate">
<option value="1">猪肉</option>
<option value="2">牛肉</option>
<option value="3">羊肉</option>
<option value="4">鸡肉</option>
<option value="5">鸭肉</option>
<option value="6">鹅肉</option>
</select>
</label>
<label for="">
<span>图片附件</span>
<input type="file" @change="getFile">
</label>
</fieldset>
<fieldset class="col-m-8">
<label for="">
<span>描述</span>
<textarea v-model="desc"></textarea>
</label>
<label for="">
<span>做法</span>
<textarea v-model="proc" rows="5"></textarea>
</label>
<button class="btn green" @click="addFood">添加</button>
<span v-if="msg">{{msg}}</span>
</fieldset>
</form>
</template>
<script>
export default {
name: "AddFood",
data() {
return {
name: "",
type: "1",
cate: "1",
desc: "",
proc: "",
msg: ""
};
},
mounted: function () {
//this.getData(this.$route.params.foodId);
},
methods: {
getFile: function (ev) {
console.log(ev.target.files);
if(ev.target.files.length){
this.photo = ev.target.files[0];
}
else{
console.log("没传图片,不允许提交!");
}
},
addFood: function (foodID) {
if(!this.name || !this.photo){
this.msg = "缺少必填项目";
return false;
}
let data = new FormData();
data.append('add', "add你个头");
data.append('name', this.name);
data.append('desc', this.desc);
data.append('process', this.proc);
data.append('type', this.type);
data.append("photo", this.photo)
this.$http.post("http://food.backend", data).then(res => {
this.$emit('updateInfo', {
id: "1",
name: this.name,
description: this.desc,
process: this.proc,
type: this.type,
cate: this.cate
});
});
}
}
};
</script>

View File

@ -0,0 +1,89 @@
<template>
<section class="food-wrap">
<router-link class="food-box" v-for="(item, i) in foods" :key="i" :to="{name: 'Food', params: {'foodId': item.id}}">
<figure>
<img :src="item.image" :alt="item.name" />
</figure>
<h4>{{item.name}}</h4>
</router-link>
</section>
</template>
<script>
export default {
name: "FoodBox",
data() {
return {
items: []
};
},
mounted: function () {
//console.log(this);
//this.foods = this.$props.foods;
},
methods: {
},
watch: {
foods: function () {
console.log("食物内容发生了变化");
}
},
props: {
foods: Array
}
};
</script>
<style scoped>
.food-wrap{
display: grid;
grid-gap: 2em;
grid-template-columns: repeat(auto-fill, minmax(13em, 1fr));
}
.food-wrap:empty:before{
content: "暂无内容";
background: #ddd;
padding: 1em;
border-radius: 1em;
}
@media screen and (max-width: 600px){
.food-wrap{
grid-gap: 1.5em;
grid-template-columns: repeat(auto-fill, minmax(10em, 1fr));
}
}
.food-box{
color: inherit;
display: flex;
cursor: pointer;
text-align: center;
flex-direction: column;
}
.food-box:hover img{
transform: scale(1.1);
}
.food-box figure{
flex: 1 1 auto;
overflow: hidden;
background: bisque;
}
.food-box img{
transition: transform .3s;
}
.food-box h4{
color: #fff;
padding: 0.75em 0;
position: relative;
font-weight: normal;
margin: -1em 1em 0 1em;
background: var(--yellow);
box-shadow: 0 5px 10px rgba(0, 0, 0, .1);
}
</style>

View File

@ -0,0 +1,95 @@
<template>
<section class="food-wrap">
<div class="food-list" v-for="(item, i) in foods" :key="i">
<router-link :to="{name: 'Food', params: {'foodId': item.id}}">
<img :src="item.image" :alt="item.name" />
</router-link>
<div class="food-info">
<h4>{{item.name}}</h4>
<div class="food-action" @click="this.props.remove(item)">删除</div>
</div>
</div>
</section>
</template>
<script>
export default {
name: "FoodBox",
data() {
return {
items: []
};
},
mounted: function () {
//console.log(this);
//this.foods = this.$props.foods;
},
methods: {
},
watch: {
foods: function () {
console.log("食物内容发生了变化");
}
},
props: {
foods: Array,
remove: Function
}
};
</script>
<style scoped>
.food-wrap:empty:before{
padding: 1em;
display: block;
content: "暂无内容";
background: #fff;
text-align: center;
color: rgba(0, 0, 0, .5);
}
.food-list{
color: inherit;
display: flex;
position: relative;
margin-bottom: 1em;
background: #fff;
}
.food-list:last-child{
margin-bottom: 0;
}
.food-list img{
width: 5em;
height: 5em;
object-fit: cover;
}
.food-list .food-info{
padding: 1em;
flex: 1 1 auto;
}
.food-list .food-action{
right: .5em;
bottom: .5em;
height: 2em;
color: #fff;
line-height: 2;
cursor: pointer;
padding: 0 1em;
opacity: 0;
transition: opacity .3s;
position: absolute;
border-radius: 5em;
background: var(--red);
}
.food-list .food-info:hover .food-action{
opacity: 1;
}
</style>

View File

@ -0,0 +1,95 @@
<template>
<section class="page-navigator">
<div class="item page-prev" v-if="pageNum > 1" @click="change(pageNum - 1)">&lt;</div>
<div class="item"
v-for="(v, i) in pageNums"
:key="i"
:class="{active: pageNum == v}"
@click="change(v)"
>{{v}}</div>
<div class="item page-next" v-if="pageNum != totalPage" @click="change(pageNum + 1)">&gt;</div>
</section>
</template>
<style>
.page-navigator{
display: flex;
user-select: none;
text-align: center;
justify-content: center;
}
.page-navigator .item{
width: 2em;
padding: 0.5em;
cursor: pointer;
background: #fff;
}
.page-navigator .item.active{
color: #fff;
background: var(--green);
}
</style>
<script>
export default {
data: () => {
return {
offset: 20,
totalPage: 0,
pageNums: []
};
},
props: {
pageNum: {
type: Number,
default: 1,
},
pageTotal: {
type: Number,
},
},
methods: {
change(page) {
this.$emit("pageChange", page);
// $emit
//this.$parent.setPage(page);
},
refresh() {
//
let left = [], right = [];
//
if (this.pageNum > 1) {
for (let v = 1; v < this.pageNum; v++) {
left.push(v);
}
}
// 3
if (left.length > 3) left.splice(0, left.length - 3);
//
if (this.pageNum < this.totalPage) {
for (let v2 = this.pageNum + 1; v2 <= this.totalPage; v2++) {
right.push(v2);
}
}
// 3
if (right.length > 3) right.splice(3, right.length);
//
this.pageNums = [...left, this.pageNum, ...right];
},
},
watch: {
pageNum() {
this.totalPage = Math.ceil(this.pageTotal / this.offset);
//
this.refresh();
},
pageTotal() {
this.totalPage = Math.ceil(this.pageTotal / this.offset);
//
this.refresh();
},
},
};
</script>

51
src/main.js Normal file
View File

@ -0,0 +1,51 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
// let API_URL = "http://food.backend";
let API_URL = "//food.cstack.top/api/";
Vue.prototype.$serv = API_URL;
Vue.prototype.$http = axios.create({baseURL: API_URL});
Vue.config.productionTip = false
class Order {
static get(){
let item;
if(!localStorage.getItem("today-order")){
item = {
b: [],
l: [],
d: []
};
}
else{
item = JSON.parse(localStorage.getItem("today-order"))
}
return item;
}
static add(type, item){
console.log(type, item);
let a = this.get();
a[type].push(parseInt(item));
localStorage.setItem("today-order", JSON.stringify(a));
}
}
Vue.prototype.$order = Order;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

113
src/router/index.js Normal file
View File

@ -0,0 +1,113 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Order from '../views/Order.vue'
//require('font-awesome');
require('../../node_modules/font-awesome/css/font-awesome.min.css');
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home,
meta: {
title: "首页"
}
},
{
path: '/order',
name: 'Order',
component: Order,
meta: {
title: "点菜"
}
},
{
path: '/food',
name: 'List',
component: () => import('../views/Food/Index.vue'),
meta: {
title: "菜谱",
keepAlive: true,
menu: [
{
icon: "add",
link: "/food/add"
},
{
icon: "search",
link: "/food/search"
}
]
}
},
{
path: '/food/add',
name: 'FoodAdd',
component: () => import('../views/Food/Add.vue'),
meta: {
title: "增加菜品",
back: true
}
},
{
path: '/food/:foodId',
name: 'Food',
component: () => import('../views/Food/Item.vue'),
meta: {
title: "菜品详情"
}
},
{
path: "/user",
name: "User",
component: () => import('../views/User/Index.vue'),
meta: {
title: "我的"
}
},
{
path: "/user/profile",
name: "UserProfile",
component: () => import('../views/User/Profile.vue'),
meta: {
title: "个人资料",
back: true
}
},
{
path: "/user/settings",
name: "UserSettings",
component: () => import('../views/User/Settings.vue'),
meta: {
title: "偏好设置",
back: true
}
}
/*{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" '../views/About.vue')
}*/
]
const router = new VueRouter({
routes,
linkExactActiveClass: "active",
});
router.beforeEach((to, from, next) => {
if(to.meta.title) {
document.title = to.meta.title + " - 菜管"; //在路由里面写入的meta里面的title字段
}
next();
});
export default router

15
src/store/index.js Normal file
View File

@ -0,0 +1,15 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})

74
src/views/Food/Add.vue Normal file
View File

@ -0,0 +1,74 @@
<template>
<main>
<section class="add-food">
<div class="wrap">
<AddFood @updateInfo="add"/>
</div>
</section>
</main>
</template>
<script>
import AddFood from '@/components/AddFood.vue'
import FoodBox from '@/components/FoodBox.vue'
export default {
name: "Food",
data() {
return {
list: [], //
list_filted: [], //
input: {
type: "all",
cate: 1,
search: ""
},
filted: false
};
},
methods: {
add: function (data) {
if(this.input.type === "all" || this.input.type === data.type || this.input.cate === data.cate){
data.image = "http://food.backend/img/" + data.name + ".jpg"
this.list.push(data);
this.list_filted.push(data);
}
},
filter: function () {
if(this.input.search){
this.list_filted = this.list.filter((item) => {
return item.name.includes(this.input.search);
})
}
else{
this.list_filted = this.list;
}
},
refresh: function () {
this.getData(this.input.type);
},
getData: function (catID = "n") {
this.$http.get("", { params: {type: catID}}).then(res => {
res.data.forEach(item => {
item.image = "http://food.backend/img/" + item.name + ".jpg"
});
this.list = res.data;
this.list_filted = this.list;
});
}
},
mounted: function () {
this.getData(this.input.type);
},
components: {
AddFood,
FoodBox
},
props: {
msg: String
}
};
</script>

117
src/views/Food/Index.vue Normal file
View File

@ -0,0 +1,117 @@
<template>
<main>
<section class="food-list">
<div class="wrap">
<form style="margin-bottom: 2em">
<fieldset class="inline">
<label for="">
<span>菜式</span>
<select v-model="type" @change="byType">
<option value="all">所有</option>
<option value="1">素菜</option>
<option value="2">荤菜</option>
<option value="3">靓汤</option>
<option value="4">饮料</option>
<option value="5">面点</option>
<option value="6">糕点</option>
</select>
</label>
<label for="">
<span>材料</span>
<select v-model="cate">
<option value="1">猪肉</option>
<option value="2">牛肉</option>
<option value="3">羊肉</option>
<option value="4">鸡肉</option>
<option value="5">鸭肉</option>
<option value="6">鹅肉</option>
<option value="7">海鲜</option>
</select>
</label>
<label for="">
<span>关键词</span>
<input type="text" v-model="searchKey"/>
</label>
<label for="">
<button class="btn green" @click="bySearch">筛选</button>
</label>
</fieldset>
</form>
<FoodBox :foods="list"/>
<PageNav :pageNum="page" :pageTotal="total" @pageChange="togglePage"/>
</div>
</section>
</main>
</template>
<script>
import FoodBox from '@/components/FoodBox.vue'
import PageNav from '@/components/PageNav.vue'
export default {
name: "Food",
data() {
return {
page: 1,
total: 0,
list: [],
getMethod: {},
type: "all",
cate: 1,
searchKey: ""
};
},
methods: {
bySearch: function () {
this.getMethod = {
search: this.searchKey
};
this.getData();
},
byType: function () {
this.getMethod = this.type !== "all" ? {
type: this.type
} : {};
this.getData();
},
getData: function () {
let data = {
num: this.page
};
for(let item in this.getMethod){
data[item] = this.getMethod[item];
}
this.$http.get("food/page/", {
params: data
}).then(res => {
this.list = res.data.data;
this.total = res.data.count;
});
},
//
togglePage(newPage){
this.page = newPage;
this.getData();
}
},
mounted: function () {
this.getData();
},
components: {
FoodBox,
PageNav
},
props: {
msg: String
}
};
</script>

198
src/views/Food/Item.vue Normal file
View File

@ -0,0 +1,198 @@
<template>
<main class="full">
<section class="food-image">
<div class="the-image" :style="'background-image: url(' + food.image + ')'"></div>
</section>
<section class="food-info" v-if="food">
<div class="wrap min clear">
<div class="box">
<figure class="food-cover">
<img :src="food.image" :alt="food.name"/>
</figure>
<h1>{{ food.name }}</h1>
<div v-if="!edit">
<article>{{ food.description }}</article>
<article v-html="process"></article>
</div>
<form action v-if="edit">
<fieldset>
<textarea rows="3" v-model.lazy="food.description"></textarea>
<textarea rows="8" v-model.lazy="food.process"></textarea>
<label for>
<span>菜式</span>
<select v-model="food.type">
<option value="all">所有</option>
<option value="1">素菜</option>
<option value="2">荤菜</option>
<option value="3">靓汤</option>
<option value="4">饮料</option>
<option value="5">面点</option>
<option value="6">糕点</option>
</select>
</label>
<label for>
<span>材料</span>
<select v-model="food.cate">
<option value="1">猪肉</option>
<option value="2">牛肉</option>
<option value="3">羊肉</option>
<option value="4">鸡肉</option>
<option value="5">鸭肉</option>
<option value="6">鹅肉</option>
</select>
</label>
</fieldset>
<fieldset class="inline">
<label for>
<button class="btn green" @click="updateFood">更新</button>
</label>
<label for>
<button class="btn red" @click="edit = false">取消</button>
</label>
</fieldset>
</form>
<button class="btn green" v-if="!edit" @click="edit = true">编辑</button>
<button class="btn transparent" @click="add_order">添加到菜单</button>
<select v-model="add_order_type">
<option value="b">早餐</option>
<option value="l">午餐</option>
<option value="d">晚餐</option>
</select>
</div>
</div>
</section>
</main>
</template>
<script>
//import Bus from '../EventBus.js'
import md from "markdown-it";
export default {
name: "FoodItem",
data() {
return {
cates: [
["猪肉", "牛肉", "羊肉", "鸡肉", "鸭肉", "鹅肉"]
],
food: [],
process,
edit: false,
add_order_type: "b"
};
},
mounted: function() {
this.getData(this.$route.params.foodId);
},
methods: {
add_order: function () {
this.$order.add(this.add_order_type, this.$route.params.foodId);
},
getData: function(foodID) {
this.$http.get("food/get/", {
params: {
id: foodID
}
}).then(res => {
this.food = res.data.data;
//
if(!this.food.description){
this.food.description = "还没有填写!";
}
if(!this.food.process){
this.food.process = "材料:油、盐\n\n制作方法\n\n- 步骤 1\n- 步骤 2";
}
let mdR = new md();
this.process = mdR.render(this.food.process || "");
});
},
updateFood: function(foodID) {
/*Axios.post("http://food.backend", { params: {food: foodID}}).then(res => {
console.log(res);
})*/
console.log("???");
if (!this.food.description) {
this.msg = "缺少必填项目";
return false;
}
let data = new FormData();
data.append("id", this.$route.params.foodId);
data.append("update", "占位修改而已");
data.append("desc", this.food.description);
data.append("process", this.food.process);
data.append("type", this.food.type);
Axios.post("http://food.backend", data).then(res => {
alert("更新成功");
this.edit = false;
});
}
},
computed: {},
watch: {
cate: function() {
//console.log(this);
console.log("changed to:" + this.$props.cate);
this.getData(this.$props.cate);
}
},
props: {
cate: String
}
};
</script>
<style scoped>
.box {
padding: 1.25em;
margin-top: -15em;
background: #fff;
border-radius: 1em;
position: relative;
box-shadow: 0 0 1em rgba(0, 0, 0, 0.2);
}
@media screen and (max-width: 800px) {
.box {
border-radius: 0;
}
}
.food-image {
overflow: hidden;
}
.food-image .the-image {
min-height: 20em;
height: 40vh;
filter: blur(5px);
opacity: .8;
transform: scale(1.1);
background: center/cover;
}
.food-cover {
margin: auto;
margin-top: -10%;
margin-bottom: 2em;
max-width: 80%;
}
.food-cover img{
border-radius: 1em;
}
.food-info h1 {
text-align: center;
}
.food-info article {
margin-bottom: 2em;
}
</style>

127
src/views/Home.vue Normal file
View File

@ -0,0 +1,127 @@
<template>
<main class="home">
<section>
<div class="wrap">
<h1>欢迎回来~</h1>
<p>今天都想好吃什么了吗</p>
<p>现在的时间是{{ new Date().toLocaleString() }}</p>
</div>
</section>
<section>
<div class="wrap">
<h2>早餐</h2>
<FoodBox/>
<h2>午餐</h2>
<p>还没有设定</p>
<h2>晚餐</h2>
<p>还没有设定</p>
<div class="container">
<div class="grid-content" style="grid-column: 1 / 3; grid-row: 1 / 1">点餐</div>
<div class="grid-content">查看菜谱</div>
<div class="grid-content">我的</div>
<div class="grid-content">历史菜单</div>
<div class="grid-content">5</div>
<div class="grid-content">6</div>
</div>
</div>
</section>
</main>
</template>
<script>
// @ is an alias to /src
import FoodBox from '@/components/FoodBox.vue'
export default {
name: 'Home',
components: {
FoodBox
}
}
</script>
<style>
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 100px 100px 100px;
}
.container div{
color: #fff;
padding: 2em;
}
.grid-content:nth-child(1) {
background: #2ecc71;
animation-delay: 0.2s;
}
.grid-content:nth-child(1):hover {
background: #27ae60;
}
.grid-content:nth-child(2) {
background: #3498db;
animation-delay: 0.4s;
}
.grid-content:nth-child(2):hover {
background: #2980b9;
}
.grid-content:nth-child(3) {
background: #f1c40f;
animation-delay: 0.6s;
}
.grid-content:nth-child(3):hover {
background: #f39c12;
}
.grid-content:nth-child(4) {
background: #e74c3c;
animation-delay: 0.8s;
}
.grid-content:nth-child(4):hover {
background: #c0392b;
}
.grid-content:nth-child(5) {
background: #9b59b6;
animation-delay: 1s;
}
.grid-content:nth-child(5):hover {
background: #8e44ad;
}
.grid-content:nth-child(6) {
background: #1abc9c;
animation-delay: 1.2s;
}
.grid-content:nth-child(6):hover {
background: #16a085;
}
.grid-content:nth-child(7) {
background: #e67e22;
animation-delay: 1.4s;
}
.grid-content:nth-child(7):hover {
background: #d35400;
}
.grid-content:nth-child(8){
background: #95a5a6;
animation-delay: 1.6s;
}
.grid-content:nth-child(8):hover {
background: #7f8c8d;
}
</style>

154
src/views/Order.vue Normal file
View File

@ -0,0 +1,154 @@
<template>
<main>
<section class="order">
<div class="wrap">
<form>
<fieldset class="inline">
<label for="">
<span>选择日期</span>
<input type="date" v-model="date.full">
</label>
</fieldset>
</form>
<h2>今天选择的菜式如下</h2>
<div class="row">
<div class="col-m-4">
<h2>早餐</h2>
<FoodList :foods="todayOrder.b"/>
</div>
<div class="col-m-4">
<h2>午餐</h2>
<FoodList :foods="todayOrder.l"/>
</div>
<div class="col-m-4">
<h2>晚餐</h2>
<FoodList :foods="todayOrder.d" :remove="removeOrder"/>
</div>
</div>
<h2>这些是为你随机挑选的菜式</h2>
<h2>素菜</h2>
<FoodBox :foods="performFoods.su"/>
<h2>荤菜</h2>
<FoodBox :foods="performFoods.hun"/>
<h2></h2>
<FoodBox :foods="performFoods.soup"/>
</div>
</section>
</main>
</template>
<script>
import FoodBox from '@/components/FoodBox.vue';
import FoodList from '@/components/FoodList.vue'
let date = new Date();
let month = date.getMonth() > 10 ? (date.getMonth() + 1) : "0" + (date.getMonth() + 1);
let day = date.getDate() > 10 ? date.getDate() : "0" + date.getDate();
export default {
name: "Order",
data() {
return {
todayOrder: {
b: [],
l: [],
d: []
},
performFoods: {
su: [],
hun: [],
soup: []
},
date: {
full: date.getFullYear() + "-" + month + "-" + day,
year: null,
month: null,
day: 16
}
};
},
components: {
FoodBox,
FoodList
},
props: {
msg: String
},
methods: {
getTodayOrder: function () {
let todayOrder = this.$order.get();
//
if(todayOrder.b.length){
this.$http.get("food/getSome/", {
params: {
ids: JSON.stringify(todayOrder.b)
}
}).then(res => {
this.todayOrder.b = res.data.data;
});
}
//
if(todayOrder.l.length){
this.$http.get("food/getSome/", {
params: {
ids: JSON.stringify(todayOrder.l)
}
}).then(res => {
this.todayOrder.l = res.data.data;
});
}
//
if(todayOrder.d.length){
this.$http.get("food/getSome/", {
params: {
ids: JSON.stringify(todayOrder.d)
}
}).then(res => {
this.todayOrder.d = res.data.data;
});
}
},
getData: function () {
this.$http.get("food/page/", {
params: {
type: 1,
num: 1
}
}).then(res => {
this.performFoods.su = res.data.data;
});
this.$http.get("food/page/", {
params: {
type: 2,
num: 1
}
}).then(res => {
this.performFoods.hun = res.data.data;
});
this.$http.get("food/page/", {
params: {
type: 3,
num: 1
}
}).then(res => {
this.performFoods.soup = res.data.data;
});
},
removeOrder(item){
console.log(item)
}
},
mounted: function () {
this.getTodayOrder();
this.getData();
}
};
</script>

3
src/views/Upload.vue Normal file
View File

@ -0,0 +1,3 @@
<template>
</template>

53
src/views/User/Index.vue Normal file
View File

@ -0,0 +1,53 @@
<template>
<main>
<div class="wrap min">
<section class="user-info">
<img :src="require('../../assets/Avatar.jpg')" alt="保罗" class="avatar">
<h3>保罗</h3>
<p>这人很懒什么都没写</p>
</section>
<section class="user-menu">
<router-link to="/user/profile"><i class="the-icon icon-user"></i>修改资料</router-link>
<router-link to="/user/settings"><i class="the-icon icon-settings"></i>偏好设置</router-link>
</section>
<section class="user-menu">
<a href="#"><i class="the-icon icon-question"></i>反馈建议</a>
<a href="#"><i class="the-icon icon-home"></i>关于作者</a>
<a href="#"><i class="the-icon icon-list"></i>关于本程序</a>
</section>
</div>
</main>
</template>
<style>
.user-info .avatar{
float: left;
max-width: 4.5em;
border-radius: 5em;
margin-right: 1em;
}
.user-info p{
opacity: .6;
font-size: .875em;
}
.user-menu{
background: #fff;
border-radius: 1em;
box-shadow: 0 0 3em rgba(0, 0, 0, .05);
}
.user-menu a{
color: inherit;
padding: 1em;
display: block;
border-bottom: 1px solid #eee;
}
.user-menu a:last-child{
border-bottom: 0;
}
.user-menu .the-icon{
margin-right: .5em;
}
</style>

View File

@ -0,0 +1,30 @@
<template>
<main>
<div class="wrap min">
<form action="#">
<fieldset>
<label>
<span>昵称</span>
<input type="text" placeholder="保罗">
</label>
<label>
<span>性别</span>
<select>
<option value="0">秀吉</option>
<option value="1">汉子</option>
<option value="2">妹纸</option>
</select>
</label>
<label>
<span>个性签名</span>
<textarea rows="3" placeholder="这人很懒,啥都没写"></textarea>
</label>
</fieldset>
</form>
</div>
</main>
</template>
<style>
</style>

View File

@ -0,0 +1,18 @@
<template>
<main>
<div class="wrap min">
<form action="#">
<fieldset>
<label>
<span>设置项目</span>
<input type="checkbox" class="switch">
</label>
</fieldset>
</form>
</div>
</main>
</template>
<style>
</style>