目录😋
背景介绍
准备步骤
目标效果
挑战需求
要求规定
通关代码✔️
代码解析📑
一、HTML 部分
二、Vue 部分
三、工作流程 ▶️
测试结果👍
背景介绍
在使用 element-ui 开发的过程中,对表格的使用比较多,且在同一个系统中表格的样式基本上是固定的,功能也基本一样。若每写一个页面都要去复制一份表格的代码,就会产生大量重复的代码,既不利于后期的维护,代码也不够简洁。为此需要前端工程师对 element-ui 的原组件进行二次封装。
准备步骤
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── element-ui-2.15.10 │ ├── index.css │ └── index.js ├── index.html ├── js │ ├── http-vue-loader.js │ └── vue.min.js └── mytable.vue
其中:
index.html
是主页面。mytable.vue
是待封装的表格组件文件。js
是用于存放 Vue.js 相关文件的文件夹。element-ui-2.15.10
是存放 element-ui 的文件夹。在浏览器中预览
index.html
页面效果显示如下所示:
目标效果
element-ui 官网上具有单选功能的表格 demo 为:点击表格下方的按钮可以选中指定的某行数据。效果如下:
![]()
从上图可以看到表格的左边有一列单选组件,但是并未实现单选功能。
![]()
现在需要我们完善
mytable.vue
文件中的 TODO 部分,实现点击某个单选组件选中该行数据的效果。效果如下:
实现该功能所需的 api 如下:
table 参数说明
属性参数:
其中如果对表格中某个字段数据呈现个性化显示效果,则可以利用
参数 说明 类型 data
显示的数据 array stripe
是否为斑马纹 table boolean highlight-current-row
是否要高亮当前行 boolean Scoped slot
获取到row
,column
,$index
和store
(table 内部的状态管理)的数据。用法参考下面示例:<el-table-column label="日期" width="180"> <template slot-scope="scope"> 📅<span style="margin-left: 10px">{ { scope.row.date }}</span> </template> </el-table-column>
radio 参数说明
属性参数:
参数 说明 类型 value
/v-model
绑定值 string / number / boolean label
Radio 的 value
string / number / boolean 事件参数:
事件名称 说明 回调参数 change
绑定值变化时触发的事件 选中的 Radio label
值
挑战需求
请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、
id
、class
、DOM 结构、以及函数名等,以免造成无法判题通过。
要求规定
- 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
- 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分。
- 不要篡改已提供的基础项目中的
id
和class
等属性值及 DOM 结构,以免造成检测失败。
通关代码✔️
<template>
<div class="main">
<el-table ref="singleTable"
highlight-current-row :data="tableData"
stripe border style="width: 100%">
<el-table-column label="单选" width="80">
<template slot-scope="scope">
<el-radio v-model="currentRow" :label="scope.row" @change="handleRadioChange(scope.row)"> </el-radio>
</template>
</el-table-column>
<el-table-column label="日期" width="180">
<template slot-scope="scope">
<span style="margin-left:10px">{
{scope.row.date}}</span>
</template>
</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>
<div class="tools">
<el-button @click="setCurrent(tableData[1])">选中第二行</el-button>
<el-button @click="setCurrent()">取消选择</el-button>
</div>
</div>
</template>
<script>
module.exports = {
props: {
tableData: {
type: Array,
default: () => [],
},
},
data() {
return {
currentRow: null,
};
},
methods: {
setCurrent(row) {
this.$refs.singleTable.setCurrentRow(row);
},
handleCurrentRow(row) {
this.setCurrent(row);
},
},
};
</script>
<style scoped>
.main{
width:60%;
margin: 0 auto;
}
.tools{
margin-top:20px;
text-align: center;
}
</style>
代码解析📑
一、HTML 部分
//index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>element-ui 组件二次封装</title> <!-- 引入样式 --> <link rel="stylesheet" href="./element-ui-2.15.10/index.css" /> <script src="./js/vue.min.js"></script> <script src="./js/http-vue-loader.js"></script> <!-- 引入组件库 --> <script src="./element-ui-2.15.10/index.js"></script> </head> <body> <div id="app"> <mytable ref="mytable" :table-data="tableData"></mytable> </div> </body> <script type="text/javascript"> Vue.use(httpVueLoader); var vm = new Vue({ components: { mytable: "url:./mytable.vue", }, el: "#app", data: { that: this, test: "hello", tableData: [ { date: "2016-05-02", name: "王小虎", address: "上海市普陀区金沙江路 1518 弄", }, { date: "2016-05-04", name: "王小虎", address: "上海市普陀区金沙江路 1517 弄", }, { date: "2016-05-01", name: "王小虎", address: "上海市普陀区金沙江路 1519 弄", }, { date: "2016-05-03", name: "王小虎", address: "上海市普陀区金沙江路 1516 弄", }, ], }, }); </script> </html>
(1)头部解析:
- 元数据设置:
meta charset="UTF-8"
:设置页面字符编码为 UTF - 8,确保页面能正确显示各种字符。meta http-equiv="X-UA-Compatible" content="IE=edge"
:让页面在 Internet Explorer 浏览器中以最新的渲染模式显示,提升兼容性。meta name="viewport" content="width=device-width, initial-scale=1.0"
:使页面在不同设备上能自适应显示,根据设备宽度进行缩放。- 资源引入:
link rel="stylesheet" href="./element-ui-2.15.10/index.css"
:引入 Element - UI 的 CSS 样式文件,让页面可以使用 Element - UI 组件的默认样式。script src="./js/vue.min.js"
:引入 Vue.js 库,它是构建用户界面的渐进式 JavaScript 框架,为后续创建 Vue 实例提供支持。script src="./js/http-vue-loader.js"
:http - vue - loader
用于动态加载.vue
文件,它能让我们在 HTML 文件中直接使用.vue
组件。script src="./element-ui-2.15.10/index.js"
:引入 Element - UI 的 JavaScript 组件库,使页面可以使用 Element - UI 提供的各种组件。(2)主体解析:
<div id="app">
:这是 Vue 实例的挂载点,Vue 会控制这个div
及其子元素的渲染和交互。<mytable ref="mytable" :table-data="tableData"></mytable>
:使用自定义组件mytable
,ref
用于在 JavaScript 中引用这个组件实例;:
是 Vue 的动态绑定语法,将tableData
数据传递给mytable
组件的table - data
属性。(3)脚本解析:
Vue.use(httpVueLoader)
:调用httpVueLoader
的安装方法,启用该插件,使其能正常加载.vue
文件。var vm = new Vue({...})
:创建一个 Vue 实例。
components
:注册自定义组件mytable
,"url:./mytable.vue"
告诉http - vue - loader
去加载./mytable.vue
文件。el: "#app"
:将 Vue 实例挂载到id
为app
的 DOM 元素上。data
:定义 Vue 实例的数据对象。
that: this
:在 Vue 实例中,this
的指向在不同函数中可能会改变,这里将当前的this
保存到that
变量中,方便后续使用。test: "hello"
:一个简单的测试数据,不过在当前代码中未被使用。tableData
:一个包含多个对象的数组,每个对象代表表格的一行数据,包含date
、name
和address
三个属性。
二、Vue 部分
(1)模板解析://mytable.vue <template> <div class="main"> <el-table ref="singleTable" highlight-current-row :data="tableData" stripe border style="width: 100%" > <el-table-column label="单选" width="80"> <template slot-scope="scope"> <el-radio v-model="currentRow" :label="scope.row" @change="handleRadioChange(scope.row)"> </el-radio> </template> </el-table-column> <el-table-column label="日期" width="180"> <template slot-scope="scope"> 📅<span style="margin-left: 10px">{ { scope.row.date }}</span> </template> </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> <div class="tools"> <el-button @click="setCurrent(tableData[1])">选中第二行</el-button> <el-button @click="setCurrent()">取消选择</el-button> </div> </div> </template> <script> module.exports = { props: { tableData: { type: Array, default: () => [], }, }, data() { return { currentRow: null, }; }, methods: { setCurrent(row) { this.$refs.singleTable.setCurrentRow(row); // 设置当前选中行 }, handleRadioChange(row) { this.setCurrent(row); }, }, }; </script> <style scoped> .main { width: 60%; margin: 0 auto; } .tools { margin-top: 20px; text-align: center; } </style>
<div class="main">
:作为组件的根元素,应用了main
类,方便进行样式控制。<el-table>
:Element - UI 的表格组件。
ref="singleTable"
:给表格组件设置引用,方便在 JavaScript 中操作该表格。highlight - current - row
:启用高亮显示当前选中行的功能。:data="tableData"
:动态绑定表格的数据,数据来自父组件传递的tableData
。stripe
:使表格显示斑马线样式。border
:为表格添加边框。style="width: 100%"
:设置表格宽度为父元素的 100%。<el-table-column>
:定义表格的列。
- 单选列:
label="单选"
:设置列的标题为 “单选”。width="80"
:设置列的宽度为 80 像素。<template slot - scope="scope">
:使用作用域插槽,scope
包含了当前行的数据信息。<el-radio>
:Element - UI 的单选按钮组件。
v - model="currentRow"
:使用v - model
指令双向绑定当前选中的行数据到currentRow
变量。:label="scope.row"
:将当前行的数据作为单选按钮的值。@change="handleRadioChange(scope.row)"
:当单选按钮状态改变时,调用handleRadioChange
方法并传递当前行的数据。- 日期列:
label="日期"
:设置列的标题为 “日期”。width="180"
:设置列的宽度为 180 像素。<template slot - scope="scope">
:使用作用域插槽显示自定义内容,显示一个日历图标和当前行的date
属性值。- 姓名列和地址列:
prop="name"
和prop="address"
:指定列要显示的数据属性,分别显示name
和address
字段的值。label
:设置列的标题。<div class="tools">
:包含两个操作按钮的容器。
<el-button @click="setCurrent(tableData[1])">
:点击该按钮时,调用setCurrent
方法并传递tableData
数组的第二个元素,即选中第二行。<el-button @click="setCurrent()">
:点击该按钮时,调用setCurrent
方法不传递参数,用于取消选择。(2)脚本解析
props
:定义组件接收的属性。
tableData
:接收一个数组类型的数据,默认值为空数组。data
:定义组件的内部状态。
currentRow
:初始值为null
,用于记录当前选中的行数据。methods
:定义组件的方法。
setCurrent(row)
:通过this.$refs.singleTable.setCurrentRow(row)
设置表格的当前选中行,如果row
为null
则取消选择。handleRadioChange(row)
:当单选按钮状态改变时调用,调用setCurrent
方法将当前选中的行设置为高亮。(3)样式解析
style scoped
:使用scoped
属性确保样式只作用于当前组件。
.main
:设置组件根元素的宽度为父元素的 60%,并使其水平居中显示。.tools
:设置操作按钮容器的顶部边距为 20 像素,并使按钮水平居中显示。
三、工作流程 ▶️
1. 准备工作
- 引入依赖:在 HTML 文件中引入 Vue.js、Element - UI 的样式和组件库,以及
http - vue - loader
插件,为后续开发提供基础环境。- 确定需求:明确要对 Element - UI 的表格组件进行二次封装,添加单选功能和操作按钮。
2. 创建自定义组件
- 创建
.vue
文件:在项目中创建mytable.vue
文件,该文件包含<template>
、<script>
和<style>
三个部分。- 设计模板:在
<template>
中使用 Element - UI 的el - table
组件,并根据需求添加单选按钮和操作按钮。- 定义属性和状态:在
<script>
中通过props
接收父组件传递的数据,通过data
定义组件的内部状态。- 编写方法:在
<script>
的methods
中编写处理逻辑,如设置选中行、处理单选按钮状态改变等。- 添加样式:在
<style>
中添加组件的样式,使用scoped
属性确保样式只作用于当前组件。3. 注册和使用组件
- 注册组件:在 HTML 文件的 Vue 实例中,通过
components
选项注册自定义组件mytable
,并指定组件的路径。- 传递数据:在 HTML 文件中使用
mytable
组件时,通过:
语法将数据传递给组件的props
。- 渲染页面:Vue 实例将根据组件的定义和传递的数据渲染页面,用户可以看到带有单选功能和操作按钮的表格。
通过以上步骤,完成了对 Element - UI 表格组件的二次封装,使其满足特定的业务需求。