前端UI:element-ui,ant-design-vue

Element-ui使用指南

开发环境

1.安装webpack

npm install -g webpack1

2.安装vue-cli

vue-cli是什么?

vue-cli 是vue.js的脚手架,用于自动生成vue.js模板工程的。

使用步骤:

  • 安装vue-cli:
npm install -g vue-cli1
  • 使用vue-cli构建项目
vue init webpack project-name  //创建一个基于webpack模板的名为project-name的项目1

目前可用的模板包括:

   - browserify–全功能的Browserify + vueify,包括热加载,静态检测,单元测试。
    - browserify-simple–一个简易的Browserify + vueify,以便于快速开始。
    - webpack–全功能的Webpack + vueify,包括热加载,静态检测,单元测试。
    - webpack-simple–一个简易的Webpack + vueify,以便于快速开始。

  • 安装项目依赖
cd project-name    //进入项目目录
npm install        //安装项目依赖
npm run dev        //运行项目123

此时在浏览器打开:localhost:8080即可看到欢迎页。

关于webpack和vue-cli的更多使用方法参见官方文档。

  • 但是这个只能在本地跑,要如何在我们自己的服务器上访问呢?此时需要执行
npm run build1

搭建开发环境

第一步:安装项目模板

  • 克隆/下载项目模板
  • 将下载的模板放到你项目的根目录下
  • 安装依赖
npm install1
  • 运行项目模板
npm run dev1

此时在浏览器打开:localhost:8080即可看到欢迎页。
前端UI:element-ui,ant-design-vue_第1张图片
项目模板里已经把需要配置的文件都配置好了。

第二步:安装element-ui

第一步,我们成功安装了项目模板,接下来,我们需要安装element-ui到项目下。

npm i element-ui@next -D1

开始使用

接下来我们就可以参照 Element-UI 的官方文档上手开发了。

例子

我们参照官方的按钮组件使用说明,在项目模板的基础上做一个按钮的例子。其它文件不需要改动,只修改App.vue文件的内容。代码如下:

App.vue

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <h1>{{ msg }}</h1>
    <el-button @click.native="startHacking">Let's do it</el-button>
    <div class="block">
    <span class="demonstration">显示默认颜色</span>
    <span class="wrapper">
    <el-button type="success">成功按钮</el-button>
    <el-button type="warning">警告按钮</el-button>
    <el-button type="danger">危险按钮</el-button>
    <el-button type="info">信息按钮</el-button>
    </span>
    </div>
    <br/>
    <div class="block">
      <span class="demonstration">hover 显示颜色</span>
    <span class="wrapper">
    <el-button :plain="true" type="success">成功按钮</el-button>
    <el-button :plain="true" type="warning">警告按钮</el-button>
    <el-button :plain="true" type="danger">危险按钮</el-button>
    <el-button :plain="true" type="info">信息按钮</el-button>
    </span>
    </div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      msg: 'Use Vue 2.0 Today!'
    }
  },

  methods: {
    startHacking () {
      this.$notify({
        title: 'It Works',
        message: 'We have laid the groundwork for you. Now it\'s your time to build something epic!',
        duration: 6000
      })
    }
  }
}
</script>

<style>
body {
  font-family: Helvetica, sans-serif;
}
</style>

效果如下图所示:
前端UI:element-ui,ant-design-vue_第2张图片

使用过程中碰到的问题:

1. phantomjs安装失败
由于源的问题,安装phantomjs必须要“搭梯子”,使用内网无法下载。所以解决的方法有两种:

  • 方法一:通过科学上网,然后安装。
  • 方法二:对于不知道怎么“搭梯子”的同学,可以通过更改源来下载,操作方法如下:
npm install phantomjs --phantomjs_cdnurl=http://cnpmjs.org/downloads1

2.打开页面乱码
通过 Element-UI 官方提供的项目模板开发,会发现在浏览器打开页面的时候,中文是乱码的。如下图所示:
前端UI:element-ui,ant-design-vue_第3张图片
但html页面中已经设置了 。

仔细查看该页面所涉及的文件的编码格式的时候,发现引用的App.vue 文件的编码格式是GBK ,所以把该文件编码格式改为UTF-8 即可

ant-design-vue使用指南

ant-design-vue是蚂蚁金服 Ant Design 官方唯一推荐的Vue版UI组件库,它其实是Ant Design的Vue实现,组件的风格与Ant Design保持同步,组件的html结构和css样式也保持一致。 用下来发现它的确称得上为数不多的完整的VUE组件库与开发方案集成项目。

本文主要目的是总结一些开发过程中比较耗时间去查找,文档中没有具体说明的常见问题,同时希望能给新上手此框架的同学提供一些参考作用。

1.Table对接后台返回数据

针对Table数据格式与后他接口返回数据格式不一致问题,修改 @/components/table/index.js 132行起

主要修改pageNo,pageSize,totalCount,data这字段与后台返回字段一致就OK了

result.then(r => {
  this.localPagination = Object.assign({}, this.localPagination, {
    current: r.pageNo,  // 这里修改当前分页字段
    total: r.totalCount, // 这里修改总记录数字段
    showSizeChanger: this.showSizeChanger,
    pageSize: (pagination && pagination.pageSize) ||
      this.localPagination.pageSize // 这里修改总记录数当前页数字段
  })
    //r.data中的data修改为返回列表字段
  if (r.data.length == 0 && this.localPagination.current != 1) {
    this.localPagination.current--
    this.loadData()
    return
  }
  !r.totalCount && ['auto', false].includes(this.showPagination) && (this.localPagination = false)
  this.localDataSource = r.data // 返回结果中的数组数据
  this.localLoading = false
});


#### 2.table操作栏参数问题

在table的dataSource中指定的每一个数据中,都必须包含有name为key的对象,而显示出的数据就是相应key对应的数据,dataIndex就用来声明列数据在数据项中对应的key

然而在操作列中,我们一般需要传入不知一项数据,试了一下如下图配置dataIndex,数据并不能正确传入slot-scope中



columns: [{
title: ‘操作’,
dataIndex: ‘id,text’,
key: ‘id’,
scopedSlots: { customRender: ‘operation’ }
}
]



多尝试后发现,其实只要不配置dataIndex就好了。。。slot-scope自定义一个字段,自然就拿到了整行数据

#### 3.table分页组件展示条数


:pagination="{showTotal: total => 共${total}条}"


#### 4.神奇的最后一个标签隐藏问题

使用可编辑tags过程中值得注意的问题,一般删除某个tag不止是从DOM中删除这个tag,而是需要调接口修改数据,那么这时候如果选择用修改完的数据动态渲染tag列表,并且理所当然地认为动态绑定数据就不需要关心数据手动处理,问题就出现了:

假如一共有5个tag,现在删除第一个tag,并调用接口返回新数据,注意tags默认的删除操作也不是从DOM中删除这个tag,而是将这个tag设置为```display:none```!这就导致了一个很神奇的问题,此时新返回的tags数组长度已经  -1,而它仍然认为当前列表的第一个Tag是隐藏的,最后呈现的效果就是只剩3个Tag,此时再接着删除第一个tag(其实是第二个),那么就只剩1个tag了。。




{{ tag.name }}




这个问题貌似没什么好的办法,只能放弃绑定动态数据,判断接口调用成功后,再用文档中的手动操作增减数据的办法:


this.Tags = this.Tags.filter(tag => tag.id !== removeTag.id)


#### 5.表单的各种常规操作

单独触发某个字段的校验:


this.form.validateFields([‘name’], { force: true })


清除某个字段的值:


this.form.resetFields(name,’’)


设置表单初始值:


this.form.resetFields(name,’’)


注意:不初始化的值用undefined而非‘’,否则下拉框会不显示placeholder!

 

自定义文件上传的action函数:


upLoad (info) {
let file = info.file;
let param = new FormData(); //创建form对象
param.append(‘file’,file);//通过append向form对象添加数据
console.log(param.get(‘file’)); //FormData私有类对象访问不到,可以通过get判断值是否传进去
let config = {
headers:{‘Content-Type’:‘multipart/form-data’}
};
this.$http.post(url, param, config).then(res => {

})
},

#### 6.接口跨域携带cookie问题

做单点登录时需要在请求头中携带cookie,遇到了很坑人的问题,实际原因是对mock.js的实现不够了解。

还是在`@/src/utils/request.js`,这里创建了axios实例供全局调用,根据axios文档,**在创建** axios 实例时添加:`withCredentials: true`

const service = axios.create({
baseURL: ${process.env.VUE_APP_BASEURL}/backend,
withCredentials: true,
timeout: 6000
})


结果发现接口请求仍然不带cookie,无奈试了一下用fetch请求`fetch(url, { credentials:  'include', mode: 'cors'  })`,发现可以携带cookie,百思不得其解,两者都是基于promise实现的,但是fetch在写法和拦截请求响应等方面都比较麻烦,全部替换成fetch也不太现实。最后才发现,是mock.js没有注释(`main.js`中注释掉就好了),原来mock.js是通过拦截XHR请求来实现的接口模拟,Axios本质上也是对原生XHR的封装,只不过它是Promise的实现版本,所以它当然被拦截了,而fetch脱离了XHR,这也是fetch请求能正常携带cookie的原因,这里还没有全部梳理清楚,打算在后一篇中详细介绍一下

7.单点登录的实现

全局的路由钩子在`permission.js`中,一般单点登录、权限验证都是在这里处理,这里也不例外。没什么特别的,需要注意的一点就是,不要忘记对页面其他接口的统一无权限处理,和403请求的响应处理。同时画个流程图会更快一些,这里就记录一下吧:

流程图:

![img](https://img-blog.csdnimg.cn/img_convert/d3ed63a060e0aa58c80d44d5d73a59c7.png)

路由钩子的处理:



router.beforeEach((to, from, next) => {
// 对403无权限的处理
if (to.path === ‘/403’) {
next()
} else {
if (roles) {//已登陆
next()
} else {
//获取用户信息,GetUserInfo逻辑如下:
//status=403 && reject(res),返回包含status;
//status=1005 && reject(res.data)返回重定向的URL;
//status=1000 && resolve()
store
.dispatch(‘GetUserInfo’)
.then(res => {
next()
})
.catch((e) => {
if (e.status) {
next({ path: ‘/403’ })
} else {
//拼接URL跳去登陆页,登陆成功会重定向回当前页(login_redirect)
const url = e.substring(0, e.lastIndexOf(‘redirect’)) + ‘redirect=’ + login_redirect
window.location.href = url
}
})
}
}
})


`@/ src/utils/request.js`中接口返回的统一处理:



service.interceptors.response.use((response) => {
if (response.data.status === 1005){
//… 同上跳去登陆页
}else{
//为返回数据做统一处理
return response.data
}
}, err)



#### 7.引入eCharts

1)npm install

2) components下新建barChart.vue ,import echarts from 'echarts',正常操作...

3) resize触发图表自适应

echart有resizeAPI,一般是在图表组件如barChart.vue里面手动监听窗口resize


mounted() {
window.addEventListener(“resize”, () => {
this.chart.resize();
});
},


后面借鉴element-admin, 利用mixins实现了更完善的统一处理方法:

1)定义一个mixin:resize.js



import { debounce } from ‘@/utils’//防抖函数
export default {
data() {
return {
$_sidebarElm: null
}
},
mounted() {
this.__resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
window.addEventListener(‘resize’, this.__resizeHandler)

this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)

},
beforeDestroy() {
window.removeEventListener(‘resize’, this.__resizeHandler)

this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)

},
methods: {
$_sidebarResizeHandler(e) {
if (e.propertyName === ‘width’) {
this.__resizeHandler()
}
}
}
}




2)@/components/_utils/util.js中添加防抖函数




export const debounce = (func, wait, immediate) => {
let timeout, args, context, timestamp, result

const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp

// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
  timeout = setTimeout(later, wait - last)
} else {
  timeout = null
  // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
  if (!immediate) {
    result = func.apply(context, args)
    if (!timeout) context = args = null
  }
}

}

return function(…args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}

return result

}
}




3)resize监听方法混入图表组件即可


mixins: [resize]

你可能感兴趣的:(elementui,前端)