Vue2实现仿小米商城练手项目前端篇(2-首页实现)

这篇具有很好参考价值的文章主要介绍了Vue2实现仿小米商城练手项目前端篇(2-首页实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

缘由

去年寒假里学习了Vue.js,开学后想做一个完整的练手项目实战一下,最后决定模仿小米手机官网做一个网站项目,具体参考了Github上一位作者的项目。
现在已经基本完成了,分享在CSDN作为学习记录。

简介

  1. 技术支持 :该项目采用前后端分离的设计结构,使用Vue2+Vue-Router+Vuex+Axios+ElementUI作为前端技术框架,后端采用了Koa框架,使用MySQL数据库作为数据存储支持。
  2. 项目功能:项目包含登录、注册、商品浏览、商品检索、收藏、购物车、订单生成与结算等功能
  3. 项目页面:项目整体页面分为首页、全部商品、商品详情页、登录注册、我的购物车、我的订单、订单结算等
  4. 后端模式:使用MVC模式,设计对应的模型层、控制层。
  5. 数据支持:使用Github项目中的小米商城数据

首页实现

首页主要分为4个部分:头部信息栏、导航栏、商品列表、底部信息栏。

1. 头部信息栏

头部信息栏主要功能为:登录注册按钮、登录成功后显示用户信息、我的订单、我的收藏、购物车商品数目信息。

效果图

Vue2实现仿小米商城练手项目前端篇(2-首页实现)

Vue2实现仿小米商城练手项目前端篇(2-首页实现)

效果实现

  1. 源码
<template>
  <div class="topbar">
    <div class="nav">
      <ul>
        <li v-if="!this.$store.getters.getUser">
          <el-button type="text" @click="login">登录</el-button>
          <span class="sep">|</span>
          <el-button type="text" @click="register = true">注册</el-button>
        </li>
        <li v-else>
          欢迎
          <el-popover placement="top" width="180" v-model="visible">
            <p>确定退出登录吗?</p>
            <div style="text-align: right; margin: 10px 0 0">
              <el-button size="mini" type="text" @click="visible = false">取消</el-button>
              <el-button type="primary" size="mini" @click="logout">确定</el-button>
            </div>
            <el-button type="text">{{this.$store.getters.getUser.userName}}</el-button>
          </el-popover>
        </li>
        <li>
          <router-link to="/order">我的订单</router-link>
        </li>
        <li>
          <router-link to="/collect">我的收藏</router-link>
        </li>
        <li :class="getNum > 0 ? 'shopCart-full' : 'shopCart'">
          <router-link to="/shoppingCart">
            <i class="el-icon-shopping-cart-full"></i> 购物车
            <span class="num">({{getNum}})</span>
          </router-link>
        </li>
      </ul>
    </div>
  </div>
</template>
  1. 逻辑实现
  • 进入首页之后,判断localStorage内是否存在登录用户,若不存在则设置登录列表初始状态为隐藏。
  • 点击触发 login 事件后更改vuex中的setShowLogin显示登录组件。
  • 登录成功后将用户信息存入vuex中,通过watch监听vuex的登录状态。
  • 若已经登录,从后台查询该用户的购物车信息,并通过vuex中的setShoppingCart方法更新购物车信息,从而获取购物车内的商品数量并显示在头部栏中。
  • 我的订单我的收藏添加路由信息,实现点击跳转对应页面。
<script>
export default {
	data() {
	   return {
	     activeIndex: "", // 头部导航栏选中的标签
	     search: "", // 搜索条件
	     register: false, // 是否显示注册组件
	     visible: false // 是否退出登录
	   };
	},	
	created() {
		if (localStorage.getItem("user")) {
			this.setUser(JSON.parse(localStorage.getItem("user")));
		}
	},
	watch: {
    // 获取vuex的登录状态
    getUser: function(val) {
      if (val === "") {
        	// 用户没有登录
        	this.setShoppingCart([]);
      } else {
	        // 用户已经登录,获取该用户的购物车信息
	        this.$axios.post("/api/user/shoppingCart/getShoppingCart", {
	            user_id: val.user_id
	          }).then(res => {
	            if (res.data.code === "001") {
	              // 001 为成功, 更新vuex购物车状态
	              this.setShoppingCart(res.data.shoppingCartData);
	            } else {
	              // 提示失败信息
	              this.notifyError(res.data.msg);
	            }
	          }).catch(err => {
	            return Promise.reject(err);
	          });
	      	}
    	}
  	},
  	methods: {
	    ...mapActions(["setUser", "setShowLogin", "setShoppingCart"]),
	    login() {
	      // 点击登录按钮, 通过更改vuex的showLogin值显示登录组件
	      this.setShowLogin(true);
	    },
	    // 退出登录
	    logout() {
	      this.visible = false;
	      // 清空本地登录信息
	      localStorage.setItem("user", "");
	      // 清空vuex登录信息
	      this.setUser("");
	      this.notifySucceed("成功退出登录");
	    },
	    // 接收注册子组件传过来的数据
	    isRegister(val) {
	      this.register = val;
	    }
  },
  computed: {
    ...mapGetters(["getUser", "getNum"]);
  }
};
</script>
  1. 登录组件
<div id="myLogin">
  <el-dialog title="登录" width="300px" center :visible.sync="isLogin">
    <el-form :model="LoginUser" :rules="rules" status-icon ref="ruleForm" class="demo-ruleForm">
      <el-form-item prop="name">
        <el-input prefix-icon="el-icon-user-solid" placeholder="请输入账号" v-model="LoginUser.name"></el-input>
      </el-form-item>
      <el-form-item prop="pass">
        <el-input
          prefix-icon="el-icon-view"
          type="password"
          placeholder="请输入密码"
          v-model="LoginUser.pass"
        ></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="medium" type="primary" @click="Login" style="width:100%;">登录</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</div>
<script>
export default {
  name: "MyLogin",
  data() {
    // 用户名的校验方法
    let validateName = (rule, value, callback) => {
      if (!value) {
        return callback(new Error("请输入用户名"));
      }
      // 用户名以字母开头,长度在5-16之间,允许字母数字下划线
      const userNameRule = /^[a-zA-Z][a-zA-Z0-9_]{4,15}$/;
      if (userNameRule.test(value)) {
        this.$refs.ruleForm.validateField("checkPass");
        return callback();
      } else {
        return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
      }
    };
    // 密码的校验方法
    let validatePass = (rule, value, callback) => {
      if (value === "") {
        return callback(new Error("请输入密码"));
      }
      // 密码以字母开头,长度在6-18之间,允许字母数字和下划线
      const passwordRule = /^[a-zA-Z]\w{5,17}$/;
      if (passwordRule.test(value)) {
        this.$refs.ruleForm.validateField("checkPass");
        return callback();
      } else {
        return callback(
          new Error("字母开头,长度6-18之间,允许字母数字和下划线")
        );
      }
    };
    return {
      LoginUser: {
        name: "",
        pass: ""
      },
      rules: {
        name: [{ validator: validateName, trigger: "blur" }],
        pass: [{ validator: validatePass, trigger: "blur" }]
      }
    };
  },
  computed: {
    // 获取vuex中的showLogin,控制登录组件是否显示
    isLogin: {
      get() {
        return this.$store.getters.getShowLogin;
      },
      set(val) {
        this.$refs["ruleForm"].resetFields();
        this.setShowLogin(val);
      }
    }
  },
  methods: {
    ...mapActions(["setUser", "setShowLogin"]),
    Login() {
      this.$refs["ruleForm"].validate(valid => {
        if (valid) {
          this.$axios.post("/api/users/login", {
              userName: this.LoginUser.name,
              password: this.LoginUser.pass
            }).then(res => {
              // “001”代表登录成功,其他的均为失败
              if (res.data.code === "001") {
                this.isLogin = false;
                let user = JSON.stringify(res.data.user);
                localStorage.setItem("user", user);
                this.setUser(res.data.user);
                this.notifySucceed(res.data.msg);
              } else {
                this.$refs["ruleForm"].resetFields();
                this.notifyError(res.data.msg);
              }
            }).catch(err => {
              return Promise.reject(err);
            });
        } else {
          return false;
        }
      });
    }
  }
};
</script> 

2. 导航栏及轮播图

导航栏主要功能为首页、全部商品路由跳转,条件搜索、轮播图显示

效果图

Vue2实现仿小米商城练手项目前端篇(2-首页实现)

效果实现

  1. 路由分配
<el-menu-item index="/">首页</el-menu-item>
<el-menu-item index="/goods">全部商品</el-menu-item>
<el-menu-item index="/about">关于我们</el-menu-item>
  1. 搜索功能
<el-input placeholder="请输入搜索内容" v-model="search">
 	<el-button slot="append" icon="el-icon-search" @click="searchClick"></el-button>
</el-input>

searchClick() {
  if (this.search != "") {
    // 跳转到全部商品页面,并传递搜索条件
    this.$router.push({ path: "/goods", query: { search: this.search } });
    this.search = "";
  }
}
  1. 轮播图
<div class="block">
  <el-carousel height="460px">
    <el-carousel-item v-for="item in carousel" :key="item.carousel_id">
      <img style="height:460px;" :src="$target + item.imgPath" :alt="item.describes" />
    </el-carousel-item>
  </el-carousel>
</div>

// 获取轮播图数据
this.$axios.post("/api/resources/carousel", {})
	.then(res => {
     this.carousel = res.data.carousel;
   }).catch(err => {
     return Promise.reject(err);
   });

3. 商品列表及切换

商品列表主要显示从后台获取到的商品信息

效果图

Vue2实现仿小米商城练手项目前端篇(2-首页实现)
Vue2实现仿小米商城练手项目前端篇(2-首页实现)
Vue2实现仿小米商城练手项目前端篇(2-首页实现)

效果实现

  1. 商品列表
<ul>
  <li v-for="item in list" :key="item.product_id">
    <router-link :to="{ path: '/goods/details', query: {productID:item.product_id} }">
      <img :src="$target +item.product_picture" alt />
      <h2>{{item.product_name}}</h2>
      <h3>{{item.product_title}}</h3>
      <p>
        <span>{{item.product_selling_price}}</span>
        <span
          v-show="item.product_price != item.product_selling_price"
          class="del"
        >{{item.product_price}}</span>
      </p>
    </router-link>
  </li>
  <li v-show="isMore && list.length>=1" id="more">
    <router-link :to="{ path: '/goods', query: {categoryID:categoryID} }">
      浏览更多
      <i class="el-icon-d-arrow-right"></i>
    </router-link>
  </li>
</ul>
getPromo(categoryName, val, api) {
  api = api != undefined ? api : "/api/product/getPromoProduct";
  this.$axios
    .post(api, {
      categoryName
    })
    .then(res => {
      this[val] = res.data.Product;
    })
    .catch(err => {
      return Promise.reject(err);
    });
}
  1. 类别菜单切换
<ul>
  <li
    v-for="item in val"
    :key="item"
    :class="activeClass == item ? 'active':''"
    @mouseover="mouseover($event,item)"
  >
    <router-link to>
      <slot :name="item"></slot>
    </router-link>
  </li>
</ul>
props: ["val"],
name: "MyMenu",
data() {
  return {
    activeClass: 1
  };
},
methods: {
  // 通过mouseover事件控制当前显示的商品分类,1为该类别的热门商品
  mouseover(e, val) {
    this.activeClass = val;
  }
},
watch: {
  // 向父组件传过去当前要显示的商品分类,从而更新商品列表
  activeClass: function(val) {
    this.$emit("fromChild", val);
  }
}

4. 底部信息栏

底部信息栏仅几个链接及样式设计,不作详细介绍。

效果图

Vue2实现仿小米商城练手项目前端篇(2-首页实现)

往期内容

Vue2实现仿小米商城练手项目前端篇(1-项目介绍)文章来源地址https://www.toymoban.com/news/detail-487160.html

到了这里,关于Vue2实现仿小米商城练手项目前端篇(2-首页实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • web前端大作业_Html5+CSS3+JS原生项目_京东商城首页 详细代码

    index.html css index.css js index.js 效果图如下:            

    2024年02月11日
    浏览(46)
  • vue2项目导出操作实现(后端接口导出、前端直接做导出)

    实现效果:导出列表数据 导出的内容: 后台相对来说比较简单一点,只要后端配合写接口即可 代码:放在导出事件里进行调整即可完成导出效果 效果如上:个人认为调接口导出的表格更美观一点 操作如下: 首先安装我们需要的xlxs库: 接着在我们项目文件夹/src/assets/js创建

    2024年04月11日
    浏览(36)
  • 【Vue全家桶高仿小米商城】——(四)项目基础架构

    此章节全力讲解前端基本项目架构,通过此章节可搭建一个通用性的前端架构,内容涵盖跨域方案、路由封装、错误拦截等。 一、前端跨域解决 什么是前端跨域? 跨域是浏览器为了安全而做出的限制策略 浏览器请求必须遵循同源策略: 同域名 、 同端口 、 同协议 怎么解决

    2024年02月10日
    浏览(73)
  • 图书商城项目练习①管理后台Vue2/ElementUI

    本系列文章是为学习Vue的项目练习笔记,尽量详细记录一下一个完整项目的开发过程。面向初学者,本人也是初学者,搬砖技术还不成熟。项目在技术上前端为主,包含一些后端代码,从基础的数据库(Sqlite)、到后端服务Node.js(Express),再到Web端的Vue,包含服务端、管理

    2024年02月11日
    浏览(70)
  • vue尚品汇商城项目-day03【vue插件-19.mockjs模拟数据(开发Home首页当中的ListContainer组件与Floor组件)】

    安装命令:cnpm install --save mockjs 重难点说明 使用swiper实现静态页面轮播 解决多个swiper冲突的问题 解决swiper动态页面轮播的bug 定义可复用的轮播组件 解决Floor组件中轮播有问题的bug 利用mockjs提供模拟数据 Mockjs: 用来拦截ajax请求, 生成随机数据返回 学习 ​ a. http://mockjs.com/ ​

    2023年04月09日
    浏览(41)
  • vue+elementui实现app布局小米商城,样式美观大方,功能完整

    目录 一、项目效果在线预览 二、效果图 1.首页效果图 2.分类,动态分类+商品数据根据所属分类动态切换 3.购物车,动态添加购物车(增、删、改、查) 4.我的 5.登录注册 6.商品详情 7.搜索(动态模糊搜索、搜索历史记录) 8.提交订单-商品详情(单个商品) 9.提交订单-购物

    2024年02月15日
    浏览(75)
  • vue2+vant 简易实现京东app商城(附源码)

    利用 vue2 + vant 模仿京东app商城,实现 首页 、 商品分类页面 、 购物车 、 简易商品详情页 、 登录页 。 ①、创建vue2项目 mobile ②、安装路由模块,vant组件 ①、在 src 目录下创建 views 文件夹,存放页面组件 views 结构如图 ②、在 src 目录下创建 router 文件夹,新建 index.js 文件

    2024年02月11日
    浏览(24)
  • 12-web前端轮播图案例 (小米商城)

    说明: 轮播图在前端开发中是一种常见的元素,通常用于展示一系列的图片或者内容,并通过滑动或者点击的方式进行切换。使用JavaScript来实现轮播图有以下几个意义: 提升用户体验:轮播图可以在有限的空间内展示更多的内容,为用户提供更多的信息。同时,轮播图也具

    2024年02月08日
    浏览(34)
  • 前端实现websocket通信讲解(vue2框架)

    前言 :最近接到的需求是前端需要实现一个全局告警弹窗,如果使用ajax请求http接口只能用定时器定时去请求是否有告警,这样既消耗资源,又不能实时监测到告警信息。所以这个时候就可以采用websocket来实现通信,因为websocket不用请求一次才响应一次,它可以实现服务器主

    2024年02月12日
    浏览(26)
  • Vue2 +Element-ui实现前端页面

    以一个简单的前端页面为例。主要是利用vue和element-ui实现。 里面涉及的主要包括:新建vue项目、一行多个输入框、页面实现等。   ①首先安装nodejs,这部分在此就不讲啦。 ②然后安装vue-cli: 查看是否安装成功: 安装成功之后就输出vue的版本 ③在cmd窗口新建一个vue2脚手架

    2024年02月16日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包