zoukankan      html  css  js  c++  java
  • vue-element-template实战(四)使用mock数据,新增用户管理界面

    实现功能包括:用户列表,搜索,新建和编辑。用户数据:用户名,类型,有效期,备注。

    一、从vue-element-admin复制文件:

      vue-admin-templatesrccomponentsPagination文件夹

      vue-admin-templatesrcutilsscroll-to.js

    二、使用mock.js模拟api返回数据,新建文件/mock/member.js

    import Mock from 'mockjs'
    
    const data = Mock.mock({
      'items|50': [
        {
          id: '@id',
          username: '@name',
          'type|1': ['normal', 'vip', 'admin'],
          timestamp: +Mock.Random.date('T'),
          pageviews: '@integer(300, 5000)'
        }
      ]
    })
    
    export default [
      {
        url: '/vue-admin-template/member/list',
        type: 'get',
        response: config => {
          const { type, username, page = 1, limit = 20, sort } = config.query
    
          let mockList = data.items.filter(item => {
            if (type && item.type !== type) return false
            if (username && item.username.indexOf(username) < 0) return false
            return true
          })
    
          if (sort === '-id') {
            mockList = mockList.reverse()
          }
    
          const pageList = mockList.filter(
            (item, index) => index < limit * page && index >= limit * (page - 1)
          )
    
          return {
            code: 20000,
            data: {
              total: mockList.length,
              items: pageList
            }
          }
        }
      },
      {
        url: '/vue-admin-template/member/detail',
        type: 'get',
        response: config => {
          const { id } = config.query
          for (const memeber of data.items) {
            if (memeber.id === +id) {
              return {
                code: 20000,
                data: memeber
              }
            }
          }
        }
      },
      {
        url: '/vue-admin-template/member/create',
        type: 'post',
        response: _ => {
          return {
            code: 20000,
            data: 'success'
          }
        }
      },
      {
        url: '/vue-admin-template/member/update',
        type: 'post',
        response: _ => {
          return {
            code: 20000,
            data: 'success'
          }
        }
      }
    ]

    三、新建文件/src/api/member.js,放用户操作的相关方法

    import request from '@/utils/request'
    
    export function fetchList(params) {
      console.log('api')
      return request({
        url: '/vue-admin-template/member/list',
        method: 'get',
        params: params
      })
    }
    
    export function fetchMember(id) {
      return request({
        url: 'vue-admin-template/member/detail',
        method: 'get',
        params: { id }
      })
    }
    
    export function createMember(data) {
      return request({
        url: '/vue-admin-template/member/create',
        method: 'post',
        data
      })
    }
    
    export function updateMember(data) {
      return request({
        url: '/vue-admin-template/member/update',
        method: 'post',
        data
      })
    }

    四、新建文件:views/member/index.vue中,渲染用户列表。列表使用elementUI的el-table-column组件。新建和编辑窗口使用el-dialog组件

    <template>
      <div class="app-container">
        <div class="filter-container" style="margin-bottom:10px">
          <el-input
            v-model="listQuery.username"
            placeholder="昵称"
            style=" 200px"
            class="filter-item"
            @keyup.enter.native="handleFilter"
          />
          <el-select
            v-model="listQuery.type"
            placeholder="类型"
            clearable
            class="filter-item"
            style=" 130px"
          >
            <el-option
              v-for="item in userTypeOptions"
              :key="item.key"
              :label="item.display_name+'('+item.key+')'"
              :value="item.key"
            />
          </el-select>
          <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button>
          <el-button
            class="filter-item"
            style="margin-left: 10px"
            type="primary"
            icon="el-icon-edit"
            @click="handleCreate"
          >新建</el-button>
        </div>
        <el-table
          v-loading="listLoading"
          :data="list"
          element-loading-text="Loading"
          border
          fit
          highlight-current-row
        >
          <el-table-column align="center" label="ID" width="95">
            <template slot-scope="scope">{{ scope.$index }}</template>
          </el-table-column>
          <el-table-column label="用户名">
            <template slot-scope="scope">{{ scope.row.username }}</template>
          </el-table-column>
          <el-table-column label="类型" width="110" align="center">
            <template slot-scope="scope"><span>{{ scope.row.type }}</span></template>
          </el-table-column>
          <el-table-column label="Date" width="150px" align="center">
            <template slot-scope="{row}">
              <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="230" class-name="small-padding fixed-width">
            <template slot-scope="{ row, $index }">
              <el-button type="primary" size="mini" @click="handleUpdate(row)">编辑</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination
          v-show="total > 0"
          :total="total"
          :page.sync="listQuery.page"
          :limit.sync="listQuery.limit"
          @pagination="fetchData"
        />
        <!-- 弹出对话框,用于新建用户 -->
        <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
          <el-form
            ref="dataForm"
            :rules="rules"
            :model="temp"
            label-position="left"
            label-width="70px"
            style=" 400px margin-left:50px"
          >
            <el-form-item label="昵称" prop="username">
              <el-input v-model="temp.username" />
            </el-form-item>
            <el-form-item label="密码" prop="password">
              <el-input v-model="temp.password" />
            </el-form-item>
            <el-form-item label="类型" prop="type">
              <el-select
                v-model="temp.type"
                class="filter-item"
                placeholder="Please select"
              ><el-option v-for="item in userTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" /></el-select>
            </el-form-item>
            <el-form-item label="有效期" prop="timestamp">
              <el-date-picker
                v-model="temp.timestamp"
                type="datetime"
                placeholder="Please pick a date"
              />
            </el-form-item>
            <el-form-item label="备注">
              <el-input
                v-model="temp.remark"
                :autosize="{ minRows: 2, maxRows: 4 }"
                type="textarea"
                placeholder="Please input"
              />
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取消</el-button>
            <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">确定</el-button>
          </div>
        </el-dialog>
        <!-- 弹出对话框,用于新建用户 end-->
      </div>
    </template>
    
    <script>
    import { fetchList, createMember, updateMember } from '@/api/member'
    import { parseTime } from '@/utils'
    import Pagination from '@/components/Pagination' // secondary package based on el-pagination
    
    const userTypeOptions = [
      { key: 'normal', display_name: '普通会员' },
      { key: 'vip', display_name: 'VIP' },
      { key: 'admin', display_name: '管理员' }
    ]
    
    export default {
      components: { Pagination },
      filters: {
        statusFilter(status) {
          const statusMap = { published: 'success', draft: 'gray', deleted: 'danger'
          }
          return statusMap[status]
        },
        parseTime(time, cFormat) {
          return parseTime(time, cFormat)
        }
      },
      data() {
        return {
          list: null,
          listLoading: true,
          total: 0,
          listQuery: { page: 1, limit: 20, username: undefined, type: undefined, sort: '+id'
          },
          userTypeOptions,
          sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }
          ],
          temp: { id: undefined, remark: '', timestamp: new Date(), username: '', password: '', type: ''},
          dialogFormVisible: false,
          dialogStatus: '',
          textMap: { update: '编辑', create: '新建' },
          // 编辑用户信息-表单验证
          rules: {
            username: [{
              required: true, message: 'username is required', trigger: 'blur' }],
            password: [{ required: true, message: 'password is required', trigger: 'blur' }],
            type: [{ required: true, message: 'type is required', trigger: 'change' }],
            timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }]
          }
        }
      },
      created() {
        this.fetchData()
      },
      methods: {
        // get memebers list
        fetchData() {
          this.listLoading = true
          fetchList(this.listQuery).then(response => {
            this.list = response.data.items
            this.total = response.data.total
            setTimeout(() => { this.listLoading = false }, 500)
          })
        },
        handleFilter() {
          console.log('search', this.listQuery.username)
          this.fetchData()
        },
    
        // open the dialog
        handleCreate() {
          this.resetTemp()
          this.dialogStatus = 'create'
          this.dialogFormVisible = true
          this.$nextTick(() => {
            this.$refs['dataForm'].clearValidate()
          })
        },
    
        // add a memeber
        createData() {
          this.$refs['dataForm'].validate(valid => {
            if (valid) {
              this.temp.id = parseInt(Math.random() * 100) + 1024 // mock a id
              this.temp.author = 'vue-element-admin'
              createMember(this.temp).then(() => {
                this.list.unshift(this.temp)
                this.dialogFormVisible = false
                this.$notify({
                  title: 'Success',
                  message: 'Created Successfully',
                  type: 'success',
                  duration: 2000 })
              })
            }
          })
        },
    
        handleUpdate(row) {
          this.temp = Object.assign({}, row) // copy obj
          this.temp.timestamp = new Date(this.temp.timestamp)
          this.dialogStatus = 'update'
          this.dialogFormVisible = true
          this.$nextTick(() => {
            this.$refs['dataForm'].clearValidate()
          })
        },
    
        updateData() {
          this.$refs['dataForm'].validate(valid => {
            if (valid) {
              const tempData = Object.assign({}, this.temp)
              tempData.timestamp = +new Date(tempData.timestamp) // change Thu Nov 30 2017 16:41:05 GMT+0800 (CST) to 1512031311464
              updateMember(tempData).then(() => {
                const index = this.list.findIndex(v => v.id === this.temp.id)
                this.list.splice(index, 1, this.temp)
                this.dialogFormVisible = false
                this.$notify({
                  title: 'Success',
                  message: 'Update Successfully',
                  type: 'success',
                  duration: 2000
                })
              })
            }
          })
        },
    
        resetTemp() {
          this.temp = { id: undefined, remark: '', timestamp: new Date(), title: '', type: ''
          }
        }
      }
    }
    </script>

    五、在/mock/index.js中注册新增的member。少了这一步,就会返回404错误代码。

    import Mock from 'mockjs'
    import { param2Obj } from '../src/utils'
    
    import member from './member'
    
    const mocks = [
      ...member
    ]

    PS:如果想行高低点,可修改views/member/index.vue代码

    <el-table
          v-loading="listLoading"
          :data="list"
          :row-style="{height:0+'px'}"
          :cell-style="{padding:0+'px'}"
          element-loading-text="Loading"
          border
          fit
          highlight-current-row
        >

    以上亲测,可行。

  • 相关阅读:
    网易2019校招C++研发工程师笔试编程题
    牛客网 数串
    ps aux 状态介绍
    阿里在线测评解析
    Ubuntu 18.04安装 Sublime
    file '/grub/i386-pc/normal.mod' not found.解决方案
    解决Windows10与Ubuntu系统时间不一致问题
    进程与线程的区别
    大端模式和小端模式
    2016湖南省赛----G
  • 原文地址:https://www.cnblogs.com/windok/p/13155398.html
Copyright © 2011-2022 走看看