赞
踩
● 移动端(Vant, Cube-UI, NutUI )
● PC端 ( element-ui, Ant Design of Vue, iView)
● 小程序: uniapp
● vue技术栈有很多的组件库(一般大厂才会维护组件库)
● 组件库要分移动端和PC端
● 学习组件库的基本方法是查文档,遇到困难时提 issue
Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
官方地址:https://element.eleme.cn/#/zh-CN
ElementPlus(适配Vue3.0的版本)官方地址: https://element-plus.org/#/zh-CN
vue create 文件夹名
找一个合适的文件夹,打开cmd窗口,用vue create 创建项目
vue create element-demo
-------------------------------
? Please pick a preset:
> Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
Manually select features
上一步的命令做了两件事:创建文件夹,把示例项目的代码下载到这个文件夹中,为了运行项目,我们还需要进入项目目录下,并运行命令。 对应的命令是:
cd element-demo # 进入项目目录
npm run serve # 运行命令
按全局引入的方式,一共分成两步:
npm i element-ui -S
-S: 是–save的简写,表示 这个包是生产依赖, 表示项目上线也要使用这个包。
-S: 是可以省略不写的。
如果要安装开发依赖,则要加 -D。
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
<template> <el-table :data="tableData" style="width: 100%"> <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> </template> <script> export default { data() { return { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }] } } } </script>
数据源由table组件的data属性来指定(不需要我们自己用v-for指令来循环)
在el-table使用data属性
在el-table-item上使用prop属性
我们需要在对应的列中,使用template
标签包裹我们自定义渲染的内容,其实用的就是插槽的机制
// 省略其它....
<el-table-column label="操作" width="100">
<template>
<el-button size="small" type="danger">删除</el-button>
</template>
</el-table-column>
要自定义内容:
用作用域插槽拿到数据,再使用函数做转换输出即可
要求 : 后端返回的数据中,只有一个指代性别的编码,为了方便用户查看,需要我们把1转换成男,0转换成女。
<el-table-column label="性别"> <!-- 1. slot-scope是固定写法 2. scope理解为变量,并不一定需要固定这个名字,el-table-column组件会自动将渲染本行需要的数据 传给scope,其中scope.row就表示当前行的数据,它对应数据源中的某个对象。这里的row是固定写法 3. {{ 方法() }} 的作用是执行这个方法,将返回值显示在当前单元格中 --> <template slot-scope="scope"> {{ transGender(scope.row.gender) }} </template> </el-table-column> <script> export default { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄', gender: 0 }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄', gender: 1 }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄', gender: 1 }], methods: { transGender(genderCode) { console.log(genderCode) const genderList = { 1: '男', 0: '女' } return genderList[genderCode] } } } </script>
<el-table-column label="性别"> <!-- 1. slot-scope是固定写法 2. scope理解为变量,并不一定需要固定这个名字,el-table-column组件会自动将渲染本行需要的数据 传给scope,其中scope.row就表示当前行的数据,它对应数据源中的某个对象。这里的row是固定写法 3. {{ 方法() }} 的作用是执行这个方法,将返回值显示在当前单元格中 --> <template slot-scope="scope"> {{ scope.row.gender === 1 ? '女' : '男'}} </template> </el-table-column> <script> export default { tableData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄', gender: 0 }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄', gender: 1 }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄', gender: 1 }] } } </script>
通过 Scoped slot 可以获取到 row, column, $index 和 store(table 内部的状态管理)的数据
scope.row
<template> <!-- layout: 决定整体的布局,关键字有自己的特殊含义 total: 一共几条数据 page-size: 一页几条 --> <el-pagination background layout="total, sizes, prev, pager, next,jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage4" :page-sizes="[1, 3, 7, 100]" :page-size="50" :total="551"> </el-pagination> </template> <script> export default { methods: { handleSizeChange(val) { console.log(`每页 ${val} 条`); }, handleCurrentChange(val) { console.log(`当前页: ${val}`); } }, data() { return { currentPage4: 6 }; } } </script> <style scoped> /deep/ .el-pager li.active{ background-color: red !important; } </style>
● layout中的关键字有自己的含义;
● total用来设置数据的总条数
● :page-size="50"默认每页50条数据
当用户点击页面进行翻页时就会触发current-change
事件
<template> <div> <h1>Pagination</h1> <el-pagination layout="prev, pager, next" :total="1000" @current-change="pageChange" > </el-pagination> </div> </template> <script> export default { methods: { // 把当前点击的页数给传进来 pageChange(page) { console.log(page) } } } </script>
<template> <div class="form-container"> <el-form label-width="80px"> <el-form-item label="手机号"> <el-input v-model="form.mobile"></el-input> </el-form-item> <el-form-item label="密码"> <el-input v-model="form.code"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">立即创建</el-button> <el-button>取消</el-button> </el-form-item> </el-form> </div> </template> <script> export default { data() { return { form: { mobile: '', code: '' } } }, methods: { onSubmit() { console.log('submit!') } } } </script> <style scoped> .form-container{ width: 600px; } </style>
基本步骤-共三步
在 data 中,补充定义规则。
格式:
data() { return { rules: { // 字段名1:表示要验证的属性 // 值: 表示验证规则列表。它是一个数组,数组中的每一项表示一条规则。 // 数组中的多条规则会按顺序进行 字段名1: [ { 验证规则1 }, { 验证规则2 }, ], 字段名2: [ { 验证规则1 }, { 验证规则2 }, ], } } }
示例
{ required: true, message: '请输入验证码', trigger: 'blur' },
{ pattern: /^\d{6}$/, message: '请输入合法的验证码', trigger: 'blur' },
{ min: 6, max: 8, message: '长度为6-8位', trigger: 'blur' }
实操代码
data () {
return {
// 表单验证规则,整体是一个对象
// 键:要验证的字段, 值:是一个数组,每一项就是一条规则
rules: {
// 字段名:mobile就表示要验证的 属性
// 值: 是一个数组。数组中的每一项表示一条规则。
mobile: [
{ required: true, message: '请输入手机号', trigger: 'blur' }
]
}
}
},
● rules中的属性名与表单数据项中的属性名必须是一致的。
内容:
:model="form" :rules="rules"
prop="mobile"
<el-form label-width="80px" :model="form" :rules="rules">
<el-form-item label="手机号" prop="mobile">
<el-input v-model="form.mobile"></el-input>
</el-form-item>
<el-form-item label="密码" prop="code">
<el-input v-model="form.code"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button @click="onCancel">取消</el-button>
</el-form-item>
</el-form>
element-ui的表单组件.validate(valid => {
if(valid) {
// 通过了验证
} else {
// 验证失败
}
})
● validate 方法是表单组件自带的,用来对表单内容进行检验。
● 需要在模板中添加对表单组件的引用:ref 的作用主要用来获取表单组件手动触发验证
代码-模板
<el-form label-width="80px"
ref="form"
:model="form"
:rules="rules">
添加ref来引用el-form组件。
代码
在做提交时进行手动兜底验证,如果通过了验证
doLogin () {
alert('我可以做登录了')
},
submit () {
this.$refs.form.validate(valid => {
// valid 就是表单验证的结果,如果是true,表示通过了
// console.log(valid)
if (valid) {
// 通过了验证,你可以做后续动作了
this.doLogin()
}
})
}
步骤
下面三个地方的属性名必须一致
rules:{ 属性名1: [ { // 注意参数顺序 validator: function (rule, value, callback) { // rule:采用的规则 // value: 被校验的值 // callback是回调函数, // 如果通过了规则检验,就直接调用callback() // 如果没有通过规则检验,就调用callback(错误对象,在错误对象中说明原因) // 例如:callback(new Error('错误说明')) }, trigger: 'blur' } ] }
rules: { name: [{required: true, message:'必须要填入', triggle: 'blur'}], code: [ { validator:(rule, value, callback)=>{ console.log(rule, value, callback) if(value === '123456') { callback(new Error('密码不能为123456')) } else { callback() } }, triggle: 'blur' }, {min: 6, max:8, message:'长度为6-8位', triggle: 'blur'}, {required: true, message:'必须要填入', triggle: 'blur'}, ] }
● 自定义规则可以让校验逻辑更加灵活,它的格式是固定的
● callback必须调用
校验失败会有红色的提示文字,有时候我们需要在执行了某个操作之后把当前校校验失败留下的痕迹清理一下,为下一次校验做准备。
this.$refs.form组件的引用.resetFields()
这个方法可以
有一些业务场景在描述主体关系的时候必须使用树形数据,比如:我们常见的家庭成员关系图,公司里的组织架构等,要描述这样的业务场景,与之对应的,我们就得给出树形结构的数据
<template> <el-tree :data="data"></el-tree> </template> <script> export default { data() { return { data: [{ label: '一级 1', children: [{ label: '二级 1-1', children: [{ label: '三级 1-1-1' }] }] }, { label: '一级 2', children: [{ label: '二级 2-1', children: [{ label: '三级 2-1-1' }] }, { label: '二级 2-2', children: [{ label: '三级 2-2-1' }] }] }, { label: '一级 3', children: [{ label: '二级 3-1', children: [{ label: '三级 3-1-1' }] }, { label: '二级 3-2', children: [{ label: '三级 3-2-1' }] }] }] } } } </script>
上面我们就完成了一个基础树形组件的渲染,依赖一个data属性即可,data属性传入的就是树状结构
注意:
● 数据项中label和children是关键字,不可随意改动。tree组件用它们来显示内容
tree组件渲染节点title默认使用的是数据中的label属性,识别子节点默认使用的是children属性,我们尝试把data里的属性名换一下,例如:label换成name,children换成childList,就会发现渲染失败了。
如果你非要去自定义这个两个关键字:label和children的话,就需要用到props属性了。
如下:
<el-tree :data="data" :props="defaultProps"></el-tree>
defaultProps:{
label:'name',
children:'childList'
}
当我们点击某个树形子节点的时候,如何获取到当前点击这项节点对应的数据?
监听时间:@node-click="handleNodeClick"
<template> <el-tree :data="data" @node-click="handleNodeClick"></el-tree> </template> <script> export default { methods:{ // 共三个参数, // 依次为: // - 传递给 data 属性的数组中该节点所对应的对象 // - 节点对应的 Node // - 节点组件本身 handleNodeClick(a,b,c){ console.log(a,b,c) } } } </script>
方法一:安装插件
npm install array-to-tree -save
import arrayToTree from "array-to-tree";
data中的自定义数组 = arrayToTree(获取请求的数组, { parentProperty: '父级id', customID: '二级id'});
引用的外部JSON数据:
{"list":
[
{"id":1,"label": "中学","parent_id":0},
{"id":2,"label": "初一","parent_id":1},
{"id":3,"label": "初二","parent_id":1},
{"id":4,"label": "小学","parent_id":0}
]}
文件中使用的部分:
<template> <div id="app"> <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree> </div> </template> <script> import axios from "axios"; import arrayToTree from "array-to-tree"; export default { data() { return { data: [], defaultProps: { id: "id", label: "label", children: "children", }, }; }, created() { this.getOptions(); }, methods: { handleNodeClick(data) { console.log(data); }, getOptions() { const url = "/api/goodsList"; axios .get(url) .then(res => { this.data = res.data.data; console.log(res.data); const treedata = arrayToTree(this.data, { parentProperty: "parent_id", customID: "id" }); this.data = treedata; console.log(treedata); }) .catch((error) => { console.log(error); }); }, }, }; </script>
方法二:第一种:递归实现数组转为树形结构
第一步: // 递归: 封装一个函数:将列表list数据转换成数据树形数据=>递归 // 遍历树形 有一个重点 要先找一个头 function transListDataToTreeData(list, root) { const arr = [] // 1.遍历 list.forEach((item) => { // 2.首次传入空字符串 判断list的pid是否为空 如果为空就是一级节点 if (item.pid === root) { // 找到之后就要去找item下面有没有子节点 以 item.id 作为 父 id, 接着往下找 const children = transListDataToTreeData(list, item.id) if (children.length > 0) { // 如果children的长度大于0,说明找到了子节点 item.children = children } // 将item项, 追加到arr数组中 arr.push(item) } }) return arr } //第二步: // 调用转化方法,转化树形结构 赋值给data中定义的数组 this.departs = transListDataToTreeData(data.depts, '') //第三步: 渲染到页面 <!-- 树形控件el-tree :data:指定数据 props:属性成员配置项 default-expand-all 控制是否默认展开--> <!-- el-tree组件 里面内容是插槽内容 有多少个节点循环多少次 --> <el-tree :data="departs" :props="defaultProps" :default-expand-all="true" > </el-tree>
● 基本交互
● 使用默认插槽来自定义内容
<template> <div> <el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button> <el-dialog title="提示" :visible.sync="dialogVisible" width="30%" > <span>这是一段信息</span> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="dialogVisible = false">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { data() { return { dialogVisible: false } } } </script>
弹框组件有俩种状态,一个是打开一个是关闭,如果我们想在它打开或者关闭时做一些自己的事情,就可以监听俩个事件
@close 弹框关闭 : dialogVisible从true变成false
@open 弹框打开 : dialogVisible从false变成true
<template> <div> <el-button type="text" @click="dialogVisible = true" >点击打开 Dialog</el-button > <el-dialog title="提示" :visible.sync="dialogVisible" @close="dialogClose" @open="dialogOpen" width="30%" > <span>这是一段信息</span> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="dialogVisible = false">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { data() { return { dialogVisible: false, } }, methods: { dialogClose() { console.log('弹框要关闭了') }, dialogOpen(){ console.log('弹框打开咯') } } } </script>
<el-dialog
:close-on-click-modal="false"
:close-on-press-escape="false"
openMessage () { this.$message({ type: 'success ', message: `月薪15K` }) }, open () { this.$alert('你真的要走吗?', '系统提示', { confirmButtonText: '确认', callback: action => { this.$message({ type: 'info', message: `action: ${action}` }) } }) }
<template> <el-select v-model="value" placeholder="请选择"> <!-- label: 显示的内容 value: 选中之后要保存的内容---值 --> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </template> <script> export default { data () { return { options: [{ value: '1', label: '黄金糕' }, { value: '2', label: '双皮奶' }, { value: '选项3', label: '蚵仔煎' }, { value: '选项4', label: '龙须面' }, { value: '选项5', label: '北京烤鸭' }], value: '' } } } </script>
selecct: @change, ajax
描述:
选中其他的菜单,刷新页面,发现默认选中的菜单不对!
解决
:default-active="$route.path"
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。