首先附上该项目地址:vue仿电商平台

该项目主要是仿照电商平台,使用vue-router处理路由,主要实现数据的展示,其中在项目中,自己封装了如下拉框,单选框等可复用组件。

第一:
App.vue: 实现首页的header和footer,content部分采用vue-router方式进行切换。为首页的logo标志添加路由,在任一路由中点击logo都可跳转到首页.同时首页中存在登录,注册,关于,这三个功能的实现采用类似modal模态框的功能来实现。
1. 给logo图片添加路由,点击跳转到首页

<router-link :to="{path: '/'}">
    <img class="header-img" src="./assets/logo.png" />
</router-link>

2.关于登录,注册,关于的dialog组件的实现。
这里以登录dialog的实现为例:

<!-- 登录dialog -->
<myDialog :isShow="isShowLogDialog" @close="closeDialog('isShowLogDialog')">
    <h3 slot="header-info">请登录</h3>
    <!-- 登录表单组件 -->
    <logForm slot="content-info" @has-login="logSuccess"></logForm>
  </myDialog>

dialog.vue: 可复用的dialog弹出框组件,首先会存在一个遮罩层来模拟modal效果,同时弹出框出现和消失时会有动画效果。该弹出框 通过props获得父组件的数据,来控制弹出框的显示和消失。当想要关闭弹出框时,通过this.$emit()来触发父组件事件,在父组件中进行弹出框的关闭。 (因为一般不推荐在子组件中改变通过props获取到的父组件数据。)

<template>
<div class="dialog">
  <div class="dialog-wrap">
    <!-- dialog-cover相当于一个遮罩层,类似于模态框效果 -->
    <div class="dialog-cover" v-show="isShow" @click="closeMyself"></div>
    <!-- 弹出对话框的动画效果 -->
    <transition name="dropDialog">
      <div class="dialog-container" v-show="isShow">
        <div class="dialog-header">
          <slot name="header-info"></slot>
          <div class="dialog-close" @click="closeMyself">x</div>
        </div>
        <div class="dialog-content">
          <slot name="content-info"></slot>
        </div>
      </div>
    </transition>
  </div>
</div>
</template>

<script>
export default {
  props: {
    isShow: false
  },
  data () {
    return {
    }
  },
  methods: {
    closeMyself () {
      this.$emit('close')
    }
  }
}
</script>

登录组件的实现:

<template>
<div class="logForm">
  <div class="login">
    <div class="login-info">
      <label>用户名</label>
      <input class="input" type="text" placeholder="请输入你的用户名" v-model="userName"/>
      <span class="errorInfo">{{userNameError.errorInfo}}</span>
    </div>
    <div class="login-info">
      <label>密&nbsp&nbsp&nbsp码</label>
      <input class="input" type="password" placeholder="请输入你的密码" v-model="passWord" />
      <span class="errorInfo">{{passWordError.errorInfo}}</span>
    </div>
    <div class="login-info">
      <button @click="login">登录</button>
    </div>
    <p class="errorText">{{errorText}}</p>
  </div>
</div>
</template>

<script>
export default {
  data () {
    return {
      userName: '',
      passWord: '',
      errorText: ''
    }
  },
  computed: {
    /* 利用正则表达式进行表单验证 */
    userNameError () {
      let reg = /^[a-zA-Z0-9]{4,12}$/
      let errorInfo, status
      if (!reg.test(this.userName)) {
        status = false
        errorInfo = '用户名长度为4--16位,且只能是数字或字母'
      } else {
        status = true
        errorInfo = ''
      }
      /* 第一次进入错误信息不提示 */
      if (!this.userNameFlag) {
        errorInfo = ''
        this.userNameFlag = true
      }
      return {
        status,
        errorInfo
      }
    },
    passWordError () {
      let reg = /^\w{6,12}$/
      let errorInfo, status
      if (!reg.test(this.passWord)) {
        status = false
        errorInfo = '密码长度为6--12位'
      } else {
        status = true
        errorInfo = ''
      }
      /* 第一次进入错误信息不提示 */
      if (!this.passWordFlag) {
        errorInfo = ''
        this.passWordFlag = true
      }
      return {
        status,
        errorInfo
      }
    }
  },
  methods: {
    login () {
      if (!this.userNameError.status || !this.passWordError.status) {
        this.errorText = '请重新检查你的输入'
      } else {
        this.errorText = ''
        this.$emit('has-login', this.userName)
      }
    }
  }
}
</script>

第二:
Index.vue:App.vue中的content内容,左侧的产品内容及最新消息内容都是以数据的形式渲染出来;右侧中的轮播调用slideShow轮播组件,四个产品以数据的形式进行渲染。每个产品中,点击立即购买按钮会跳转到相应的路由。

slideShow.vue: 可复用的轮播幻灯片组件。由图片和图片说明信息两部分组成。轮播图片数据通过props从父组件中获取,获取到的是一个存放图片信息的数组,为标签绑定图片信息,将所有图片渲染出来。

detail.vue: 算是四个产品详情页信息的控制者吧。采用vue-router路由切换方式展示四个产品的详细信息。为左侧的图片绑定路由映射,根据不同的的路由显示所对应的不同图片。

这个问题的主要是:当点击不同的产品时,会跳转到相应的产品详情页。
我主要是为每一个点击按钮绑定了路由,即:

<router-link :to="{path: 'detail/' + item.toKey}">
    <button>点击购买</button>
</router-link>

其中,toKey的值是指在路由配置中path的值。
这一点的实现现在想来还是比较简单的。
还有一点就是:当我点击不同的产品时,出现的图片是不一样的,所以我为每张图片绑定了路由映射。

 <!-- 为图片绑定路由映射 -->
 <img :src="productImg" />
  imgMap: {
      '/detail/pro1': require('../../assets/board-item-images/1.jpg'),
      '/detail/pro2': require('../../assets/board-item-images/2.jpg'),
      '/detail/pro3': require('../../assets/board-item-images/3.jpg'),
      '/detail/pro4': require('../../assets/board-item-images/4.jpg')
      }
 computed: {
    productImg () {
      return this.imgMap[this.$route.path]
    }
  }

根据路由的变化显示不同的图片。

第三:
可复用单选框组件:

 <!-- 单选radioChoose组件 -->
<radioChoose :selections="colorTypes"       @selectChange="onParamChange('proType', $event)">
</radioChoose>

<template>
  <div class="radioChoose-wrap">
    <ul>
      <li v-for="(item, index) in selections" :class="{active:index===nowIndex}" @click="chooseSelection(index)">
      {{item.name}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: {
    selections: Array
  },
  data () {
    return {
      nowIndex: 0
    }
  },
  methods: {
    chooseSelection (index) {
      this.nowIndex = index
      this.$emit('selectChange', this.selections[index])
    }
  }
}
</script>

单选框组件的实现:主要是从父组件中获得数据,为每一个单选框绑定点击事件,当点击该单选框时,设置当前点击的index等于nowIndex。其中还要注意一点:为每一个单选框绑定 :class=”{active:index===nowIndex}”,只有当index等于nowIndex时,才会显示选中的样式。

第四:
可复用下拉框组件

 <!-- 下拉框selection组件 -->
<selection :selections='districts' @selectChange="onParamChange('proPlaces', $event)">
</selection>

<template>
<div class="selection-wrap">
  <div class="selection-title" @click="toggleDrop">
    <span> {{ selections[nowIndex].name }} </span>
    <div class="arrow"></div>
  </div>
  <div class="selection-list" v-show="isDrop">
    <ul>
      <li v-for="(item,index) in selections" @click="chooseSelection(index)">{{item.name}}</li>
    </ul>
  </div>
</div>
</template>

<script>
export default {
  props: {
    selections: Array
  },
  data () {
    return {
      nowIndex: 0,
      isDrop: false
    }
  },
  methods: {
    toggleDrop () {
      this.isDrop = !this.isDrop
    },
    chooseSelection (index) {
      this.nowIndex = index
      this.isDrop = !this.isDrop
      this.$emit('selectChange', this.selections[this.nowIndex])
    }
  }
}
</script>

下拉框组件的实现:从父组件中获得数据,默认显示数组中的第一个,为显示框设置点击事件,为下拉列表绑定v-show属性,通过点击事件,来改变v-show属性的值,实现下拉列表的显示与隐藏。
还有一点就是实现点击下拉列表中的某一项:文本框中会自动显示点击的内容,这主要是为每一项绑定一个点击函数,函数中传入当前点击的index值,并且设置index等于nowIndex,来实现点击时的切换。

第五:
使用localStorage来存储用户的购买信息。
首先用户获得自己的购买信息,是通过每次选择完商品属性时,通过$emit()向父组件传递当前所选中的信息,然后将这些信息保存在localStorage中。
因为这些信息信息是以json数据的格式进行存储的,而localStorage中只能保存字符串,所以我通过JSON.stringify()将json对象转化为字符串存储在本地存储中,当用户想要查看购买信息是,在从本地存储中获取。

Logo

前往低代码交流专区

更多推荐