权限开发(demo使用教程)

简介: 权限开发(demo使用教程)

bda5ae4820e74f9fad72b14963a0f28e.png

总结一下运行此项目需要安装的插件:

一、router

二、vuex

三、element ui

前三个可以使用vue ui 进行安装

四、安装less   :npm install less -–save-dev

五、安装less-loader(低版本的less-loader):npm install less-loader@5.0.0 --save

六、安装axios:npm install axios --save

七、core-js版本:npm i core-js@3.6.4

八、mokejs:npm install --save mockjs

首先和之前一样把直接创建好的脚手架拿来用

安装三个插件

b6c3b778567247feb221e9e33db17e1a.png

再次用命令安装axios

npm install axios --save

安装完成后的四个插件

05381442cebd465d8184c352a6b7d508.png

运行后的效果

ff617be2acb54fab995b61ef892b5c76.png

接下来开始正式写demo

添加公共样式

6ec60c62ab9a4f3d9d4579befb4af9dd.png

新建Login页面

dfff171ac9d64efca28f5cfed90cfae3.png

<template>
  <div class="container">
    <div class="wrapper">
      <h1>WEB ADMIN</h1>
      <el-form
        label-width="auto"
        :model="form"
        :rules="rules"
        ref="form"
        v-loading="isloading"
      >
        <el-form-item label="用户" prop="username">
          <el-input v-model="form.username" placeholder="请输入用户名">
            <i slot="prefix" class="el-input__icon el-icon-user"></i>
          </el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input
            v-model="form.password"
            placeholder="请输入密码"
            show-password
          >
            <i slot="prefix" class="el-input__icon el-icon-lock"></i>
          </el-input>
        </el-form-item>
        <el-row>
          <el-button type="primary" size="mini" @click="login">登录</el-button>
          <el-button type="success" size="mini" @click="resetForm('form')"
            >重置</el-button
          >
        </el-row>
      </el-form>
    </div>
  </div>
</template>
<script>
export default {
  name: "Login",
  data() {
    return {
      form: {
        username: "admin",
        password: "admin",
      },
      isloading: false,
      rules: {
        username: [
          {
            required: true,
            message: "请输入用户名",
            trigger: "blur",
          },
          {
            min: 3,
            max: 18,
            message: "长度在 3 到 18 个字符",
            trigger: "blur",
          },
        ],
        password: [
          {
            required: true,
            message: "请输入密码",
            trigger: "blur",
          },
          {
            min: 3,
            max: 18,
            message: "长度在 3 到 18 个字符",
            trigger: "blur",
          },
        ],
      },
    };
  },
  methods: {
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    login() {
      /* this.$axios.post('/login',{
      username:this.form.username,
      password:this.form.password
    }).then(res=>{
      console.log(res);
      this.$store.commit('setUser',res.data)
      window.sessionStorage.setItem('token',res.data.token)
      this.$router.push('/')
    }) */
      this.isloading = true;
      this.$api
        .login({
          username: this.form.username,
          password: this.form.password,
        })
        .then((res) => {
          console.log(res);
          this.$store.commit("setUser", res.data);
          window.sessionStorage.setItem("token", res.data.token);
          this.isloading = false;
          this.$router.push("/");
          this.$message({
            message: "恭喜你,登录成功",
            type: "success",
          });
        });
    },
  },
};
</script>
<style scoped="scoped">
.container {
  width: 100%;
  height: 100%;
  position: absolute;
  bottom: 0;
  left: 0;
  overflow: hidden;
  background-color: #2b4b6b;
}
.wrapper {
  width: 500px;
  height: 320px;
  background-color: #fff;
  margin: 120px auto;
}
.wrapper {
  padding: 0 30px;
}
.wrapper h1 {
  color: #666;
  text-align: center;
  padding: 20px 0 30px 0;
}
.el-row {
  float: right;
}
</style>

42311f1be3554fa880712ead7941fbb4.png

页面效果如下:

7ac02904b3064269892de10d6f8bb8a8.png

接下来写NotFound页面

当网址输入错误时将出现404页面

<template>
  <div class="not-found">
    <h1>啊哦!找不到相关页面o(╥﹏╥)o。</h1>
    <router-link to>
      <p @click="$router.back(-1)">返回上一级页面</p>
    </router-link>
  </div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
.not-found {
  width: 100%;
  height: 100vh;
  background-color: #6495ED;
  display: flex;
  justify-content: center;
  align-items: center;
  h1 {
    margin: 0;
    color: #fff;
  }
  a {
    color: #E0FFFF;
    font-size: 14px;
    font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
    transform: translateY(10px);
  }
}
</style>

735b8c48cb8c4b91879ad25f17b3caf7.pngfe64d52dfed24bd9894b00a4097d6f7b.png

引入完毕后安装less-loader插件和less

安装less   :

npm install less -–save-dev

安装less-loader(低版本的less-loader):

npm install less-loader@5.0.0 --save

然后运行,如果会报错的话这里给两个参考方案 ,启动成功的话当然是最好的了!

接下来还会有报错建议安装一下这个版本的core-js

0b8f999aec58457f83831e50271e80c2.png

npm i core-js@3.6.4

出现下列报错信息就是得重新安装一下element-ui

948d19a5eb7645ea9275e4434696aea6.png

These dependencies were not found:  * element-ui in ./src/plugins/element.js
npm install --save element-ui

运行成功后可以试一下这一页能不能打开

3c0aa3a5292c45c58fe9f402626e6791.png

77e51da4500841acab45acaeb5121941.png

显示出来后可以继续进行下面的操作

ac55602790cf4523afdbee42bf2ce22f.png

写四个公共部分

Aside.vue

<template>
  <div class="container">
    <div class="wrapper">
      <h1>WEB ADMIN</h1>
      <el-form
        label-width="auto"
        :model="form"
        :rules="rules"
        ref="form"
        v-loading="isloading"
      >
        <el-form-item label="用户" prop="username">
          <el-input v-model="form.username" placeholder="请输入用户名">
            <i slot="prefix" class="el-input__icon el-icon-user"></i>
          </el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input
            v-model="form.password"
            placeholder="请输入密码"
            show-password
          >
            <i slot="prefix" class="el-input__icon el-icon-lock"></i>
          </el-input>
        </el-form-item>
        <el-row>
          <el-button type="primary" size="mini" @click="login">登录</el-button>
          <el-button type="success" size="mini" @click="resetForm('form')"
            >重置</el-button
          >
        </el-row>
      </el-form>
    </div>
  </div>
</template>
<script>
export default {
  name: "Login",
  data() {
    return {
      form: {
        username: "admin",
        password: "admin",
      },
      isloading: false,
      rules: {
        username: [
          {
            required: true,
            message: "请输入用户名",
            trigger: "blur",
          },
          {
            min: 3,
            max: 18,
            message: "长度在 3 到 18 个字符",
            trigger: "blur",
          },
        ],
        password: [
          {
            required: true,
            message: "请输入密码",
            trigger: "blur",
          },
          {
            min: 3,
            max: 18,
            message: "长度在 3 到 18 个字符",
            trigger: "blur",
          },
        ],
      },
    };
  },
  methods: {
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    login() {
      /* this.$axios.post('/login',{
      username:this.form.username,
      password:this.form.password
    }).then(res=>{
      console.log(res);
      this.$store.commit('setUser',res.data)
      window.sessionStorage.setItem('token',res.data.token)
      this.$router.push('/')
    }) */
      this.isloading = true;
      this.$api
        .login({
          username: this.form.username,
          password: this.form.password,
        })
        .then((res) => {
          console.log(res);
          this.$store.commit("setUser", res.data);
          window.sessionStorage.setItem("token", res.data.token);
          this.isloading = false;
          this.$router.push("/");
          this.$message({
            message: "恭喜你,登录成功",
            type: "success",
          });
        });
    },
  },
};
</script>
<style scoped="scoped">
.container {
  width: 100%;
  height: 100%;
  position: absolute;
  bottom: 0;
  left: 0;
  overflow: hidden;
  background-color: #2b4b6b;
}
.wrapper {
  width: 500px;
  height: 320px;
  background-color: #fff;
  margin: 120px auto;
}
.wrapper {
  padding: 0 30px;
}
.wrapper h1 {
  color: #666;
  text-align: center;
  padding: 20px 0 30px 0;
}
.el-row {
  float: right;
}
</style>

BreadCrumb.vue

<template>
  <el-breadcrumb separator-class="el-icon-arrow-right">
    <el-breadcrumb-item v-for="(item, idx) in breads" :key="idx" :to="{ path: item.path }">
      {{ item.name }}
    </el-breadcrumb-item>
  </el-breadcrumb>
</template>
<script>
import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['breads'])
  }
}
</script>
<style>
</style>

Headedr.vue

<template>
  <div class="header">
    <div class="header-left">
      <div class="header-left__logo">
        <img src="@/assets/logo.png" alt="">
      </div>
      <div class="header-left__title">后台管理系统权限Demo</div>
    </div>
    <div class="header-right">
      <div class="header-right__info">
        <div class="header-right__info-name">{{user.username}}</div>
      </div>
      <div class="header-right__logout">
        <el-button type="danger" size="20" @click="logout">退出</el-button>
      </div>
    </div>
  </div>
</template>
<script>
import { mapState } from 'vuex' 
export default {
  methods: {
    logout () {
      this.$confirm('您确定要退出吗, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        window.sessionStorage.removeItem('rightsList')
        window.sessionStorage.removeItem('token')
        this.$router.push({ path: '/login' })
      }).catch((err) => err)
    }
  },
  computed: {
    ...mapState(['user']) 
  }
}
</script>
<style lang="less" scoped>
.header {
  width: 100%;
  height: 100%;
  background-color: #00BFFF;
  display: flex;
  justify-content: space-between;
  padding: 0 15px;
  box-shadow: 0 2px 5px #00BFFF;
  &-left {
    height: 100%;
    display: flex;
    align-items: center;
    &__logo {
      width: 80px;
      height: 100%;
      padding: 5px;
      & > img {
        width: 100%;
        height: 100%;
      }
    }
    &__title {
      font-size: 20px;
      color: #fff;
      text-shadow: 10px 10px rgba(25, 255, 255, .3);
    }
  }
  &-right {
    height: 100%;
    display: flex;
    align-items: center;
    &__info {
      &-name {
        color: #F0FFFF;
        font-size: 16px;
        margin-right: 15px;
      }
    }
  }
}
</style>

Main.vue

<template>
  <div class="main">
    <div class="bread">
      <v-bread-crumb></v-bread-crumb>
    </div>
    <div class="content">
      <router-view :key="+new Date()"></router-view>
    </div>
  </div>
</template>
<script>
import BreadCrumb from '@/components/BreadCrumb.vue'
export default {
  data () {
    return {
      activeKey: ''
    }
  },
  components: {
    'v-bread-crumb': BreadCrumb
  }
}
</script>
<style lang="less" scoped>
.content {
  width: 100%;
  height: 100%;
  background-color: #fff;
  padding: 20px 15px;
  border-radius: 5px;
  transform: translateY(15px);
}
</style>

在main文件夹里写两个页面,添加以及查找

b4c67a27a01d470b880e5e428c7dda81.png

Card.vue

<template>
  <div class="card animate__animated animate__zoomIn" v-loading="isOperate">
    <div class="card-header">
      <div class="card-header__title">
        {{ isAdd ? '添加信息' : '删除信息' }}
      </div>
      <div class="card-header__close" @click="$emit('close')">
        <i class="el-icon-close"></i>
      </div>
    </div>
    <div class="card-content">
      <el-form :model="formData" :rules="rules" ref="form">
        <el-form-item label="姓名:" prop="name">
          <el-input v-model="formData.name"></el-input>
        </el-form-item>
        <el-form-item label="地址:" prop="address">
          <el-input v-model="formData.address"></el-input>
        </el-form-item>
        <el-form-item label="爱好:" prop="likes">
          <el-input  v-model="formData.likes"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button @click="$emit('close')" type="info">取消</el-button>
          <el-button @click="submitForm" type="primary">{{ isAdd ? '添加' : '修改' }}</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    isAdd: Boolean,
    isOperate: Boolean,
    rowData: {
      type: Object,
      default () {
        return {}
      }
    }
  },
  data () {
    return {
      formData: {
        name: '',
        address: '',
        likes: ''
      },
      rules: {
        name: { required: true, message: '请输入姓名', trigger: 'blur' },
        address: { required: true, message: '请输入地址', trigger: 'blur' },
        likes: { required: true, message: '请输入爱好', trigger: 'blur' }
      }
    }
  },
  created () {
    if (Object.keys(this.rowData).length && !this.isAdd) {
      this.formData = { ...this.rowData }
    } else {
      this.formData = {
        name: '',
        address: '',
        likes: ''
      }
    }
  },
  methods: {
    submitForm () {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.$emit('submitAction', {
            isAdd: this.isAdd,
            rowData: this.formData
          })
        }
      })
    }
  }
}
</script>
<style lang="less" scoped>
.card {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  transform-origin: 0 0;
  z-index: 99;
  background: #fff;
  box-shadow: 0 0 20px gray;
  border-radius: 5px;
  padding: 15px 80px;
  &-header {
    display: flex;
    justify-content: space-between;
    margin: 0 -50px 30px;
    &__title {
      font-size: 20px;
    }
    &__close {
      cursor: pointer;
      transition: all .5s;
      &:hover {
        transform: rotate(-15deg);
      }
    }
  }
  .el-form-item {
    display: flex;
    &:last-child {
      display: block;
      text-align: right;
    }
  }
  .el-input {
    width: 200px;
  }
}
.animate__animated.animate__zoomIn {
  --animate-duration: .8s;
}
</style>

TopBar.vue

<template>
  <div class="top-bar">
    <el-input placeholder="请输入内容,按回车键搜索..." @keydown.enter.native="handleSearch" v-model="inputValue">
      <template slot="append">
       搜索
      </template>
    </el-input>
    <el-button type="primary" @click="$emit('show')">添加商品</el-button>
  </div>
</template>
<script>
export default {
  data () {
    return {
      inputValue: ''
    }
  },
  methods: {
    handleSearch () {
      this.$emit('handleSearch', this.inputValue)
    }
  }
}
</script>
<style lang="less" scoped>
.top-bar {
  .el-input {
    width: 300px;
  }
  .el-button {
    margin-left: 15px;
  }
}
</style>

引入moke文件夹

// main.js
import './mock'

在moke文件夹中写入两种权限的数据

74b112ebc97d40c7b022782cedad14d2.png

index.js

引入mockjs插件

npm install --save mockjs
// 使用 Mock
const Mock = require('mockjs')
require('./my-radom')
const Random = Mock.Random
Mock.setup({
  timeout: '500-1000'
})
const list = []
for (let i = 0; i < 20; i++) {
  list.push({
    id: i + 1,
    date: Random.date(),
    name: Random.cname(),
    address: Random.address(),
    likes: Random.likes()
  })
}
const users = [
  {
    id: 1,
    username: 'normal',
    password: 'normal',
    token: 'abcdefghijklmnopqrstuvwxyz',
    rights: [{
      id: 1,
      authName: '用户管理',
      icon: 'icon-menu',
      children: [{
        id: 11,
        authName: '用户项目1',
        path: '/menu/one',
        rights: ['view', 'edit', 'add', 'delete']
      }, {
        id: 12,
        authName: '用户项目2',
        path: '/menu/two',
        rights: ['view']
      }]
    }]
  },
  {
    id: 2,
    username: 'admin',
    password: 'admin',
    token: 'abcdefghijklmnopqrstuvwxyz'.split('').reverse().join(''),
    rights: [{
      id: 1,
      authName: '用户管理',
      icon: 'icon-menu',
      children: [{
        id: 11,
        authName: '用户项目1',
        path: '/menu/one',
        rights: ['view', 'edit', 'add', 'delete']
      }, {
        id: 12,
        authName: '用户项目2',
        path: '/menu/two',
        rights: ['view', 'edit', 'add', 'delete']
      }]
    }, {
      id: 2,
      authName: '用户权限',
      icon: 'icon-menu',
      children: [{
        id: 22,
        authName: '权限项目1',
        path: '/menu/three',
        rights: ['view', 'edit', 'add', 'delete']
      }]
    }]
  }
]
// 获取列表
Mock.mock('/list', 'get', options => {
  const { current } = JSON.parse(options.body)
  return list.slice(((current - 1) * 10), current * 10)
})
// 总数
Mock.mock('/list/total', 'get', () => {
  return list.length
})
// 查询
Mock.mock('/list/value', 'get', options => {
  const { value } = JSON.parse(options.body)
  const _list = list.filter(item => {
    if (item.name.includes(value) || item.address.includes(value) || item.likes.includes(value)) {
      return true
    }
    return false
  })
  return {
    list: _list,
    total: _list.length
  }
})
// 添加
Mock.mock('/list/add', 'post', options => {
  const { rowData } = JSON.parse(options.body)
  rowData.id = list[list.length - 1].id + 1
  rowData.date = new Date().toLocaleDateString().replace(/\//g, '-')
  list.unshift(rowData)
  return rowData
})
// 修改
Mock.mock('/list/update', 'put', options => {
  const { rowData } = JSON.parse(options.body)
  let _rowData = {}
  list.forEach((item, idx) => {
    if (item.id === rowData.id) {
      _rowData = rowData
      list[idx] = rowData
    }
  })
  return _rowData
})
// 删除
Mock.mock('/list/delete', 'delete', options => {
  const { id } = JSON.parse(options.body)
  const index = list.findIndex(item => item.id === id)
  const item = index > 0 ? list[index] : {}
  list.splice(index, 1)
  return item
})
// 用户登录
Mock.mock('/login', 'post', options => {
  const { username, password } = JSON.parse(options.body)
  const user = users.find(item => {
    return item.username === username && item.password === password
  })
  return user
})

my-radom.js

// 使用 Mock
var Mock = require('mockjs')
Mock.Random.extend({
  likes: function () {
    const likes = [
      '喜欢打游戏,看电影,尤其是英雄联盟和欧美大片。',
      '喜欢做饭,尤其是西餐,喜欢做甜点,自己每次都吃得饱饱的。',
      '我最爱去游泳了,当然也喜欢潜水,在海底下看各种好看的鱼鱼。',
      '我最最喜欢的就是去旅游了,看沿途的风景,真是美呆了。',
      '我的爱好是打篮球,我很喜欢打篮球,我的偶像是科比。',
      '我超喜欢去蹦迪了,感觉整个身体都在那里放松了。',
      '哈哈哈,我喜欢的是和女孩子一起玩,因为男女搭配,干活不累嘛。',
      '我没啥爱好,唯一的爱好就是宅。',
      '我喜欢看动漫,更喜欢日漫,我可是一个二次元哦。',
      '我喜欢cosplay,喜欢cos动漫里的每一个角色。'
    ]
    return this.pick(likes)
  }
})
Mock.Random.extend({
  address: function () {
    const address = [
      '深圳市南山区科技园南区R2-B三楼',
      '深圳南山区科技园汇景豪苑海欣阁',
      '深圳市南山区白石洲中信红树湾',
      '上海市普陀区金沙江路 1517 弄',
      '四川成都市中德英伦联邦C区',
      '北京市中南海老四合院靠左',
      '广州市中心中央银行33号'
    ]
    return this.pick(address)
  }
})

在store文件夹的index.js中写入以下代码

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    breads: [],
   /* user: JSON.parse(window.sessionStorage.getItem('rightsList')||'{}') */
   user:JSON.parse(window.sessionStorage.getItem('rightsList')||'{}')
  },
  mutations: {
    addBread (state, bread) {
      const index = state.breads.findIndex(_bread => _bread.name === bread.name)
      if (index > -1) {
        state.breads.splice(index + 1, state.breads.length - index - 1)
      } else {
        state.breads.push(bread)
      }
    },
    removeBread (state, bread) {
      state.breads = state.breads.filter(_bread => _bread !== bread)
    },
  setUser(state,preload) {
  state.user = preload
  window.sessionStorage.setItem('rightsList',JSON.stringify(preload))
  }
   /* setUser (state, user) {
      state.user = user
      window.sessionStorage.setItem('rightsList',JSON.stringify(user))
    } */
  },
  actions: {
  },
  modules: {
  }
})

接下来做核心的页面部分

Page1.vue

<template>
  <div class="page">
  <v-card :isOperate="isOperate" v-if="cardShow" @close="cardShow = false" @submitAction="submitAction" :isAdd="isAdd"
   :rowData="rowData"></v-card>
  <v-top-bar @show="showAddCard" @handleSearch="handleSearch"></v-top-bar>
  <el-table :data="tableData" v-loading="loading" border>
    <el-table-column type="index" label="#" width="50">
    </el-table-column>
    <el-table-column prop="date" label="日期" width="180">
    </el-table-column>
    <el-table-column prop="name" label="姓名" width="180">
    </el-table-column>
    <el-table-column prop="address" label="地址">
    </el-table-column>
    <el-table-column prop="likes" label="爱好">
    </el-table-column>
    <el-table-column label="操作" width="200">
    <template v-slot:default="scope">
      <div class="btns">
      <el-button type="primary" @click="handleUpdate(scope)">
        <i class="el-icon-edit"></i>
      </el-button>
      <el-button type="danger" @click="handleDelete(scope)">
        <i class="el-icon-delete"></i>
      </el-button>
      </div>
    </template>
    </el-table-column>
  </el-table>
  <el-pagination class="pagi" background layout="prev, pager, next" :total="total" @current-change="sizeChange">
  </el-pagination>
  </div>
</template>
<script>
  import TopBar from '@/components/main/TopBar.vue'
  import Card from '@/components/main/Card.vue'
  import {
  mapMutations
  } from 'vuex'
  export default {
  data() {
    return {
    tableData: [],
    page: {
      size: 10,
      current: 1
    },
    total: 0,
    loading: false,
    title: '添加用户',
    cardShow: false,
    isAdd: true,
    rowData: {},
    isOperate: false
    }
  },
  methods: {
    ...mapMutations(['addBread']),
    sizeChange(data) {
    this.page.current = data
    this.getList(this.page.current)
    },
    initData() {
    this.getList(this.page.current)
    this.getTotal()
    },
    showAddCard() {
    this.isAdd = true
    this.cardShow = true
    },
    submitAction(info) {
    // 添加或修改项目
    this.isOperate = true
    if (info.isAdd) {
      this.$api.addList({
      rowData: info.rowData
      }).then(() => {
      this.initData()
      this.cardShow = false
      this.isOperate = false
      this.$message({
        message: '添加成功!',
        type: 'success',
        customClass: 'v-message',
        offset: 100
      })
      })
    } else {
      this.$api.updateList({
      rowData: info.rowData
      }).then(() => {
      this.initData()
      this.cardShow = false
      this.isOperate = false
      this.$message({
        message: '修改成功!',
        type: 'success',
        customClass: 'v-message',
        offset: 100
      })
      })
    }
    },
    handleSearch(value) {
    if (value === '') {
      this.$message({
      message: '警告哦,这是一条警告消息',
      type: 'warning'
      });
      this.getList() 
      return
    }
    this.loading = true
    this.$api.getListByValue({
      value
    }).then(res => {
      this.loading = false
      this.tableData = res.data.list
      this.total = res.data.total
    })
    },
    handleUpdate(scope) {
    this.isAdd = false
    this.cardShow = true
    this.rowData = scope.row
    },
    handleDelete(scope) {
    this.$confirm('你确定要删除这一条数据吗?', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'danger'
    }).then(() => {
      this.$api.deleteList({
      id: scope.row.id
      }).then(res => {
      this.initData()
      this.$message({
        message: '删除成功!',
        type: 'success',
        customClass: 'v-message',
        offset: 100
      })
      })
    }).catch(err => err)
    },
    getList(current) {
    this.loading = true
    this.$api.getList({
      current
    }).then(res => {
      this.tableData = res.data
      this.loading = false
      document.querySelector('.page').scrollTop = 0
    })
    },
    getTotal() {
    this.$api.getTotal().then(res => {
      this.total = res.data
    })
    }
  },
  created() {
    if (this.$route.query.name) {
    this.addBread({
      name: this.$route.query.name,
      path: this.$route.path
    })
    }
    this.initData()
  },
  components: {
    'v-top-bar': TopBar,
    'v-card': Card
  }
  }
</script>
<style lang="less">
  .page {
  height: 100%;
  overflow-y: scroll;
  }
  .el-table {
  transform: translateY(15px);
  }
  .pagi {
  margin: 30px 0;
  text-align: center;
  }
  .v-message {
  left: 58%;
  }
</style

下面写api

bc29850dc7c74db796e0236fd930d0b7.png

http.js 这个页面主要封装的是axios

import Axios from 'axios'
const axios = Axios.create({
  // baseURL: process.env.NODE_ENV === 'development' ? '' : '',
})
export default (url, method = 'get', data = {}) => {
  return axios({
    url,
    method,
    data
  })
}

index.js      

require.context是什么

一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块

把那三个js导入到这个index.js文件中 (自动化的导入,不需要一个一个的去引入页面)

这个方法有 3 个参数:

读取文件的路径

是否遍历文件的子目录(上述的图片中只有当前目录没有子目录所以为false)

以及一个匹配文件的正则表达式。

const context = require.context('./', false, /.js$/)
const modules = {}
console.log(context.keys());
context.keys().forEach(fileName => {
  if (!['./index.js', './http.js'].includes(fileName)) {
    Object.assign(modules, context(fileName))
  }
})
export default modules
page.js        页面所对应的接口全部获取过来
import http from './http'
export const getList = data => {
  return http('/list', 'get', data)
}
export const getTotal = () => {
  return http('/list/total')
}
export const getListByValue = data => {
  return http('/list/value', 'get', data)
}
export const addList = data => {
  return http('/list/add', 'post', data)
}
export const updateList = data => {
  return http('/list/update', 'put', data)
}
export const deleteList = data => {
  return http('/list/delete', 'delete', data)
}

user.js

import http from './http'
export const login = data => {
  return http('/login', 'post', data)
}

8b9c89fb5ada4fee8826c58f6f16cde6.png

在此路径添加common.js

export default {
  filters: {
    toString (str) {
      return str.toString()
    }
  }
}

最后把Home页面进行绑定

<template>
  <div class="home">
    <el-container>
      <el-header>
        <v-header></v-header>
      </el-header>
      <el-container class="v-container">
        <el-aside width="200px">
          <v-aside></v-aside>
        </el-aside>
        <el-main>
          <v-main></v-main>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script>
import Header from '@/components/Header.vue'
import Aside from '@/components/Aside.vue'
import Main from '@/components/Main.vue'
export default {
  name: 'Home',
  components: {
    'v-header': Header,
    'v-aside': Aside,
    'v-main': Main
  }
}
</script>
<style lang="less" scoped>
.home {
  height: 100%;
}
.el-container {
  height: 100%;
}
.v-container {
  height: calc(100% - 60px);
}
.el-header {
  padding: 0;
  z-index: 9;
}
.el-aside {
  height: 100%;
  background-color: #00BFFF;
}
.el-main {
  height: 100%;
  background-color: #eee;
  .main {
    height: 100%;
    overflow: hidden;
  }
}
</style>
相关文章
|
7月前
|
SQL XML Java
若依框架 --- 使用数据权限功能
若依框架 --- 使用数据权限功能
871 0
|
IDE 开发工具
IntelliJ插件开发教程之新建Action
认识Action 在IDE编辑器中可以通过右键打开选项,如下图所示,这里的动作便是Action,同时在顶部的ToolBar也会有相应的Action,如下图所示。可能大家对我这个IDE的UI有点陌生,其实这是2022.3版本的IDEA开启了New UI,NEW UI还是内测中,需要手动开启,设置位置在:Settings->appearance&behavior -> New UI
IntelliJ插件开发教程之新建Action
|
iOS开发
完整版在xcode打测试专用ipa包流程​
完整版在xcode打测试专用ipa包流程​
|
Web App开发 JSON 前端开发
YApi 官网说明文档-接口操作
为方便和前端, 节省沟通成本, 编写接口文档非常有比较 使用过swagger, 觉得入侵性太大. POST又感觉和项目结合的不太紧密. 所以一直在寻找 新的接口阅读/生成/测试工具. 下面介绍一下YApi.
1782 0
YApi 官网说明文档-接口操作
|
Python
odoo 开发入门教程系列-准备一些操作(Action)?
odoo 开发入门教程系列-准备一些操作(Action)?
211 0
|
测试技术
JMeter入门教程(11) --关联
正则表达式提取器介绍
101 0
JMeter入门教程(11) --关联
|
存储 测试技术
|
SQL 运维 分布式计算
阿里云相关产品操作演示 | 学习笔记
快速学习阿里云相关产品操作演示。
阿里云相关产品操作演示  |  学习笔记
|
缓存 文字识别 运维
开发一个小程序 Demo| 学习笔记
快速学习开发一个小程序 Demo。
开发一个小程序 Demo| 学习笔记
|
缓存 小程序 IDE
开发一个小程序 Demo|学习笔记
快速学习 开发一个小程序 Demo
199 0
开发一个小程序 Demo|学习笔记