2023年2月

在我们一般开发的系统界面里面,列表页面是一个非常重要的综合展示界面,包括有条件查询、列表展示和分页处理,以及对每项列表内容可能进行的转义处理,本篇随笔介绍基于Vue +Element基础上实现表格列表页面的查询,列表展示和字段转义处理。

在前面随笔《
循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理
》介绍了一个对产品列表的卡片式图片分页展示处理,其中涉及到了对于Element 组件分页控件的操作,本篇随笔继续深化这一组件的使用,结合表格展示来处理效果展示。

1、列表查询界面效果

在介绍任何代码处理逻辑之前,我们先来做一个感官的认识,贴上一个效果图,在逐一介绍其中处理的步骤和注意事项。

常规的列表展示界面,一般分为几个区域,一个是查询区域,一个是列表展示区域,一个是底部的分页组件区域。查询区域主要针对常规条件进行布局,以及增加一些全局或者批量的操作,如导入、导出、添加、批量添加、批量删除等按钮;而其中主体的列表展示区域,是相对比较复杂一点的地方,需要对各项数据进行比较友好的展示,可以结合Tag,图标,按钮等界面元素来展示,其中列表一般后面会包括一些对单行记录处理的操作,如查看、编辑、删除的操作,如果是批量删除,可以放到顶部的按钮区域。

2、查询区域的处理

查询区域一般的界面效果如下所示,除了包含一些常用的查询条件,并增加一些常规的处理按钮,如查询、重置、新增、批量删除、导入、导出等按钮。

对于查询区域来说,它也是一个表单的处理,因此也需要添加一一个对应的对象来承载表单的数据,在data里面增加一个searchForm的模型对象,以及一个用于分页查询的pageinfo对象,如下代码所示。

export default{
data() {
return{
listLoading:
true,
pageinfo: {
pageindex:
1,
pagesize:
10,
total:
0},
searchForm: {
ProductNo:
'',
BarCode:
'',
ProductType:
'',
ProductName:
'',
Status:
0},

视图模板代码如下所示

    <el-formref="searchForm":model="searchForm"label-width="80px">
      <el-row>
        <el-col:span="6">
          <el-form-itemlabel="产品编号"prop="ProductNo">
            <el-inputv-model="searchForm.ProductNo" />
          </el-form-item>
        </el-col>
        <el-col:span="6">
          <el-form-itemlabel="产品名称"prop="ProductName">
            <el-inputv-model="searchForm.ProductName" />
          </el-form-item>
        </el-col>
        <el-col:span="6">
          <el-form-itemlabel="商品类型"prop="ProductType">
            <el-selectv-model="searchForm.ProductType"filterable clearable placeholder="请选择">
              <el-optionv-for="(item, key) in typeList":key="key":label="item.value":value="item.key"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col:span="6">
          <el-form-itemlabel="状态"prop="Status">
            <el-selectv-model="searchForm.Status"filterable clearable placeholder="请选择">
              <el-optionv-for="item in Status":key="item.Value":label="item.Text":value="item.Value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <el-rowstyle="float:right;padding-bottom:10px">
      <el-buttonicon="el-icon-search"type="primary"round @click="search()">查询</el-button>
      <el-buttonicon="el-icon-refresh-left"type="warning"round plain @click="resetForm('searchForm')">重置</el-button>
      <el-buttonicon="el-icon-document-add"type="success"round @click="showAdd()">新增</el-button>
      <el-buttonicon="el-icon-document-remove"type="danger"round @click="BatchDelete()">批量删除</el-button>
      <el-buttonicon="el-icon-upload2"type="danger"plain=""round @click="showImport()">导入</el-button>
    </el-row>

其中产品类型的是下拉列表,我们通过在data区域获取一个对象,并在此遍历可以展示字典内容,如果我们花点时间,可以把这些下拉列表统一按照一个常规的处理模式,定义一个字典组件的方式实现,简单赋予一个字典类型的Prop值,就可以绑定下拉列表了,这个稍后在细讲。

在Vue的脚本处理逻辑里面,我们可以在Created声明周期里面,通过API获取数据,绑定在模型上,界面就会自动进行更新了,处理过程代码如下所示。

created() {//获取产品类型,用于绑定字典等用途
    GetProductType().then(data =>{if(data) {
data.forEach(item
=>{this.productTypes.set(item.id, item.name)this.typeList.push({ key: item.id, value: item.name })
})
}
});
//获取列表信息 this.getlist()
},
methods: {
getlist() {
//构造常规的分页查询条件 var param ={
type:
this.producttype === 'all' ? '' : this.producttype,
pageindex:
this.pageinfo.pageindex,
pagesize:
this.pageinfo.pagesize
};
//把SearchForm的条件加入到param里面,进行提交查询 param.type = this.searchForm.ProductType //转换为对应属性 Object.assign(param, this.searchForm);//获取产品列表,绑定到模型上,并修改分页数量 this.listLoading = trueGetProductList(param).then(data=>{this.productlist =data.listthis.pageinfo.total =data.total_countthis.listLoading = false})
},

其中 Object.assign(param, this.searchForm); 语句处理,是把获得的查询条件,覆盖原来对象里面的属性,从而实现查询条件的变量赋值。

获得列表数据,就是介绍如何展示表格列表数据的过程了,表格界面效果如下所示。

先定义一个表格头部,类似HTML里面的<table>的标签,指定样式和一些常规的操作函数,如下代码所示。

    <el-tablev-loading="listLoading":data="productlist"border
fit
stripe
highlight-current-row
:header-cell-style
="{background:'#eef1f6',color:'#606266'}"@selection-change="selectionChange"@row-dblclick="rowDbclick" >

具体的属性可以参考下Element组件关于表格控件的属性了,在表格列里面,我们主要关注它的data绑定即可。

接着定义一列复选框选择的列,用于批量处理的勾选,如批量删除操作。

  <el-table-columntype="selection"width="55"/>

接着就是根据返回JSON属性,逐一进行内容转换为表格列的展示过程了,如下所示。

  <el-table-columnlabel="商品编号"width="80">
    <templateslot-scope="scope">{{ scope.row.ProductNo }}</template>
  </el-table-column>

我们如果需要在显示里面增加处理效果,一般在template里面修改展示效果即可,如下是单位的处理,增加一个tag标志强调下。

  <el-table-columnalign="center"label="单位"width="80">
    <templateslot-scope="scope">
      <el-tagtype=""effect="plain"> {{ scope.row.Unit }}</el-tag>
    </template>
  </el-table-column>

而对于一些需要判断处理的效果,我们可以对内容进行判断输出,如下状态所示。

  <el-table-columnlabel="状态"width="80">
    <templateslot-scope="scope">
      <el-tagv-if="scope.row.Status==0"type=""effect="dark">正常</el-tag>
      <el-tagv-else-if="scope.row.Status==1"type="success"effect="dark">推荐</el-tag>
      <el-tagv-else-if="scope.row.Status==2"type="danger"effect="dark">停用</el-tag>
    </template>
  </el-table-column>

另外,对于一些常见的日期处理,我们可以使用Formatter,Filter等手段进行内容的转义处理,可以去掉后面的时间部分。

<el-table-columnalign="center"label="创建日期"width="120"prop="CreateTime":formatter="dateFormat" />

dataFormat就是一个转义函数,函数代码如下所示。

dateFormat(row, column, cellValue) {return cellValue ? fecha.format(new Date(cellValue), 'yyyy-MM-dd') : ''},

使用的时候,需要在顶部引入一个类库即可

import * as fecha from 'element-ui/lib/utils/date'

对于类似需要进行字典转义的操作,我们可以使用Formatter的方式转义,如增加一个函数来解析对应的值为中文信息

效果可以使用Formatter来转义

productTypeFormat(row, column, cellValue) {var display = this.productTypes.get(cellValue)return display || ''},

也可以使用Filter模式来进行处理。

这里介绍使用Filter的操作处理,首先在界面HTML代码里面增加对应的操作,如下代码所示。

  <el-table-columnalign="center"label="商品类型"width="120"prop="ProductType">
    <templateslot-scope="scope">
      <el-tagtype="danger">  {{ scope.row.ProductType | productTypeFilter }}</el-tag>
    </template>
  </el-table-column>

Filter其实就是一个 | 过滤符号,以及接着一个过滤函数处理即可。

export default{
filters: {
productTypeFilter:
function(value) {if (!value) return '' var display =that.productTypes.get(value)return display || ''}
},

值得注意的是,Filter本身不能引用data里面的属性列表进行转义的需要,如果需要,那么需要在beforeCreate的钩子函数里面记录this的引用,如下代码所示。

对于操作按钮,我们需要增加一行来显示几个按钮即可,如果需要权限控制,可以再根据权限集合判断一下可操作权限即可。

      <el-table-columnlabel="操作"width="140">
        <templatescope="scope">
          <el-row>
            <el-tooltipeffect="light"content="查看"placement="top-start">
              <el-buttonicon="el-icon-search"type="success"circle size="mini"@click="showView(scope.row.ID)" />
            </el-tooltip>
            <el-tooltipeffect="light"content="编辑"placement="top-start">
              <el-buttonicon="el-icon-edit"type="primary"circle size="mini"@click="showEdit(scope.row.ID)" />
            </el-tooltip>
            <el-tooltipeffect="light"content="删除"placement="top-start">
              <el-buttonicon="el-icon-delete"type="danger"circle size="mini"@click="showDelete(scope.row.ID)" />
            </el-tooltip>
          </el-row>
        </template>
      </el-table-column>

这里showView/showEdit/ShowDelete主要就是做一些弹出层前的处理操作,我们在data项里面定义了几个变量,用来确定是那个操作显示的需要。

      isAdd: false,
isEdit:
false,
isView:
false,
isImport:
false,

例如对应编辑操作,我们是需要通过API处理类,获取后端数据,并赋值给编辑框的表单对象上,进行展示即可。

showEdit(id) {//通过ID参数,使用API类获取数据后,赋值给对象展示
      var param ={ id: id }
GetProductDetail(param).then(data
=>{
Object.assign(
this.editForm, data);
})
this.isEdit = true},

对于查看处理,我们除了在每行按钮上可以单击进行查看指定行记录外,我们双击指定的行,也应该弹出对应的查看记录界面

rowDbclick(row, column) {var id =row.IDthis.showView(id);
},

这个就是表格定义里面的一些处理事件

    <el-tablev-loading="listLoading":data="productlist"border
fit
stripe
highlight-current-row
:header-cell-style
="{background:'#eef1f6',color:'#606266'}"@selection-change="selectionChange"@row-dblclick="rowDbclick" >

每个对话框的:visible的属性值,则是确定哪个模态对话框的显示和隐藏。

而对于删除操作,我们只需要确认一下,然后提交远端处理,返回正常结果,就提示用户删除成功即可。如下逻辑代码所示。

showDelete(id) {this.$confirm('您确认删除选定的记录吗?', '操作提示',
{
type:
'warning' //success,error,info,warning //confirmButtonText: '确定', //cancelButtonText: '取消' }
).then(()
=>{//删除操作处理代码 this.$message({
type:
'success',
message:
'删除成功!'});
}).
catch(() =>{this.$message({
type:
'info',
message:
'已取消删除'});
});
},

以上就是常规表格列表页面查询、列表展示、字段转义的一些常规操作,以及对新增、编辑、查看、删除操作的一些常规处理,通过对这些模型的操作,减少了我们以往重新获取对应DOM的繁琐操作,是的数据的操作处理,变得方便了很多。

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题

在我们开发BS页面的时候,往往需要了解常规界面组件的使用,小到最普通的单文本输入框、多文本框、下拉列表,以及按钮、图片展示、弹出对话框、表单处理、条码二维码等等,本篇随笔基于普通表格业务的展示录入的场景介绍这些常规Element组件的使用,使得我们对如何利用Element组件有一个大概的认识。

1、列表界面和其他模块展示处理

在前面随笔《
循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理
》介绍了基于列表展示了相关数据,并在列表界面整合了增删改查等常规的业务操作处理。

常规的列表展示界面,一般分为几个区域,一个是查询区域,一个是列表展示区域,一个是底部的分页组件区域。查询区域主要针对常规条件进行布局,以及增加一些全局或者批量的操作,如导入、导出、添加、批量添加、批量删除等按钮;而其中主体的列表展示区域,是相对比较复杂一点的地方,需要对各项数据进行比较友好的展示,可以结合Tag,图标,按钮等界面元素来展示,其中列表一般后面会包括一些对单行记录处理的操作,如查看、编辑、删除的操作,如果是批量删除,可以放到顶部的按钮区域。

对于常规按钮、表格、分页组件,前面已经做了相关的介绍,这里就不再赘述。

在介绍具体界面组件的时候,我们先来了解下,整体的界面布局,我们把常规的列表界面,新增、编辑、查看、导入等界面放在一起,除了列表页面,其他内容以弹出层对话框的方式进行处理,如下界面示意所示。

每个对话框的:visible的属性值,则是确定哪个模态对话框的显示和隐藏。

在Vue的JS模块里面,我们除了定义对应的对话框显示的变量外,对每个对话框,我们定义一个表单信息用来进行数据的双向绑定处理。

常规的新增、编辑、查看、导入等内容的定义,作为一个对话框组件定义,常规的对话框组件的使用代码如下所示。

<el-dialogtitle="提示":visible.sync="dialogVisible"width="30%":before-close="handleClose">
  <span>这是一段信息</span>
  <spanslot="footer"class="dialog-footer">
    <el-button@click="dialogVisible = false">取 消</el-button>
    <el-buttontype="primary"@click="dialogVisible = false">确 定</el-button>
  </span>
</el-dialog>

为了控制对话框的样式,我们这里注意下footer的slot,这个我们一般是把处理按钮放在这里,如对于查看界面对话框,我们定义如下所示。

一般来说,对于表单内容比较多的场景,我们一般分开多个选项卡进行展示或者录入,这样方便管理,查看界面整体效果如下所示。

对于对话框的数据绑定,我们在打开对话框前,先通过API模块请求获得JSON数据,然后绑定在对应的对话框模型属性上即可,如对于查看界面,我们的处理逻辑如下所示。

showView(id) {var param ={ id: id }
GetProductDetail(param).then(data
=>{
Object.assign(
this.viewForm, data);
})
this.isView = true},

对于表格的双击,我们同样绑定它的查看明细处理操作,如下模板代码和JS代码所示。

模板HTML代码如下:

<el-tablev-loading="listLoading":data="productlist"border
fit
stripe
highlight-current-row
:header-cell-style
="{background:'#eef1f6',color:'#606266'}"@selection-change="selectionChange"@row-dblclick="rowDbclick" >

JS逻辑代码如下

rowDbclick(row, column) {var id =row.IDthis.showView(id);
},

2、常规界面组件的使用

一般情况下,我们使用界面组件的时候,参考下官网《
Element组件使用
》,寻找对应组件的代码进行参考,就差不多了,这里还是就各种常规的Element组件进行大概的介绍吧。

1)表单和表单项、单文本框

对于表单,我们一般定义一个对应的名称,并设置它的data对应的模型名称即可,如下所示。

<el-formref="viewForm":model="viewForm"label-width="80px">

而表单项,一般是定义好表单项的Label即可,然后在其中插入对应的录入控件或者展示控件。如对于单文本组件使用,如下所示。

 <el-form-itemlabel="产品编号">
   <el-inputv-model="editForm.ProductNo" />
 </el-form-item>

其中 v-model="editForm.ProductNo"  就是对应绑定的数据。

而表单项,可以添加对字段的验证处理,在数据提交前,可以校验客户的录入是否有效等。

  <el-form-itemprop="email"label="邮箱":rules="[
{ required: true, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
]"
> <el-inputv-model="dynamicValidateForm.email"></el-input> </el-form-item>

注意这里表单项,必须添加一个prop的属性设置,如 prop="email" 所示。

一般为了控制布局,我们还结合el-row进行一个布局的处理,如下代码所示(一行等于span为24,span=12也就是一行放两个控件组)。

<el-row>
  <el-col:span="12">
    <el-form-itemlabel="产品编号">
      <el-inputv-model="editForm.ProductNo" />
    </el-form-item>
  </el-col>
  <el-col:span="12">
    <el-form-itemlabel="条码">
      <el-inputv-model="editForm.BarCode" />
    </el-form-item>
  </el-col>
</el-row>

2)、下拉列表控件的绑定

下拉列表的绑定处理,也是通过 v-model 进行值的绑定,而选项则可以通过数据列表进行绑定。

<el-form-itemlabel="商品类型">
  <el-selectv-model="editForm.ProductType"filterable=""placeholder="请选择">
    <el-optionv-for="(item, key) in typeList":key="key":label="item.value":value="item.key"
    />
  </el-select>
</el-form-item>

而选项中的 typeList,我们可以在页面初始化的时候获取出来即可。

created() {//获取产品类型,用于绑定字典等用途
    GetProductType().then(data =>{if(data) {
data.forEach(item
=>{this.productTypes.set(item.id, item.name)this.typeList.push({ key: item.id, value: item.name })
})
//获取列表信息 this.getlist()
}
});
},

对于textarea常规的多行文本框,其实和普通单行文本框处理差不多,指定它的type="textarea" 和 rows的数值即可。

  <el-tab-panelabel="说明"name="second">
    <el-form-itemlabel="说明">
      <el-inputv-model="editForm.Description"type="textarea":rows="10" />
    </el-form-item>
  </el-tab-pane>

而对于一些可能需要展示HTML内容的,我们可以使用DIV控件来展示,通过v-html标识来处理包含HTML代码的内容。

  <el-tab-panelabel="详细说明">
    <el-form-itemlabel="详细说明">
      <divclass="border-radius"v-html="viewForm.Note" />
    </el-form-item>
  </el-tab-pane>

3)、图片展示

对于一些需要展示服务器图片,我们请求后,根据Element图片组件的设置处理即可,如下包括单个图片和多个图片的展示和预览操作。

图片展示的代码如下所示。

  <el-tab-panelabel="图片信息">
    <el-form-itemlabel="封面图片">
      <el-imagestyle="width: 100px; height: 100px":src="viewForm.Picture":preview-src-list="[viewForm.Picture]"
      />
    </el-form-item>
    <el-form-itemlabel="Banner图片">
      <el-imagestyle="width: 100px; height: 100px":src="viewForm.Banner":preview-src-list="[viewForm.Banner]"
      />
    </el-form-item>
    <el-form-itemlabel="商品展示图片">
      <el-imagev-for="item in viewForm.pics":key="item.key"class="border-radius":src="item.pic"style="width: 100px; height: 100px;padding:10px":preview-src-list="getPreviewPics()"
      />
    </el-form-item>
  </el-tab-pane>

上图中,如果是单个图片,那么预览我们设置一个集合为一个url即可,如 [viewForm.Banner],如果是多个图片,需要通过一个函数来获取图片列表,如 getPreviewPics() 函数所示。

getPreviewPics() {//转换ViewForm.pics里面的pic集合
      var list =[]if (this.viewForm.pics) {this.viewForm.pics.forEach(item =>{if(item.pic) {
list.push(item.pic)
}
})
}
returnlist
}

4)、第三方扩展控件

对于一些需要使用扩展组件的,我们一般搜索下解决方案,通过npm安装对应的组件即可解决,如对于条码和二维码,我使用 @chenfengyuan/vue-barcode和 @chenfengyuan/vue-qrcode,一般在Github上搜索下关键字,总能找到一些很受欢迎的第三方组件。

安装这些组件都有具体的说明,如下所示(
如果卸载,直接修改install为uninstall即可
)。

npm install @chenfengyuan/vue-barcode vue

以及

npm install @chenfengyuan/vue-qrcode vue

条码和二维码的展示效果如下所示

如果全局引入barcode和qrcode 组件,我们在main.js里面引入即可,如下代码所示

//引入barcode,qrcode
import VueBarcode from '@chenfengyuan/vue-barcode';
import VueQrcode from
'@chenfengyuan/vue-qrcode';
Vue.component(VueBarcode.name, VueBarcode);

富文本编辑,我这里采用了 Tinymce 第三方组件来实现编辑处理,展示效果如下所示。

代码如下所示

  <el-tab-panelabel="详细说明"name="third">
    <el-form-itemlabel="详细说明">
      <tinymcev-model="editForm.Note":height="300" />
    </el-form-item>
  </el-tab-pane>

以上就是一些常规的界面组件的使用,后面在继续介绍文件上传和图片结合的操作。

3、自定义组件的创建使用

使用Vue的比以往BS开发的好处,就是可以很容易实现组件化,这点很好,一旦我们定义好一个控件,就可以在多个界面里面进行使用,非常方便,而且封装性可以根据自己的需要进行处理。

查询区域一般的界面效果如下所示,除了包含一些常用的查询条件,一般会有一些下拉列表,这些可能是后台字典里面绑定的内容,可以考虑作为一个通用的字典下拉列表组件来做。

其实界面录入的时候,也往往需要这些条件下拉列表的。

那么我们来定义一个自定义组件,并在界面上使用看看。

在Components目录创建一个目录,并创建一个组件的vue文件,命名为my-dictdata.vue,如下所示。

界面模板代码我们就一个select组件为主即可。

<template>
  <el-selectv-model="svalue"filterable clearable placeholder="请选择">
    <el-optionv-for="(item, index) in dictItems":key="index":label="item.Text":value="item.Value"
    />
  </el-select>
</template>

script脚本逻辑代码如下所示。

<script>
//引入API模块类方法
import { GetDictData } from'@/api/dictdata'exportdefault{
name:
'MyDictdata',//组件的名称 props: {
typeName: {
//字典类型方式,从后端字典接口获取数据 type: String,default:''},
options: {
//固定列表方式,直接绑定 type: Array,default: ()=>{return[] }
}
},
data() {
return{
dictItems: [],
//设置的字典列表 svalue:'' //选中的值 }
},
watch: {
//判断下拉框的值是否有改变 svalue(val, oldVal) {if(val!==oldVal) {this.$emit('input',this.svalue);
}
}
},
mounted() {
varthat= this;if(this.typeName&& this.typeName!== '') {//使用字典类型,从服务器请求数据 GetDictData(this.typeName).then(data=>{if(data) {
data.forEach(item
=>{if(item&& typeof(item.Value)!== 'undefined' &&item.Value!== '') {
that.dictItems.push(item)
}
});
}
})
}
else if(this.options&& this.options.length> 0) {//使用固定字典列表 this.options.forEach(item=>{if(item&& typeof(item.Value)!== 'undefined' &&item.Value!== '') {
that.dictItems.push(item)
}
});
}
//设置默认值 this.svalue= this.value;
},
methods: {

}
}
</script>

主要就是处理字典数据的获取,并绑定到模型对象上即可。

在页面上使用前,需要引入我们定义的组件

import myDictdata from '@/components/Common/my-dictdata'

然后包含进去components里面即可

export default{
components: { myDictdata},

那么原来需要直接使用select组件的代码

<el-selectv-model="searchForm.ProductType"filterable clearable placeholder="请选择">
  <el-optionv-for="(item, key) in typeList":key="key":label="item.value":value="item.key"
  />
</el-select>

则可以精简为一行代码

<my-dictdatav-model="searchForm.ProductType"type-name="商品类型" />

而对于固定列表的,我们也可以通用的处理代码

<my-dictdatav-model="searchForm.Status":options="Status" />

其中Status是定义的一个对象集合

Status: [
{ Text:
'正常', Value: 0},
{ Text:
'推荐', Value: 1},
{ Text:
'停用', Value: 2}
]

是不是非常方便,而得到的效果则不变。

以上就是多个页面内容,通过对话框层模式整合在一起,并介绍如何使用,以及对界面中常见的Element组件进行介绍如何使用,以及定义一个字典列表的主定义组件,用于简化界面代码使用,

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题

在我们使用VUE+Element 处理界面的时候,往往碰到需要利用JS集合处理的各种方法,如Filter、Map、reduce等方法,也可以涉及到一些对象属性赋值等常规的处理或者递归的处理方法,以前对于这些不是很在意,但往往真正使用的时候,需要了解清楚,否则很容易脑袋出现短路的情况。本篇随笔列出一些在VUE+Element 前端开发中经常碰到的JS处理场景,供参考学习。

1、常规集合的filter、map、reduce处理方法

filter函数的主要用途是对数组元素进行过滤,并返回一个符合条件的元素的数组

const nums = [10,20,30,666666,222,333]
let newNums
=nums.filter(function(n){return n<100})

输出:[10,20,30]

map函数是对数组每个元素的映射操作,并返回一个新数组,原数组不会改变将newNums中每个数字乘2

const nums = [10,20,30,666666,222,333]
let newNums
=nums.map(function(n){return n*2})

输出:[20,40,60,222,666]

reduce函数主要用于对数组所有元素的汇总操作,如全部相加、相乘等

const nums = [10,20,30,666666,222,333]
let newNums
=nums.reduce(function(preValue,n){return PreValue+n
},
0)

输出:726

有时候可以结合几种处理方式一起,如下综合案例所示。

const nums = [10,20,30,666666,222,333]
let newNums
=nums.filter(function(n){return n<100}).map(function(n){return n*2}).reduce(function(preValue,n){return preValue+n
},
0)

结果:120

另外还有一个数组集合的find方法,和filter方法类似。

find()方法主要用来返回数组中
符合条件的第一个元素
(没有的话,返回undefined)

 var Array = [1,2,3,4,5,6,7];var result = Array.find(function(value){return value > 5;   //条件
});
console.log(result);
//6 console.log(Array);//[1,2,3,4,5,6,7]

同样我们也可以在vue里面,利用require.context的处理机制,遍历文件进行处理,也需要用到了filter,如下代码所示。

下面代码是我对某个文件夹里面的文件进行一个过滤处理操作

const req = require.context('vue-awesome/icons', true, /\.js$/)
const requireAll
= requireContext =>requireContext.keys()

const re
= /\.\/(.*)\.js/const vueAwesomeIcons= requireAll(req).filter((key) => { return key.indexOf('index.js') < 0 }).map(i =>{return i.match(re)[1]
})

export
default vueAwesomeIcons

2、递归处理

有时候,我们需要从一个JSON集合里面,由于集合是嵌套的,如children里面还有chilren集合,根据某个关键属性进行查询,这种处理方式就要用到递归了。

例如我定义的一个菜单集合里面,就是这样一个嵌套的结构,需要根据名称来获得对应的对象的时候,就涉及到了一个递归处理函数。

首先我们来看看菜单的JSON集合。

//此菜单数据一般由服务器端返回
export const asyncMenus =[
{
id:
'1',
pid:
'-1',
text:
'首页',
icon:
'dashboard',
name:
'dashboard'},
{
id:
'2',
pid:
'-1',
text:
'产品信息',
icon:
'table',
children: [
{
id:
'2-1',
pid:
'2',
text:
'产品展示',
name:
'product-show',
icon:
'table'}]
},
{
id:
'3',
pid:
'-1',
text:
'杂项管理',
icon:
'example',
children: [
{
id:
'3-1',
pid:
'3',
text:
'图标管理',
name:
'icon',
icon:
'example'},{
id:
'3-3',
pid:
'3',
text:
'树功能展示',
name:
'tree',
icon:
'tree'},
{
id:
'3-2',
pid:
'3',
text:
'二级菜单2',
icon:
'tree',
children: [
{
id:
'3-2-2',
pid:
'3-2',
text:
'三级菜单2',
name:
'menu1-1',
icon:
'form'}]
}
]
}
]

如果我们需要根据ID来遍历查询,就是一个典型的递归查询处理。

    //根据菜单id来获取对应菜单对象
FindMenuById(menuList, menuid) {for (var i = 0; i < menuList.length; i++) {var item =menuList[i];if (item.id && item.id ===menuid) {returnitem
}
else if(item.children) {var foundItem = this.FindMenuById(item.children, menuid)if (foundItem) { //只有找到才返回 returnfoundItem
}
}
}
}

这里值得注意的是,不能在递归的时候,使用下面直接返回

return this.FindMenuById(item.children, menuid)

而需要判断是否有结果在进行返回,否则嵌套递归就可能返回undefined类型

  var foundItem = this.FindMenuById(item.children, menuid)if (foundItem) { //只有找到才返回
    returnfoundItem
}

3、forEach遍历集合处理

在很多场合,我们也需要对集合进行一个forEach的遍历处理,如下根据它的键值进行处理,注册全局过滤器的处理操作

//导入全局过滤器
import * as filters from './filters'
//注册全局过滤器
Object.keys(filters).forEach(key =>{
Vue.filter(key, filters[key])
})

或者我们在通过API方式获取数据后,对集合进行处理的操作

    //获取产品类型,用于绑定字典等用途
    GetProductType().then(data =>{if(data) {this.treedata = [];//树列表清空
        data.forEach(item =>{this.productTypes.set(item.id, item.name)this.typeList.push({ key: item.id, value: item.name })var node ={ id: item.id, label: item.name }this.treedata.push(node)
})
//获取列表信息 this.getlist()
}
});

又或者请求字典数据的时候,进行一个非空值的判断处理。

      //使用字典类型,从服务器请求数据
      GetDictData(this.typeName).then(data =>{if(data) {
data.forEach(item
=>{if (item && typeof (item.Value) !== 'undefined' && item.Value !== '') {
that.dictItems.push(item)
}
});
}
})

forEach()方法也是用于对数组中的每一个元素执行一次回调函数,
但它没有返回值
(或者说它的返回值为undefined,即便我们在回调函数中写了return语句,返回值依然为undefined)

注意: 如果forEach里有两个参数,则第一个参数为该集合里的元素,第二个参数为集合的索引;

4、Object.assign赋值方法

在有些场合,我们需要把全新的集合,复制到另一个对象上,替换原来对象的属性值,那么我们可以利用Object对象的assign方法。

如在编辑界面展示的时候,把请求到的对象属性复制到表单对象上。

      var param ={ id: id }
GetProductDetail(param).then(data
=>{
Object.assign(
this.editForm, data);
})

或者查询的时候,获得查询条件,进行部分替换

      //构造常规的分页查询条件
      var param ={
type:
this.producttype === 'all' ? '' : this.producttype,
pageindex:
this.pageinfo.pageindex,
pagesize:
this.pageinfo.pagesize
};
//把SearchForm的条件加入到param里面,进行提交查询 param.type = this.searchForm.ProductType //转换为对应属性 Object.assign(param, this.searchForm);

5、slice() 方法

slice() 方法可从已有的数组中返回选定的元素。

语法如下所示。

arrayObject.slice(start,end)

如下案例所示。

let red = parseInt(color.slice(0, 2), 16)
let green
= parseInt(color.slice(2, 4), 16)
let blue
= parseInt(color.slice(4, 6), 16)

或者我们结合filter函数对图标集合进行获取部分处理

vueAwesomeIconsFiltered: function() {
const that
= this var list = that.vueAwesomeIcons.filter(item => { return item.indexOf(that.searchForm.label) >= 0})if (that.searchForm.pagesize > 0) {return list.slice(0, that.searchForm.pagesize)
}
else{returnlist;
}
}

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题

在我前面随笔《
循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用
》里面曾经介绍过一些常规的界面组件的处理,主要介绍到单文本输入框、多文本框、下拉列表,以及按钮、图片展示、弹出对话框、表单处理,本篇随笔补充这一个主题,介绍树列表组件和下拉列表树组件在项目中的使用,以及一个SplitPanel的组件。

1、常规树列表控件的使用

众所周知,一般界面很多情况涉及到树列表的处理,如类型展示,如果是一层的,可以用下拉列表代替,如果是多个层级的,采用树控件展示会更加直观。

在Element里面也有一个el-tree的控件,如下所示,这里主要对它的各种属性和方法进行介绍。

简单的代码如下所示

<el-tree:data="data"@node-click="handleNodeClick"></el-tree>

主要在script部分里面指定它的data数据,以及单击节点的事件处理,结合卡片控件的展示,我们可以把树放在其中进行展示

界面代码如下所示,通过 default-expand-all 可以设置全部展开,icon-class 指定节点图标(也可以默认不指定)

        <el-cardclass="box-card">
          <divslot="header"class="clearfix">
            <span>树列表</span>
            <el-buttonstyle="float: right; padding: 3px 0"type="text">操作按钮</el-button>
          </div>
          <div>
            <el-treestyle="padding-top:10px":data="treedata"node-key="id"default-expand-all
icon-class
="el-icon-price-tag"highlight-current
@node-click
="handleNodeClick" > <spanslot-scope="{ node, data }"class="custom-tree-node"> <span> <i:class="node.icon ? node.icon : 'el-icon-price-tag'" />{{ node.label }}&nbsp;&nbsp; </span> </span> </el-tree> </div> </el-card>

其中界面里面,我们通过 class="custom-tree-node",来指定树列表的展现内容,可以加入图标等信息

而在script里面,定义了一个treedata的属性

      //初始化树列表
treedata: [
{
label:
'一级 1',
id:
'1',
children: [{
id:
'1-1',
label:
'二级 1-1',
children: [{
label:
'三级 1-1-1',
id:
'1-1-1'}, {
label:
'三级 1-1-2',
id:
'1-1-2'}, {
label:
'三级 1-1-3',
id:
'1-1-3'}]
}]
}
]

如果设置有选择框,得到界面如下所示。

主要设置  show-checkbox 和 @check-change="handleCheckChange" 即可。

界面代码如下所示

<el-treestyle="padding-top:10px":data="treedata"node-key="id"default-expand-all
highlight-current
show-checkbox
:default-checked-keys
="['1-1-1']"@node-click="handleNodeClick"@check-change="handleCheckChange" > <spanslot-scope="{ node, data }"class="custom-tree-node"> <span> <i:class="node.icon ? node.icon : 'el-icon-price-tag'" />{{ node.label }}&nbsp;&nbsp; </span> </span> </el-tree>

而对于树列表,可以进行一个过滤处理操作,如下界面所示。

在内容区增加一个input的文本框进行过滤处理,并绑定对应的属性变量

<el-inputv-model="filterText"placeholder="输入关键字进行过滤"clearable
prefix-icon
="el-icon-search" />

树列表控件需要增加过滤函数绑定 :filter-node-method="filterNode",如下代码所示。

<el-treeref="tree"class="filter-tree"style="padding-top:10px":data="treedata"node-key="id"default-expand-all
highlight-current
show-checkbox
:filter-node-method
="filterNode"@check-change="handleCheckChange"@node-click="handleNodeClick" > <spanslot-scope="{ node, data }"class="custom-tree-node"> <span> <i:class="node.icon ? node.icon : 'el-icon-price-tag'" />{{ node.label }}&nbsp;&nbsp; </span> </span> </el-tree>

script的处理代码如下所示,需要watch过滤的绑定值,变化就进行过滤处理。

为了在列表结合中进行快速的过滤,我们可以在上次介绍的列表界面里面增加一个树列表的快速查询处理。如下界面所示。

这里列表里面增加了一个第三方组件 splitpanes,用来划分区块展示,而且可以拖动,非常不错,地址是:
https://github.com/antoniandre/splitpanes

这个组件的Demo展示地址如下所示:
https://antoniandre.github.io/splitpanes

效果大概如下所示

npm 安装如下所示

npm i --S splitpanes

安装成功后,然后在vue文件的script部分里面引入即可

import { Splitpanes, Pane } from 'splitpanes'import'splitpanes/dist/splitpanes.css'

它的使用代码也很简单

<splitpanesstyle="height: 400px">
  <panemin-size="20">1</pane>
  <pane>
    <splitpaneshorizontal>
      <pane>2</pane>
      <pane>3</pane>
      <pane>4<pane>
    </splitpanes>
  </pane>
  <pane>5</pane>
</splitpanes>

我的列表界面使用了两个Panel即可实现左侧树的展示,和右侧常规列表查询的处理。

2、下拉框树列表的处理

除了常规的树列表展示内容外,我们也需要一个在下拉列表中展示树内容的界面组件。

这里又得引入一个第三方的界面组件,因此Element的Select组件不支持树列表。

GitHub地址:
https://github.com/riophae/vue-treeselect

官网地址:
https://vue-treeselect.js.org/

NPM安装:

npm install --save @riophae/vue-treeselect

界面代码如下所示。

<template>
  <divid="app">
    <treeselectv-model="value":multiple="true":options="options" />
  </div>
</template>

这里的value就是选中的集合,options则是树列表的节点数据。

<script>
  //import the component
import Treeselect from'@riophae/vue-treeselect'
  //import the styles
import'@riophae/vue-treeselect/dist/vue-treeselect.css'exportdefault{//register the component
components: { Treeselect },
data() {
return{//define the default value value:null,//define options options: [ {
id:
'a',
label:
'a',
children: [ {
id:
'aa',
label:
'aa',
}, {
id:
'ab',
label:
'ab',
} ],
}, {
id:
'b',
label:
'b',
}, {
id:
'c',
label:
'c',
} ],
}
},
}
</script>

我的测试界面代码如下所示

          <divstyle="height:180px">
            <!--v-model 绑定选中的集合
options 树节点数据
defaultExpandLevel 展开层次,Infinity为所有
flat 为子节点不影响父节点,不关联
--> <treeselectv-model="value":options="treedata":multiple="true":flat="true":default-expand-level="Infinity":open-on-click="true":open-on-focus="true"clearable
:max-height
="200" /> </div>
<script>
//import vue-treeselect component
import Treeselect from'@riophae/vue-treeselect'
//import the styles
import'@riophae/vue-treeselect/dist/vue-treeselect.css'exportdefault{
name:
'Tree',
components: { Treeselect },
data() {
return{//过滤条件 filterText:'',//初始化树列表 treedata: [
{
label:
'一级 1',
id:
'1',
children: [{
id:
'1-1',
label:
'二级 1-1',
children: [{
label:
'三级 1-1-1',
id:
'1-1-1'}, {
label:
'三级 1-1-2',
id:
'1-1-2'}, {
label:
'三级 1-1-3',
id:
'1-1-3'}]
}]
}
],
value: [
'1-1-2']
}
},
................
}
</script>

来一张几个树列表一起的对比展示界面。

以上就是普通树列表和下拉列表树展示的界面效果,往往我们一些特殊的界面处理,就需要多利用一些封装良好的第三方界面组件实现,可以丰富我们的界面展示效果。

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题

我们开发的系统,一般可以不用考虑语言国际化的问题,大多数系统一般是给本国人使用的,而且直接使用中文开发界面会更加迅速 一些,不过框架最好能够支持国际化的处理,以便在需要的时候,可以花点时间来实现多语言切换的处理,使系统具有更广泛的受众用户。VUE+Element 前端应用实现国际化的处理还是非常方便的,一般在Main.js函数里面引入语言文件,然后在界面上进行一定的处理,把对应的键值转换为对应语言的语义即可。本篇随笔介绍在VUE+Element 前端应用中如何实现在界面快速的支持多语言国际化的处理逻辑代码。

1、main入口函数支持

Element 组件内部默认使用中文,若希望使用其他语言,则需要进行多语言设置。以英文为例,在 main.js 中:

//完整引入 Element
import Vue from 'vue'import ElementUI from'element-ui'import locale from'element-ui/lib/locale/lang/en'Vue.use(ElementUI, { locale })

由于我们现在是需要处理多语言的切换,那么,我们在src下面的一个目录里面创建一个lang目录,在其中里面编辑zh.js和en.js分别代表中英文语言对照信息,index.js文件则为引入这两个文件的处理关系。

在index.js里面,需要设置一个函数,用来获取Cookie里面存储的语言,如果没有找到,以浏览器国际化语言为准,如下代码所示。

export functiongetLanguage() {
const chooseLanguage
= Cookies.get('language')if (chooseLanguage) returnchooseLanguage//如果没有选择语言,那么使用浏览器语言 const language = (navigator.language ||navigator.browserLanguage).toLowerCase()
const locales
=Object.keys(messages)for(const locale of locales) {if (language.indexOf(locale) > -1) {returnlocale
}
}
return 'en'}

其中代码行

const locales = Object.keys(messages)

是获取message对象里面的键,如下所示。

import Vue from 'vue'import VueI18n from'vue-i18n'import Cookies from'js-cookie'import elementEnLocale from'element-ui/lib/locale/lang/en' //element-ui lang
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'//element-ui lang
import enLocale from './en'import zhLocale from'./zh'Vue.use(VueI18n)//定义对应语言键,展开对应的键值对应表
const messages ={
en: {
...enLocale,
...elementEnLocale
},
zh: {
...zhLocale,
...elementZhLocale
}
}

其中message就是一个两个语言(en/zh)字典下的对照表,包含各自对应键值下的内容。

然后整个index.js文件就是公布对应的多语言处理接口和属性。

const i18n = newVueI18n({
locale: getLanguage(),
messages
})

export
default i18n

然后在main.js函数里面处理国际化的处理即可

Vue.use(ElementUI, {
size: Cookies.get(
'size') || 'medium', //set element-ui default size i18n: (key, value) =>i18n.t(key, value) })newVue({
el:
'#app',
router,
store,
i18n,
render: h
=>h(App)
})

有了这些准备,那么我们在界面上就可以调用对应的键来获取对应语言的语义了,

2、界面处理实现

首先,我们编辑一下对应国际化的键值内容,例如中文参照如下所示。

例如对应登录界面上,界面效果如下所示。

或者

其中里面的文本内容,我们都是以国际化处理内容。

如登陆表单里面的代码如下所示。

        <el-formref="loginForm":model="loginForm":rules="rules"class="loginForm">
          <el-form-itemprop="username"class="login-item">
            <el-inputv-model="loginForm.username"class="area"type="text":placeholder="$t('login.username')"prefix-icon="el-icon-user-solid"@keyup.enter.native="submitForm('loginForm')"
            />
          </el-form-item>
          <el-form-itemprop="password"class="login-item">
            <el-inputv-model="loginForm.password"class="area"type="password":placeholder="$t('login.password')"prefix-icon="el-icon-lock"@keyup.enter.native="submitForm('loginForm')"
            />
          </el-form-item>

          <el-form-item>
            <el-button:loading="loading"type="primary"class="submit_btn"@click="submitForm('loginForm')">{{ $t('login.logIn') }}</el-button>
          </el-form-item>
          <divclass="tiparea">
            <spanstyle="margin-right:20px;">{{ $t('login.username') }} : admin</span>
            <span> {{ $t('login.password') }} : {{ $t('login.any') }}</span>
          </div>
        </el-form>

我们多处采用了类似 $t('login.username') 的函数处理方式来动态获取对应语言的内容即可,其中$t()函数里面就是对应的语义解析的键参数,对应我们lang/zh.js里面或者lang/en.js里面的内容即可。

其中多语言切换的时候,单击图标就可以切换为其他语言内容了。

切换英文后界面如下所示

同样,其他地方,如果需要切换多语言的国际化处理,也可以使用$t的转义方式,在顶部导航栏里面,我们可以设置得到多语言支持的界面。

中文界面提示如下所示。

这部分的实现代码是在组件模块里面,一样可以实现国际化的处理的。

  <templatev-if="device!=='mobile'">
    <searchid="header-search"class="right-menu-item" />
    <error-logclass="errLog-container right-menu-item hover-effect" />
    <el-tooltip:content="$t('navbar.fullscreen')"effect="dark"placement="bottom">
      <screenfullid="screenfull"class="right-menu-item hover-effect" />
    </el-tooltip>
    <el-tooltip:content="$t('navbar.size')"effect="dark"placement="bottom">
      <size-selectid="size-select"class="right-menu-item hover-effect" />
    </el-tooltip>
    <el-tooltip:content="$t('navbar.language')"effect="dark"placement="bottom">
      <lang-selectclass="right-menu-item hover-effect" />
    </el-tooltip>
  </template>

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理


循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用


循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用


循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理


循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

VUE+Element 前端应用开发框架功能介绍

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

使用代码生成工具快速生成基于ABP框架的Vue+Element的前端界面

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

电商商品数据库的设计和功能界面的处理

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

部署基于.netcore5.0的ABP框架后台Api服务端,以及使用Nginx部署Vue+Element前端应用

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志

循序渐进VUE+Element 前端应用开发(32)--- 手机短信动态码登陆处理

循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

使用代码生成工具快速开发ABP框架项目

使用Vue-TreeSelect组件实现公司-部门-人员级联下拉列表的处理

使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题