Vue项目-家政服务平台之登录&顾客管理篇

家政服务平台后台管理系统

前言

该文记录博主做项目时的大致流程和遇到的问题及如何解决。

视图:基于vue框架,大量运用ElementUI组件;
数据:从云服务器上通过若干接口传输到项目。
综合运用了项目依赖【dependencies】axios,element-ui,vue,vue-router,vuex
本文是基于其中一个小模块-顾客模块,展开来说的

第一步-项目部署:

有以下三种方法:

  • 部署到自己的云服务器上
  • 部署到本地
  • 直接调用别人已经部署好的接口

这里以部署本地为例(简):

第一步:在Navicat中新建数据库并导入sql文件,设置该数据库的权限等;
第二步:在终端中运行java文件【此时后台数据已经就位】;
第三步:打开vue-admin-template-master半成品框架,执行cnpm install命令完成初始化项目;
第四步:npm run dev跑项目
...

第二步-修改框架

刚到手的框架内的数据基本都是为使用者提供指南的数据,所以我们要将不用的数据/用不到的数据修改或删除。

修改基路径
.env.development
.env.production
两个文件中将原VUE_APP_BASE_API注释掉,替换成不是的接口基路径(修改完需要重启项目才会生效)
# VUE_APP_BASE_API = ‘/prod-api’
VUE_APP_BASE_API = ‘http:/localhost:端口号’

对于登录

登录模块流程

  登录总结:
    第一步index.vue中发送一个登录表单loginForm至状态机中的login方法
    【框架的优越性:只调用一个方法->自己内部逻辑中访问了多个文件夹(方便后期维护项目,大大减少了修改的工作量)】
    第二步login方法拿到token,并将token设置到全局
    第三步在request方法中拿到token,并设置到请求头
    第四步在response方法中判断状态码,若成功200返回成功对象
    第五步push方法跳转至'/'

下面是代码:

  登录方法handleLogin中对refs中的loginForm表单数据valid进行了校验,
  校验中使用了状态机store的dispatch方法,该状态机存在于/src/store/moduler/user.js
  调用了状态机中的login方法,
// @/views/login/index.vue
    handleLogin() {
      // 对refs中名为loginForm的表单进行了校验,校验的值valid
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          // 模态框加载
          this.loading = true
          // 使用了状态机store中user的login方法
          // 该状态机存在于/src/store/moduler/user.js
          console.log(this.loginForm)
          this.$store.dispatch('user/login', this.loginForm).then(() => {
            this.$router.push({ path: this.redirect || '/' })
            this.loading = false
          }).catch(() => {
            this.loading = false
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    }
  向后台提交的数据username、password、type都会被捕捉到this.loginForm
  而状态机会从中解构数据
    login({ commit }, userInfo) {
      const { username, password, type } = userInfo...
  状态机中login方法来自@/api/user 
// @/api/user.js
import request from '@/utils/request'

// 默认到处三个方法
export function login(data) {
  return request({
    url: '/user/login',
    method: 'post',
    data
  })
}

export function getInfo(token) {
  return request({
    url: '/user/info',
    method: 'get',
    params: { token }
  })
}

export function logout() {
  return request({
    url: '/user/logout',
    method: 'post'
  })
}

  login方法中返回的request方法来自@/utils/request
  在request中// 全局最初写后台访问请求的各种方法,
  请求拦截/响应拦截
  请求拦截中判断是否含有token若有则在请求头部添加属性值Authorization=TOKEN
  响应拦截中根据不同的状态码response.data.status做出不同提示信息
    当状态码为200时返回response.data
// @/utils/request
service.interceptors.request.use(
  config => {
    // do something before request is sent

    // 判断请求中是否有token
    if (store.getters.token) {
      // let each request carry token
      // ['Authorization'] is a custom headers key
      // please modify it according to the actual situation
      // 请求头中添加一条属性值
      config.headers['Authorization'] = getToken()
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)
service.interceptors.response.use(...)

登录页面预览:
在这里插入图片描述

对于顾客模块
 一、 修改侧边栏一个路由@/router/index.js
    当路由配置好后发现右边内容区域,是顶格显示:
      选中css样式然后在VScode中点击Search图标,粘贴找到对应css修改
      
  二、布局
    第一件事:打开要参考的原型或网站查看布局
    【在main.js中可以将ElementUI的样式设置为中文/英文】
    load方法:将数据导入
    在分页区域问题:/customer/query方法传参page,pageSize需要的类型是query类型(而默认json字符串)
      这是就需要导入qs,在查询字符串之前qs.stringify(this,params)进行数据转换为查询字符串
      
  三、增删改查
    点击新增/修改时出现模态框,点击删除时获取当前行id
    【外键:用户下单,订单还未完成,不可删除】
    详情按钮:页面跳转
      在方法中通过this.$router.push() - 路由跳转
      跳转过去后,有返回按钮
        Element中的页头样式
      跳转时,携带参数row
        传【handleDetails方法中】 - this.$router.push({ path: 'customerDetails', query: { row }})
        收【created生命周期函数中】 - this.$route.query.row
      详情页面 - ElementUI的Card组件

在@/router/index.js中配置路由,并且在views目录下创建路径
在这里插入图片描述

  // 顾客端
  {
    path: '/customer',
    // 是否侧边栏显示
    component: Layout,
    // 重定向到/customer/index
    redirect: '/customer/index',
    name: 'Customer',
    meta: { title: '顾客管理', icon: 'example' },
    children: [
      {
        // 默认路径
        path: 'customer',
        name: 'Customer',
        // 组件路径
        // 法一:views修改原文件|法二:在views目录下重新创建一个customer|法三:在@/下创建pages自己定义路径
        component: () => import('@/views/customer/index'),
        meta: { title: '顾客管理', icon: 'table' }
      },
      {
        path: 'customerDetails',
        name: 'CustomerDetails',
        // 将顾客看详情隐藏
        hidden: true,
        component: () => import('@/views/customer/customerDetails'),
        meta: { title: '顾客详情', icon: 'tree' }
      }
    ]
  },

页面如下:
在这里插入图片描述在customer/index.vue中大致分为:上方按钮搜索区域、中间表格区域、下方分页区域
这些框架都可以在ElementUI中找到,我们只需要修改其中的数据/参数即可
最后显示的页面布局如下:

在这里插入图片描述在index.vue中导入request方法,并且调用post/get方法进行数据的加载

    load() {
      request.post('/customer/query', qs.stringify(this.params)).then((res) => {
        this.tableData = res.data
      })

新增/修改模态框

    // 新增操作
    add() {
      this.title = '新增顾客'
      this.dialogFormVisible = true
    },
    // onSubmit新增模态框中提交按钮
    onSubmit() {
      request.post('/customer/saveOrUpdate', qs.stringify(this.form)).then((res) => {
        this.$message({
          message: res.message,
          type: 'success'
        })
        // 关闭模态框
        this.dialogFormVisible = false
        // 刷新数据
        this.load()
      })
    },

customerDetails.vue页面(点击【详情】按钮跳转页面)同理,布局如下:
在这里插入图片描述
上方的标签页tabs可以在ElementUI中找到。
其中遇到的问题,时间戳转换:

    formatDate(row, column, cellValue, index) {
      if (cellValue === null || cellValue === '') return ''
      // 时间戳为10位需*1000,如果为13位的话不需乘1000。
      const date = new Date(parseInt(cellValue))
      const Y = date.getFullYear() + '-'
      const M = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) + '-' : date.getMonth() + 1 + '-'
      const D = date.getDate() < 10 ? '0' + date.getDate() + ' ' : date.getDate() + ' '
      const h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':'
      const m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':'
      const s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
      return Y + M + D + h + m + s
    }
<span class="cusDetails">注册时间: </span>{{ formatDate(null, null, info.registerTime, null) }}<br>

遇到了如下浏览器错误:
在这里插入图片描述大致意思为本应传入的数据为数组类型,而传入了对象。。。

  data() {
    return {
      info: {},
      addressInfo: [],
      commentInfo: {},
      orderInfo: {},
      // 基本信息默认
      activeName: 'first',
      // load方法传参id
      id: ''
    }
  },

错误原因就是上方代码中的addressInfo类型,应该将 addressInfo: {}改为 addressInfo: [],错误则消失了。

下面是页头的返回按钮方法:

    // 页头返回键
    goBack() {
      // console.log('go back')
      // 返回上一次
      this.$router.go(-1)
    },

总结:在Element-UI中,我们除了自己要用什么就搬什么之外,还要熟悉其中标签中的属性/方法,这些东西可以让我们事半功倍!说到这,最主要还是要熟悉。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值