张值绫 4 år sedan
förälder
incheckning
9bc64efc8f

+ 2 - 0
.env.development

@@ -0,0 +1,2 @@
+NOOE_ENV="development"
+VUE_APP_APIURL="https://api.it120.cc/xiaochengxu"

+ 2 - 0
.env.production

@@ -0,0 +1,2 @@
+NOOE_ENV="production"
+VUE_APP_APIURL="https://api.it120.cc/noodles"

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+node_modules

+ 5 - 0
babel.config.js

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

+ 0 - 1
demo-demonstration

@@ -1 +0,0 @@
-Subproject commit d6e2277a708a2ec4544538c5100b3aabd9fe52ab

+ 31 - 0
package.json

@@ -0,0 +1,31 @@
+{
+  "name": "demo-demonstration",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "prod": "vue-cli-service serve  --mode production",
+    "prodbuild": "vue-cli-service build --mode production"
+  },
+  "dependencies": {
+    "axios": "^0.21.1",
+    "core-js": "^3.6.5",
+    "vant": "^2.12.22",
+    "vue": "^2.6.11",
+    "vue-router": "^3.2.0",
+    "vuex": "^3.4.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "vue-template-compiler": "^2.6.11"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead"
+  ]
+}

+ 16 - 0
src/App.vue

@@ -0,0 +1,16 @@
+<template>
+  <div id="app">
+    <!-- App页作为公共组件 -->
+    <!-- 我们可以使用router-view组件来实现点击导航不刷新页面的效果,只在当前页面打开内容 -->
+    <router-view/>
+  </div>
+</template>
+
+<style>
+*{
+  /* 当style标签具有该scoped属性时,其CSS将仅应用于当前组件的元素 */
+  /* 当前页面没有用scoped属性,因为App页面作为我们公共组件*/
+  margin: 0px;
+  padding: 0px;
+}
+</style>

+ 0 - 0
src/api/index.js


BIN
src/assets/logo.png


+ 44 - 0
src/components/Header/Header.vue

@@ -0,0 +1,44 @@
+<template>
+    <div>
+        <!-- 头部组件示例 -->
+        <!-- 例如当前模块多个页面需要,我们可以把这个模块封装出来,达到组件复用的效果
+             可以按需载入,也可以全局载入,按照项目需求来完成
+         -->
+        <div v-for="(item,index) in header" :key="index" @click="gethome">
+            <h1 class="h1">{{item.value}}</h1>
+        </div>
+    </div>
+</template>
+
+<script>
+    export default {
+        data(){
+            return{
+                header:[]
+            }
+        },
+        methods:{
+            //获取头部标题
+            getheader(){
+                this.$http.get("/config/values?keys=mallName").then(res=>{
+                    // console.log(res.data.data);
+                    this.header=res.data.data
+                })
+            },
+            //点击事件,当处于其他页面时返回首页
+            gethome(){
+                this.$router.push("/home/homepage" ?"/home/homepage" : "");
+            }
+            
+        },
+        mounted(){
+            this.getheader()
+        }
+    }
+</script>
+
+<style scoped>
+    .h1{
+        text-align: center;
+    }
+</style>

+ 22 - 0
src/main.js

@@ -0,0 +1,22 @@
+import Vue from 'vue'
+import App from './App.vue'
+import router from './router'
+import store from './store'
+
+import axios from "axios"
+//区别开发环境和测试环境
+axios.defaults.baseURL=process.env.VUE_APP_APIURL
+Vue.prototype.$http=axios
+//我们以vant-UI为主模板开发,全局载入
+import Vant from 'vant';
+import 'vant/lib/index.css';
+//引入轮播图组件
+import { Lazyload } from 'vant';
+Vue.use(Lazyload);
+Vue.use(Vant);
+Vue.config.productionTip = false
+new Vue({
+  router,
+  store,
+  render: h => h(App)
+}).$mount('#app')

+ 57 - 0
src/router/index.js

@@ -0,0 +1,57 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+
+
+Vue.use(VueRouter)
+
+const routes = [
+  {
+    //path为路径
+    path: '/home',
+    //name是路由名称
+    name: 'home',
+    //component为引入目录下的XX组件
+    component: () => import('../views/home.vue'),
+    //children为home页面下的子路由
+    children:[
+      {
+        path:'homepage',
+        name:'homepage',
+        component: () => import('../views/Homepage/homepage.vue'),
+      },
+      {
+        path:'menu',
+        name:'menu',
+        component: () => import('../views/Menu/menu.vue'),
+      },
+      {
+        path:'shoppingCart',
+        name:'shoppingCart',
+        component: () => import('../views/ShoppingCart/shoppingCart.vue'),
+      },
+      {
+        path:'my',
+        name:'my',
+        component: () => import('../views/My/my.vue'),
+      },
+    ]
+  },
+  //路由跳转菜品详情页
+  {
+    path:'/menuInfo',
+    nama:'menuInfo',
+    component: () => import('../views/MenuInfo/menuInfo.vue'),
+  },
+  //路由重定向
+  {
+    path:'/',
+    redirect:{"name":"homepage"}
+  }
+]
+
+
+const router = new VueRouter({
+  routes
+})
+
+export default router

+ 57 - 0
src/store/index.js

@@ -0,0 +1,57 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+	state: {
+		carArr: []
+	},
+	mutations: {
+		addCar(state, obj) {
+			obj.check = true
+			// console.log(obj.check)
+			let index = state.carArr.findIndex(val => val.id == obj.id)
+			if (index == -1) {
+				obj.num = 1;
+				state.carArr.push(obj)
+			} else {
+				obj.num += 1
+			}
+		},
+		jia(state, id) {
+			let carArr = [...state.carArr]
+			// console.log(carArr)
+			let index = carArr.findIndex(val => val.id == id)
+			carArr[index].num += 1
+			state.carArr = carArr
+		},
+		jian(state, id) {
+			let carArr = [...state.carArr]
+			let index = carArr.findIndex(val => val.id == id)
+			if (carArr[index].num > 1) {
+				carArr[index].num -= 1
+				state.carArr = carArr
+			}
+		},
+		sc(state, id) {
+			let index = state.carArr.findIndex(val => val.id == id)
+			state.carArr.splice(index, 1)
+		}
+	},
+	getters: {
+		sumPrice(state) {
+			let sum = 0;
+			state.carArr.map(val => {
+				if (val.check == true) {
+					sum += val.minPrice * val.num
+				}
+			})
+			return sum
+		}
+	},
+	actions: {
+	},
+	modules: {
+	}
+})

+ 84 - 0
src/views/Homepage/homepage.vue

@@ -0,0 +1,84 @@
+<template>
+  <div>
+    <!-- 轮播 -->
+    <div class="banner">
+      <van-swipe :autoplay="3000">
+        <van-swipe-item v-for="(image, index) in banner" :key="index">
+          <img v-lazy="image.picUrl" />
+        </van-swipe-item>
+      </van-swipe>
+    </div>
+    <!-- 店铺信息 -->
+    <div v-for="item in subshop" :key="item.id">
+      <p>{{ item.name }}</p>
+      <p>{{ item.address }}</p>
+      <p>
+        营业时间 <span>{{ item.openingHours }}</span>
+      </p>
+      <p>
+        联系电话 <span>{{ item.linkPhone }}</span>
+      </p>
+    </div>
+    <!-- 店家推荐 -->
+    <h1>店家推荐</h1>
+    <div>
+      <van-card
+        v-for="item in shopping"
+        :key="item.id"
+        :price="item.minPrice"
+        :title="item.name"
+        :thumb="item.pic"
+        @click="$router.push(`/menuInfo?id=${item.id}`)"
+      />
+      <!-- 点击事件,路由跳转,这里是简写
+           可以单独写一个方法进行跳转
+        -->
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      banner: [],//轮播图
+      subshop: [],//店铺信息
+      shopping: [],//店铺推荐
+    };
+  },
+  methods: {
+    //获取轮播数据
+    getbanner() {
+      this.$http.get("/banner/list").then((res) => {
+        this.banner = res.data.data;
+      });
+    },
+    //获取店铺信息
+    getsubshop() {
+      this.$http.get("/shop/subshop/list").then((res) => {
+        this.subshop = res.data.data;
+      });
+    },
+    //获取店铺推荐
+    getshopping() {
+      this.$http.post("/shop/goods/list").then((res) => {
+        this.shopping = res.data.data;
+      });
+    },
+  },
+  mounted() {
+    this.getbanner();
+    this.getsubshop();
+    this.getshopping();
+  },
+};
+</script>
+
+<style scoped>
+.banner img {
+  width: 100%;
+}
+h1 {
+  text-align: center;
+}
+</style>

+ 86 - 0
src/views/Menu/menu.vue

@@ -0,0 +1,86 @@
+<template>
+    <div>
+        <pre>       
+      当前页面作为vue简洁版文档攻略,以及需要注意到的地方
+      1. v-if 与 v-show 的区别使用
+      -v-if 是“真正”的条件渲染,因为它会确保在切换过程中
+      条件块内的事件监听器和子组件适当地被销毁和重建。
+      -v-show不管初始条件是什么,元素总是会被渲染,并且
+      只是简单地基于 CSS 进行切换。即通过设置元素的 
+      display:none ,达到显示隐藏的作用。
+      -如果频繁的切换元素的状态,v-if的开销会比较大,
+      因为它涉及到条件块内各组件的重建和销毁,而 v-show 
+      只是切换元素的 css,v-show 的开销比较小。
+      -考虑到开销的问题,如果我们有非常频繁的切换
+      建议采用 v-show当然如果我们不想让别人看到这些 dom,
+      还是需要采用 v-if
+      2. v-for 中唯一标识 key
+      -如果不使用 key,Vue 会使用一种最大限度减少动态元素
+      并且尽可能的尝试就地修改/复用相同类型元素的算法,
+      也就是所谓的就地复用策略。
+      -而使用 key 时,它会基于 key 的变化重新排列元素顺序,
+      并且会移除 key 不存在的元素。key 的作用是辅助判断
+      新旧 vdom 节点在逻辑上是不是同一个对象。
+      -渲染列表时,key 值需要一个唯一确定的 id 来赋值。
+      key 的作用主要是为了高效的更新虚拟 DOM。
+      3. v-for 和 v-if 在同一组件使用
+      -在vue2中 v-for 的优先级大于 v-if 也就是说每次挂载
+      该组件都会每一次循环都会进行一次判断,想要杜绝此类现象,
+      需要在外层包裹一个元素来放置 v-if
+      4. $router 与 $route 的区别
+      -this.$router:全局的 router 实例。通过 vue 根实例中
+      注入 router 实例,然后再注入到每个子组件,从而让整个
+      应用都有路由功能。其中包含了很多属性和对象
+      (比如 history 对象),任何页面也都可以调用其 push(),
+       replace(), go() 等方法。
+      -this.$route:当前激活的路由的信息对象。每个对象都是
+      局部的,可以获取当前路由的 path, name, params, query
+      等属性。
+      5. router 路由
+      -在vue-router中, 我们看到它定义了两个标签 router-link
+      和 router-view 来对应点击和显示部分。router-link 就是定义
+      页面中点击的部分,router-view 定义显示部分,就是点击后,
+      区配的内容显示在什么地方。所以 router-link 还有一个非常
+      重要的属性to,定义点击之后,要到哪里去
+      -配置路由:首先要定义route,  一条路由的实现。它是一个对象,
+      由两个部分组成: path和component.  path 指路径,
+      component 指的是组件。如:{path:’/home’,component:home}
+      这里推荐路由懒加载模式,详细写法在Router文件夹下index中
+      已经配置,可以进行参考
+      -路由模式 
+        -Hash: 使用URL的hash值来作为路由。支持所有浏览器。
+        -History: 以来HTML5 History API 和服务器配置。参考官网中
+        HTML5 History模式
+      6.style里的scoped属性
+      -加scoped后,生成一个data-v-XXXXX的唯一标识,给所在组件的
+      父级全部加唯一标示,达到样式私有化,不污染全局的作用
+      -通过给 dom 增加一个动态属性,然后 css 选择器也额外添加
+      对应的属性来选择该 dom ,达到该样式只作用于含有该
+      属性的 dom,实现组件样式的模块化
+      7. v-on 事件绑定
+      -v-on是用来绑定事件监听器,用在普通元素上时,
+      只能监听原生 DOM 事件。用在自定义元素组件上时,
+      也可以监听子组件触发的自定义事件。
+      - v-on 可以简写为@
+      8. v-bind 属性绑定
+      -可以绑定对象,可以绑定对象的形式,
+      {属性1:boolean,属性2:boolean …}这种形式,我们通过动态绑定
+      这些布尔值,如果布尔值是true的话,说明就会绑定到这个对象的
+      属性名,如果是false的话就不会绑定这个对象的属性名。
+      -还可以写成绑定数组的形式,这种形式[‘active’,‘line’]
+      -还可以绑定方法,方法返回对象或者数组,也就是上两种形式的数据
+      -v-bind 可以用冒号简写
+      9. v-html 与 v-text 
+        </pre>
+    </div>
+</template>
+
+<script>
+    export default {
+        
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 67 - 0
src/views/MenuInfo/menuInfo.vue

@@ -0,0 +1,67 @@
+<template>
+  <div>
+    <div>
+      <p>{{ basicInfo.name }}</p>
+      <p class="images">
+        <img :src="basicInfo.pic" alt="" />
+      </p>
+      <p>¥{{ basicInfo.minPrice }}</p>
+    </div>
+    <div>
+      <van-goods-action>
+        <van-goods-action-icon icon="chat-o" text="客服" />
+        <van-goods-action-icon icon="cart-o" text="购物车" />
+        <van-goods-action-icon icon="shop-o" text="店铺" />
+        <van-goods-action-button
+          type="danger"
+          text="立即购买"
+          @click="onClickButton(basicInfo)"
+        />
+      </van-goods-action>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      basicInfo: [],//当前商品详细信息
+    };
+  },
+  methods: {
+    //获取当前商品
+    getbasicInfo(id) {
+      // console.log(id);
+      this.$http
+        .get("/shop/goods/detail", {
+          params: {
+            id: id,
+          },
+        })
+        .then((res) => {
+          // console.log(res);
+          this.basicInfo = res.data.data.basicInfo;
+        });
+    },
+    //点击进入购物车页面
+    //决定使用vuex状态管理器来存放我们获得到的商品详情信息
+    onClickButton(obj) {
+      // console.log(obj);
+      this.$store.commit("addCar", obj);
+      this.$router.push("/home/shoppingCart");
+    },
+  },
+  mounted() {
+    //$route.query获取地址栏上的信息
+    // console.log(this.$route.query.id);
+    this.getbasicInfo(this.$route.query.id);
+  },
+};
+</script>
+
+<style scoped>
+.images img {
+  width: 100%;
+}
+</style>

+ 15 - 0
src/views/My/my.vue

@@ -0,0 +1,15 @@
+<template>
+    <div>
+        <h1>my</h1>
+    </div>
+</template>
+
+<script>
+    export default {
+        
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 49 - 0
src/views/ShoppingCart/shoppingCart.vue

@@ -0,0 +1,49 @@
+<template>
+    <div>
+        <div class="gos" v-for="item in carArr" :key="item.id">
+            <input type="checkbox" v-model="item.check">
+            <p>
+                <img :src="item.pic" alt="">
+            </p>
+            <div>
+                <p>{{item.name}}  <span>价格 ¥{{item.minPrice}}</span></p>
+            </div>
+            <div>
+                <button @click="jia(item.id)">+</button>
+                <span>{{item.num}}</span>
+                <button @click="jian(item.id)">-</button>
+                <button @click="sc(item.id)">删除</button>
+            </div>
+            <div>
+                <van-submit-bar :price="sumPrice*100" button-text="提交订单"/>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import { mapState ,mapGetters,mapMutations} from "vuex"
+    export default {
+        computed:{
+            ...mapState(['carArr']),
+            ...mapGetters(['sumPrice'])
+        },
+        methods:{
+            ...mapMutations(['jia','jian','sc'])
+        }
+    }
+</script>
+
+<style scoped>
+    .gos{
+        display: flex;
+        justify-content: space-between;
+        height: 15vh;
+        line-height: 15vh;
+        border: 1px solid;
+    }
+    .gos img{
+        width: 15vh;
+        height: 15vh;
+    }
+</style>

+ 55 - 0
src/views/home.vue

@@ -0,0 +1,55 @@
+<template>
+  <div id="box">
+    <!-- home页面作为我们所有组件的父组件,可以用其他单词来进行命名 -->
+
+
+    <!-- 可以看出这里引入了一个组件,这里起到示例作用
+         如果有多个页面需要用到当前模块,我们可以封装
+         一个组件,在有需求的页面里按需载入,起到组件
+         复用的效果 
+      -->
+
+    <!-- 头部 -->
+    <Header></Header>
+    
+    <!-- 主体 -->
+    <div class="content">
+      <router-view></router-view>
+    </div>
+
+    <!-- 底部tab -->
+    <div>
+        <!-- 载入vant的tabbar路由模式,通过路由跳转页面 -->
+        <!-- 这里van-tabbar-item里的to属性跟 router-link里的to属性效果相同 -->
+        <!-- 通过我们的路由路径进行跳转 -->
+      <van-tabbar route>
+        <van-tabbar-item to="/home/homepage" icon="home-o">首页</van-tabbar-item>
+        <van-tabbar-item to="/home/menu" icon="qr-invalid">菜单</van-tabbar-item>
+        <van-tabbar-item to="/home/shoppingCart" icon="shopping-cart-o">购物车</van-tabbar-item>
+        <van-tabbar-item to="/home/my" icon="friends-o">我的</van-tabbar-item>
+      </van-tabbar>
+    </div>
+  </div>
+</template>
+
+<script>
+//这里引入Header组件
+import Header from "../components/Header/Header.vue";
+export default {
+  //这里注册Header组件
+  components: {
+    Header,
+  },
+};
+</script>
+
+<style scoped>
+#box {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+}
+.content {
+  flex: 1;
+}
+</style>

+ 10 - 0
vue.config.js

@@ -0,0 +1,10 @@
+module.exports = {
+    // 基本路径
+    publicPath: './',
+    // 输出文件目录
+    outputDir: 'dist',
+    configureWebpack: {
+      externals: {
+      }
+    }
+  }

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 7985 - 0
yarn.lock