首页 vue 正文
  • 本文约6576字,阅读需33分钟
  • 1881
  • 0

vue-element-admin

温馨提示:本文最后更新于2020年10月1日 22:28,若内容或图片失效,请在下方留言或联系博主。

下载 vue-element-admin,并启动

官方:https://github.com/PanJiaChen/vue-element-admin

框架里的组件样式可以从 element 上找 

element:http://element-cn.eleme.io/#/zh-CN/component/table

可以直接下载压缩包解压,也可以通过 git 下载

 # 克隆项目
git clone https://github.com/PanJiaChen/vue-element-admin.git

#设置淘宝仓库
npm install --registry=https://registry.npm.taobao.org

# 安装依赖
npm install

# 启动服务
npm run dev

├── build // 构建相关  

├── config // 配置相关

├── src // 源代码

│   ├── api // 所有请求

│   ├── assets // 主题 字体等静态资源

│   ├── components // 全局公用组件

│   ├── directive // 全局指令

│   ├── filtres // 全局 filter

│   ├── icons // 项目所有 svg icons

│   ├── lang // 国际化 language

│   ├── mock // 项目mock 模拟数据

│   ├── router // 路由

│   ├── store // 全局 store管理

│   ├── styles // 全局样式

│   ├── utils // 全局公用方法

│   ├── vendor // 公用vendor

│   ├── views // view

│   ├── App.vue // 入口页面

│   ├── main.js // 入口 加载组件 初始化等

│ └── permission.js // 权限管理

├── static // 第三方不打包资源

│   └── Tinymce // 富文本

├── .babelrc // babel-loader 配置

├── eslintrc.js // eslint 配置项

├── .gitignore // git 忽略项

├── favicon.ico // favicon图标

├── index.html // html模板

└── package.json // package.json

dev.env.js

先来看下 config 文件夹下的 dev.env.js

这个文件夹里的 BASE_API 后台接口的就是公共路径,调后台的时候要记得改,这是本地的,剩下的 prod 和 sit 分别是正式环境打包和 测试环境打包的

/src/router/index.js

先来看下目录

详细的解释在这个目录文件的上面有,每个属性什么意思,可以在上面看

mock 假数据页面

mock 主要是帮助前后分离的项目为前端提供数据,这样才好测试

先来画个页面,一个分页列表吧,路径 /src/service/dataLog.vue 用来显示一些信息

我在 element 组件里找了一个列表功能和分页功能

​/src/service/dataLog.vue

dataLog.vue 的 template 部分

<template>
    <div class="app-container"> 
        <!-- 查询框 双向绑定 keyword-->
        <el-input
        v-model="keyword"
        placeholder="请输入关键字"
        clearable
        style="width:500px" />
        <!-- 搜索按钮 绑定点击事件 -->
        <el-button type="primary" icon="el-icon-search" @click="getDataLog()">搜索</el-button>
        <!-- data就是绑定数据用的 -->
        <el-table
        :data="dataLog"
        style="width: 100%">
            <el-table-column type="expand">
                <template slot-scope="props">
                    <el-form label-position="left" inline class="demo-table-expand">
                    <el-form-item label="错误信息">
                    <span>{{ props.row.log }}</span>
                    </el-form-item>
                    </el-form>
                </template>
            </el-table-column>
            <el-table-column
            label="服务单"
            prop="data"/>
            <el-table-column
            label="时间"
            prop="time"/>
        </el-table>
        <!-- 分页 -->
        <pagination
        v-show="total>0"
        :total="total"
        :page.sync="listQuery.page"
        :limit.sync="listQuery.limit"
        @pagination="getDataLog" />
        <!-- total总条数
        listQuery.page 当前页
        listQuery.limit 每页几条
        getDataLog 后买点击分页时候要回调的函数 -->
    </div>
</template>

注意 template 下只能有一个节点,两个就报错了,可以试下,所有我放在一个统一的 div 里

至于这些值为啥这样写,我只能说照着人家给的模板改就好,人家写啥你写啥,样式啥的人家上面都有

样式部分就不贴了,最后会把完整的代码贴出来,来看下 js 的部分

这里解释下分页,分页除了初始化给了第 1 页和每页 10 条后,之后每次点击页码,数据都会双向绑定到值上,所有在调后台函数的时候,直接取 page 和 limit 值就行了,不想要再去想我怎么去拿 div 上面的数字

<script>
    // 这里要调用我使用的 api  
    // 括号里的是要使用的函数接口,多个的话逗号隔开
    import { getDataLog } from '@/api/service/dataLog'  
    // 引入分页组件
    import Pagination from '@/components/Pagination'
    export default {
        // 这里需要把分页组件注册进来
        components: { Pagination },
        data() {
            return {
                // 搜索关键字
                keyword: '',
                // 数据条数
                total: 0,
                // 分页参数
                listQuery: {
                page: 1,
                limit: 10
                },
                // 列表数据
                dataLog: []
            }
        },
        // 这个是生命周期函数,这个时候是 data 和 methods 都初始化好了,具体看基础知识
        created() {
            this.getDataLog()
        },
        methods: {
            // 函数部分
            getDataLog() {
            // 参数
                this.listQuery = {
                    page: this.listQuery.page,
                    limit: this.listQuery.limit,
                    object: this.keyword
                }
                // 调用上面引入的 api 里的 getDataLog
                // 不引入就报函数未定义了,刚开始一个人折腾好久,老子明明定义在这了,为啥还没定义
                getDataLog(this.listQuery).then(response => {
                    // 返回值处理
                    this.dataLog = []
                    this.total = response.data.total
                    this.dataLog = response.data.items
                    // 查询后要把关键字给清空
                    this.keyword = ''
                })
            }
        }
    }
</script>

接下来看看上面的 api 接口

/src/api/service/dataLog.js

每次点击就会去调用 api 接口里的方法,参数都看得懂

上面引用的 request 文件使得每次调用的时候都会对请求进行拦截,上面的 BASE_API 就会在里面被拼上去

 import request from '@/utils/request'
// 获取错误信息列表
export function getDataLog(query) {
    return request({
        url: '/log/getDataLog',
        method: 'get',
        params: query
    })
}

/src/mock/service/dataLog.js

接下来就是使用 mock 假数据,我就循环了10条,因为假的分页,特意去实现太费劲了

如果有多个接口的数据要返回,可以在 export default 里写多个接口去返回

import Mock from 'mockjs'
const List = []
const count = 10
// 模拟错误信息
for (let i = 0; i < count; i++) {
    List.push(Mock.mock({
        data: '12987122',
        time: '好滋好味鸡蛋仔',
        log: '江浙小吃、小吃零食江浙小吃、小吃零食'
    }))
}
export default {
    // 获取错误信息列表
    getDataLog: () => {
        return {
            total: List.length,
            items: List,
            limit: 10
        }
    }
}

/src/mock/index.js

上面的写完还不行,因为通过 api 提交的请求,mock 不知道哪些是需要请求假数据的,所有需要在 index 文件里进行拦截

直接加就好了,就这两行,把刚写的假数据引用进来,对请求进行拦截

第一个参数,就是要拦截的 url 这里就和 api 挂钩起来了

第二个参数,get 类型请求

第三个参数,/src/mock/service/dataLog.js 里 export 的对应接口,这样就和 mock 假数据也挂钩起来了

需要拦截多少个请求就要写多少个

然后 npm run dev 运行测试就好了

axios 连接后台真数据

这里我偷了个懒,由于 utils/request.js 已经帮我们把 axios 都弄好了,像 BASE_API 的路径拼接,我又不想再写个 api 文件,所以我就直接拿过来用了

先引入

import request from '@/utils/request'

js 部分:

methods: {
    getDataLog() {
        this.listQuery = {
            page: this.listQuery.page,
            limit: this.listQuery.limit,
            object: this.keyword
        }
        // mock 请求假数据
        // getDataLog(this.listQuery).then(response => {
        // this.dataLog = []
        // this.total = response.data.total
        // this.dataLog = response.data.items
        // // 查询后要把关键字给清空
        // this.keyword = ''
        // })
        // 请求后台获得真实数据
        request({
            url: '/log/getDataLog/',
            method: 'post',
            data: this.listQuery
        }).then(response => {
            this.dataLog = []
            this.total = response.data.pageEntity.total
            this.dataLog = response.data.retData
        })
    }
}

这里访问路径就是 http://127.0.0.1:8081/log/getDataLog,如果全路径访问也是可以的,url 前面带了 &ldquo;/&rdquo;意思就是会进行路径的拼接,如果写的是 url: 'log/getDataLog' 那么访问就报错了,因为前缀没拼上,还有要把 mock 里的 index.js 文件里的注掉,要不会拦截变成假数据

这里用的是 post 方法,后台部分直接用 @RequestBody 接收参数就好了

也可以用 get 方法,把参数拼在 url 上传递,我这采用 restful 形式的接口,用 @PathVariable 接收参数

这时候你可能会遇到跨域问题

新建 config 包

@Configuration
public class CorssDomainConfig implements WebMvcConfigurer {
    @Autowired
    private CorsInterceptor corsInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(corsInterceptor);
        registration.addPathPatterns("/**");
    }
}

然后新建 interceptor 包

@Component
public class CorsInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
        // 添加跨域CORS
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Authorization,token, x-token");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
        return true;
    }
}

项目再启动时,addInterceptors 就会把 preHandle 给注册成对象,后续请求都会经过 preHandle 接口对请求做出处理

正式环境部署

我这前端采用 Nginx 作为前端的运行容器

详细部署:Docker 上部署 Nginx

我 Nginx html 文件夹下我保留了 dist目录

所以 /conf.d/default.conf 要改下

vue 里 config/sit.env.js,这里我配置了测试服的,然后在 prod.env.js 配置了正式服的

module.exports = {
    NODE_ENV: '"production"',
    ENV_CONFIG: '"sit"',
    // 项目访问根路径
    // 测试服
    BASE_API: '"http://xx.xx.xxx.xxx:xxxx"',
}
#测试服打包
npm run build:sit
#正式服打包
npm run build:prod

命令就在 package.json 里

打包后会在根目录生成 dist 文件夹,把文件夹放到服务器的 html 文件夹下就好了,然后启动 Nginx,启动过就不用启动了,由于我 Nginx 直接配置了 80 端口的,所以直接服务器路径访问就行了

PS:如果遇到了打包报错的情况,那就把 npm 更新下 npm install ,这会在项目根目录生成 node_modules 文件夹,这些是需要的依赖,在 linux 上打包我这试了不行,依赖更新了也不对,不知道问题出在哪,应该是 windows 和 linux 依赖不太一样吧

前端完整代码

/src/views/service/dataLog.vue

<template>
    <div class="app-container">
        <!-- 查询框 双向绑定 keyword-->
        <el-input
        v-model="keyword"
        placeholder="请输入关键字"
        clearable
        style="width:500px" />
        <!-- 搜索按钮 -->
        <el-button type="primary" icon="el-icon-search" @click="getDataLog()">搜索</el-button>
        <!-- data就是绑定数据用的 -->
        <el-table
        :data="dataLog"
        height="600"
        style="width: 100%">
            <el-table-column type="expand">
                <template slot-scope="props">
                    <el-form label-position="left" inline class="demo-table-expand">
                    <el-form-item label="错误信息">
                    <div v-html="props.row.log"/>
                    </el-form-item>
                    </el-form>
                </template>
            </el-table-column>
            <el-table-column
            label="服务单"
            prop="data"/>
            <el-table-column
            label="时间"
            prop="time"/>
        </el-table>
        <!-- 分页 -->
        <pagination
        v-show="total>0"
        :total="total"
        :page.sync="listQuery.page"
        :limit.sync="listQuery.limit"
        @pagination="getDataLog" />
        <!-- total总条数
        listQuery.page 当前页
        listQuery.limit 每页几条
        getDataLog 后买点击分页时候要回调的函数 -->
    </div>
</template>
<script>
    // import { getDataLog } from '@/api/service/dataLog'
    import Pagination from '@/components/Pagination'
    import request from '@/utils/request'
    export default {
        components: { Pagination },
        data() {
            return {
                // 搜索关键字
                keyword: '',
                // 数据条数
                total: 0,
                // 分页参数
                listQuery: {
                page: 1,
                limit: 10
                },
                // 列表数据
                dataLog: []
            }
        },
        created() {
            this.getDataLog()
        },
        methods: {
            getDataLog() {
                this.listQuery = {
                    page: this.listQuery.page,
                    limit: this.listQuery.limit,
                    object: this.keyword
                }
                // mock 请求假数据
                // getDataLog(this.listQuery).then(response => {
                // this.dataLog = []
                // this.total = response.data.total
                // this.dataLog = response.data.items
                // // 查询后要把关键字给清空
                // this.keyword = ''
                // })
                // 请求后台获得真实数据
                request({
                    url: '/log/getDataLog/',
                    method: 'post',
                    data: this.listQuery
                }).then(response => {
                    this.dataLog = []
                    this.total = response.data.pageEntity.total
                    this.dataLog = response.data.retData
                })
            }
        }
    }
</script>
<style>
    .demo-table-expand {
        font-size: 0;
    }
    .demo-table-expand label {
        width: 90px;
        color: #99a9bf;
    }
    .demo-table-expand .el-form-item {
        margin-right: 0;
        margin-bottom: 0;
        width: 50%;
    }
</style>

/src/api/service/dataLog.js

import request from '@/utils/request'
// 获取错误信息列表
export function getDataLog(query) {
    return request({
        url: '/log/getDataLog',
        method: 'get',
        params: query
    })
}

/src/mock/service/index.js

拦截原因,请求后台就注掉

// Mock.mock(/\/log\/getDataLog/, 'get', dataLogAPI.getDataLog)

/src/mock/service/dataLog.js

import Mock from 'mockjs'
const List = []
const count = 10
// 模拟错误信息
for (let i = 0; i < count; i++) {
    List.push(Mock.mock({
        data: '12987122',
        time: '好滋好味鸡蛋仔',
        log: '江浙小吃、小吃零食江浙小吃、小吃零食'
    }))
}
export default {
    // 获取错误信息列表
    getDataLog: () => {
        return {
            total: List.length,
            items: List,
            limit: 10
        }
    }
}​
评论