【Vue】仿小米商城系统(二)

【Vue】仿小米商城系统(二)

前言

本项目是基于Vue全家桶的仿小米商城系统,系列笔记(已完结)如下👇🏻

【Vue】仿小米商城系统(一)

【Vue】仿小米商城系统(二)

【Vue】仿小米商城系统(三)

【Vue】仿小米商城系统(四)


🐶项目地址:

点击这里👉vue仿小米商城源码

这里是小飞侠Pan🥳,立志成为一名优秀的前端程序媛!!!

本篇博客收录于我的github前端笔记仓库中,持续更新中,欢迎star~

👉https://github.com/mengqiuleo/myNote




三、商品首页的开发

mixin的使用

//flex布局的复用
@mixin flex($hov:space-between,$col:center) {
  display: flex;
  justify-content: $hov;
  align-items: $col;
}

商标移出和进入

商标其实是一个a标签,a标签的大小是两个图片的大小,要把两个图片包起来。给a标签上设置两个伪类(相当于加了两个伪元素),当鼠标移动到a标签上时,要给第一个元素设置margin-left为负值,这样整个图片就向左移了。

.header-logo{
          display: inline-block;
          width: 55px;
          height: 55px;
          background-color: #FF6600;
          a{
            display: inline-block;
            width: 110px;
            height: 55px;
            &:before{
              content: "";
              @include bgImg(55px,55px,'/imgs/mi-logo.png',55px);
              transition: margin .2s;
            }
            &:after{
              content: "";
              @include bgImg(55px,55px,'/imgs/mi-home.png',55px);
            }
            &:hover:before{
              margin-left: -55px;
              transition: margin .2s;
            }
          }

鼠标移动到菜单上显示下拉列表

给下拉的列表设置定位(绝对定位),子绝父相,然后给下拉元素设置top=上面的高度,left=0。

然后设置hover:,给下拉列表的外层容器(就是设置position:absolute的那个)设置overflow:hidden。

.children{
              position: absolute;//!!!
              top:112px;
              left:0;
              width: 1226px;
              height: 0; //起初children的高度为0,当鼠标移动到上面时才有高度
              opacity: 0;//透明度为0
              overflow: hidden;//!!!
              border-top:1px solid #E5E5E5;
              box-shadow: 0px 7px 6px 0px rgba(0,0,0,0.11);
              z-index: 10;
              transition: all .5s;//!!!
              background-color: #ffffff;
    
    //给外层设置
   &:hover{
              color: $colorA; 
              .children{
                height: 220px;//高度出现
                opacity: 1;
              }
            }

对返回的数据统一样式 --> 使用过滤器

filters:{
    currency(val){
      if(!val) return '0.00';
      return '¥' + val.toFixed(2) + '元';
    }
  }

鼠标移动到左侧菜单上,右侧列表打开

可以使用display:none 和 display:block。

对于六行四列的渲染,可以使用flex,对于外面的ul设置display:flex,并设置排列方式…between。对于里面的li设置flex:1。

和上面的区别是:上面的是从上往下滑的,只要控制height是否为0就行。

而这个是要整个出现,宽高都要设置。

所以用 display:none 和 display:block。


弹框组件实现 --> Modal组件

Modal.vue
<template>
  <transition name="slide">
    <div class="modal" v-show="showModal">
      <div class="mask"></div>
      <div class="modal-dialog">
        <div class="modal-header">
          <span>{{title}}</span>
          <a href="javascript:;" class="icon-close" v-on:click="$emit('cancel')"></a>
        </div>
        <div class="modal-body">
          <slot name="body"></slot>
        </div>
        <div class="modal-footer">
          <!-- 判断是几个按钮 -->
          <a href="javascript:;" class="btn" v-if="btnType==1" @click="$emit('submit')">{{sureText}}</a>
          <a href="javascript:;" class="btn" v-if="btnType==2" @click="$emit('cancel')">{{cancelText}}</a>
          <div class="btn-group" v-if="btnType==3">
            <a href="javascript:;" class="btn" @click="$emit('submit')">{{sureText}}</a>
            <a href="javascript:;" class="btn btn-default" @click="$emit('cancel')">{{cancelText}}</a>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>
<script>
  export default{
    name:'modal',
    props:{
      // 弹框类型:小small、中middle、大large、表单form
      modalType:{
        type:String,
        default:'form'
      },
      // 弹框标题
      title:String,
      // 按钮类型: 1:确定按钮 2:取消按钮 3:确定取消
      btnType:String,
      sureText:{
        type:String,
        default:'确定'
      },
      cancelText:{
        type:String,
        default:'取消'
      },
      showModal:Boolean
    }
  }
</script>

Vue动画:modal.scss
.modal{
  @include position(fixed);
  z-index: 10;
  transition: all .5s;
  .mask{
    @include position(fixed);
    background-color: $colorI;
    opacity: 0.5;
  }
  &.slide-enter-active{
    top:0;
  }
  &.slide-leave-active{
    top:-100%;
  }
  //对于这些顺序都有严格的要求,最好按照官方文档的顺序
  &.slide-enter{
    top:-100%;
  }
  .modal-dialog{
    @include position(absolute,40%,50%,660px,auto);
    background-color: $colorG;
    transform:translate(-50%,-50%);
    .modal-header{
      height:60px;
      background-color: $colorJ;
      padding:0 25px;
      line-height: 60px;
      font-size:$fontI;
      .icon-close{
        @include positionImg(absolute,23px,25px,14px,14px,'/imgs/icon-close.png');
        transition: transform .3s;
        &:hover{
          transform: scale(1.5);
        }
      }
    }
    .modal-body{
      padding:42px 40px 54px;
      font-size:14px;
    }
    .modal-footer{
      height: 82px;
      line-height: 82px;
      text-align: center;
      background-color: $colorJ;
    }
  }
}

首页使用Modal组件
<!-- 加载模态框 -->
    <modal 
    title="提示" 
    sureText="查看购物车" 
    btnType="1" 
    modalType="middle"
    v-bind:showModal="showModal"
    v-on:submit="goToCart"
    v-on:cancel="showModal=false">
    <template v-slot:body>
      <p>商品添加成功!</p>
    </template>
    </modal>

需要注意的是,使用动画的部分必须要用标签进行包裹,在定义动画的时候,在以下类名中定义:

  • v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  • v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

  • v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

  • v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

  • v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

  • v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

对于这些在过渡中切换的类名来说,如果使用一个没有名字的 ,则 v- 是这些类名的默认前缀。因为这里定义name为slide,所以以slide-开头。


图片懒加载

import VueLazyLoad from 'vue-lazyload'
Vue.use(VueLazyLoad,{
  loading:'/imgs/loading-svg/loading-bars.svg'
})

使用vue-lazyload:将:src换成v-lazy即可

// 原来
<img :src="'/imgs/banner-1.png'" alt="">
// 懒加载形式
<img v-lazy="'/imgs/banner-1.png'" alt="">

四、登录页面的开发

用户名和密码都是jack

登录模块
<div class="login-form">
          <h3>
            <span class="checked">帐号登录</span><span class="sep-line">|</span><span>扫码登录</span>
          </h3>
          <div class="input">
            <input type="text" placeholder="请输入帐号" v-model="username">
          </div>
          <div class="input">
            <input type="password" placeholder="请输入密码" v-model="password">
          </div>
          <div class="btn-box">
            <a href="javascript:;" class="btn" @click="login">登录</a>
          </div>
          <div class="tips">
            <div class="sms" @click="register">手机短信登录/注册</div>
            <div class="reg">立即注册<span>|</span>忘记密码?</div>
          </div>
        </div>

在这里插入图片描述


将登录的信息进行保存到vuex
methods:{
    //登录初始为 jack,密码也为jack
    login(){
      //拿到用户输入的账号密码,因为数据是双向绑定的
      let { username,password } = this;
      this.axios.post('/user/login',{
        //这里是简写,key和value一样
        username,
        password
      }).then((res)=>{
        //将信息存到cookie中,expires表示过期时间
        this.$cookie.set('userId',res.id,{expires:'Session'});

        //因为登录成功以后要在首页显示用户名,所以使用vuex进行管理
        // this.$store.dispatch('saveUserName',res.username);
        this.saveUserName(res.username);
        //登录成功,跳转到首页
        this.$router.push({
          name:'index',
          params:{
            from:'login'
          }
        });
      })
    }
 }

上面是登录逻辑的实现,当用户点击登录按钮后,会触发登录所对应的事件函数。

在函数里,要将用户的账号和密码通过axios发送给后端,然后将用户id保存在cookie中,并且跳转到首页,还要对用户名进行vuex管理,因为首页要显示用户名。


注册模块

当用户点击注册按钮后,同样是在methods中定义一个函数

这里默认注册的用户名和密码都是admin1

//注册
    register(){
      this.axios.post('/user/register',{
        username:'admin1',
        password:'admin1',
        email:'admin1@163.com'
      }).then(()=>{
        Message.success('注册成功');
      })
    }

登录后获取用户信息和购物车商品数量

第一次登录进去保存数据到vuex

在刚登录进去的时候,要获取一次用户数据,所以在APP.vue中

  mounted(){
    if(this.$cookie.get('userId')){
      this.getUser();
      this.getCartCount();
    }
  },
  methods:{
    getUser(){
      this.axios.get('/user').then((res)=>{
        this.$store.dispatch('saveUserName',res.username);
      })
    },
    getCartCount(){
      this.axios.get('/carts/products/sum').then((res)=>{
        this.$store.dispatch('saveCartCount',res);
      })
    }
  }

在vuex中设置action和mutation
//action.js

export default{
  saveUserName(context,username){
    context.commit('saveUserName',username);
  },
  saveCartCount(context,count){
    context.commit('saveCartCount',count);
  }
}
//mutation.js

export default{
  saveUserName(state,username){
    state.username = username;
  },
  saveCartCount(state,count){
    state.cartCount = count;
  }
}

在首页读取用户名和购物车数量

这里需要用计算属性:

原因:

​ 组件加载是需要时间的,首先加载APP.vue组件,然后加载首页组件。在首页组件中只是纯渲染,没有请求时间,在APP.vue进去后会执行接口,而接口的调用需要花时间,所以会先在首页组件中读取到变量的值,但此时变量的值为空。相当于先取的值后保存的数据,所以值为空,可以通过计算属性解决。

当值返回后,值发生变化,计算属性会重新计算。

这里使用到了computed计算属性,如果我们将这些数据直接定义在data中,他就是纯渲染,没有请求的时间。当我们进入APP.vue文件时,会执行两个接口请求,执行请求需要一定的时间,执行完获得数据之后,页面数据早已经渲染出来,渲染的值时请求之前的默认值,所以数据就不对了。

使用computed属性,当数据的值发生变化时,computed就会执行,来更新数据,这样就可以保证数据是正确的了。

computed:{
	username(){
      return this.$store.state.username;
    },
    cartCount(){
      return this.$store.state.cartCount;
    }
}
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
你好!对于Vue3仿小米商城项目,有许多资源和教程可供参考。以下是一些步骤和资源,希望对你有所帮助: 1. 准备工作: - 确保你已经安装了Node.js和Vue CLI。如果没有,请先安装它们。 2. 搭建项目: - 使用Vue CLI创建一个新的Vue项目:`vue create mi-mall` - 在创建项目时,选择适合你的配置选项。 3. 导入项目所需的资源: - 可以在小米商城官网或其他资源网站上找到项目所需的图片、CSS等资源。 - 将这些资源导入到你的项目目录中,并在代码中引用它们。 4. 开发页面和组件: - 根据小米商城的页面结构,将其拆分成各个组件。 - 开发每个组件并在页面上使用它们。 5. 实现功能: - 根据小米商城的需求,实现项目的各种功能,比如商品展示、购物车、用户登录等。 - 可以使用Vue的响应式数据和组件间通信来实现这些功能。 6. 样式和布局: - 使用CSS或者CSS预处理器来美化你的项目。 - 通过调整布局和样式来使项目更加符合小米商城的风格。 7. 调试和优化: - 在开发过程中进行调试,确保项目正常运行并修复可能的错误。 - 优化你的代码和性能,使项目更加高效和流畅。 以上是一个大致的步骤,你可以根据自己的需求和实际情况进行调整和扩展。另外,还有一些开源的Vue仿小米商城项目可供参考,你可以搜索一下并学习它们的实现方式。 祝你在Vue3仿小米商城项目中取得成功!如果你有其他问题,我会尽力帮助你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛小y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值