通过社交网站来做招聘决定,wordpress流量站,网站主要内容,网站设计的流程是怎样的背景
照惯例#xff0c;先交待下背景#xff0c;从真实需求出发#xff0c;讲述实现效果、设计思路和实现方式。 软件系统中#xff0c;会有一些常见常用的选择功能#xff0c;如部门选择、人员选择等#xff0c;用于填报表单#xff0c;使用频率很高。直接使用一方面会…背景
照惯例先交待下背景从真实需求出发讲述实现效果、设计思路和实现方式。 软件系统中会有一些常见常用的选择功能如部门选择、人员选择等用于填报表单使用频率很高。直接使用一方面会比较繁琐另一方面造成代码重复当需要调整时则需要遍历整个项目源码容易因漏改引发问题。这种情况下更好的实现方案是通过封装组件来实现简化使用和复用的目的。 前面有一篇介绍了使用VUE自定义组件封装数据字典功能比较简单今天进一步封装一个比较复杂的部门单选组件其他业务实体如人员、角色等实现非常类似就不再赘述。
实现效果
首先展示下实现效果。 用户管理列表左边是部门树右侧是用户列表如下图。 点击“新增”按钮打开用户编辑页面自动显示传入的部门。
第一行就是我们封装的部门单选组件点击最右侧的图标弹出部门选择页面来。
选择新部门后确定即可实现部门的变更。
站在使用的角度看也非常简单用户编辑页面整体源码如下
templateel-dialog :titletitle :visiblevisible closevisiblefalseel-formrefform:modelentityData:rulesruleslabel-width80pxlabel-positionrightstylewidth:90%;margin:0px auto;!--表单区域 --el-form-item label组织机构 proporganizationIdorganization-single-selectv-modelentityData.organizationId//el-form-itemel-form-item label账号 propaccountel-input v-modelentityData.account //el-form-itemel-form-item label姓名 propnameel-input v-modelentityData.name //el-form-itemel-form-item label职务 proppositionel-input v-modelentityData.position //el-form-itemel-form-item label性别 propgenderdictionary-radio-groupv-modelentityData.gender:codeconstant.DICTIONARY_TYPE_CODES.GENDER//el-form-itemel-form-item label出生日期 propbirthdayel-date-pickerv-modelentityData.birthdayvalue-formatyyyy-MM-dd HH:mm:ssformatyyyy年MM月dd日typedateplacementbottom-endplaceholder请选择classform-item//el-form-itemel-form-item label手机号 proptelephoneel-input v-modelentityData.telephone //el-form-itemel-form-item label邮箱地址 propemailel-input v-modelentityData.email //el-form-itemel-form-item label状态 propstatusdictionary-radio-groupv-modelentityData.status:codeconstant.DICTIONARY_TYPE_CODES.STATUS//el-form-itemel-form-item label排序号 proporderNoel-input v-modelentityData.orderNo //el-form-item/el-formdiv slotfooter classdialog-footerel-button v-showsaveButtonVisible typeprimary clicksave保存/el-buttonel-button clickclose关闭/el-button/div/el-dialog
/template引入部门单选组件后具体使用的时候只需要如下代码即可
el-form-item label组织机构 proporganizationIdorganization-single-selectv-modelentityData.organizationId//el-form-item也就是说封装组件后使用部门单选功能跟使用一个文本输入框类似所有与之相关的页面展现和逻辑处理都在组件内部实现了是不是对使用方非常友好
设计与实现
技术栈采用的还是vue2.0UI组件库使用element ui。
使用简单是因为将复杂工作封装在了内部这里同样用组件化的思路将部门单选组件拆分成了两个vue页面一个是整体组件负责文本框的展示对弹出部门选择页面的调度另一个是负责具体的部门选择。
先附上整体组件源码
templatedivel-input v-modelorganizationName disabledel-button slotappend iconel-icon-s-grid clickopenModal //el-inputorganization-modal reforganizationModel okhandleOK //div
/templatescript
import OrganizationModal from ./OrganizationModal
export default {name: OrganizationSingleSelect,components: {OrganizationModal},model: {prop: value,event: change},props: {width: {type: Number,default: 500,required: false},value: {type: String,default: ,required: false},disabled: {type: Boolean,required: false,default: false}},data() {return {visible: false,organizationName: }},watch: {value: {immediate: true,handler: handleValue}},methods: {openModal() {this.$refs.organizationModel.show(this.value, this.organizationName)},handleValue() {if (this.value) {this.$api.system.organization.get(this.value).then((res) {this.organizationName res.data.name})}},handleOK(id) {// 更新父组件绑定值this.$emit(change, id)}}
}
/scriptstyle scoped
/style
下面重点说下封装需要注意的点。
1.UI元素比较简单就一个文本框默认设置为禁用状态并且追加了一个按钮用于触发部门选择页面的弹出。 el-input v-modelorganizationName disabledel-button slotappend iconel-icon-s-grid clickopenModal //el-input在这基础上当然也可以进行功能扩展如再追加一个清空已选择的按钮视需求而定。 2.很重要的一点是设置model选项。因为默认情况下model使用名为 value 的 prop 和名为 input 的事件而我们封装的效果是选择控件将文本框禁用了事件应该使用chang而不是input所以需要做如下设置 model: {prop: value,event: change}3.为了组件的可配置性设置了部分prop属性如宽度、是否禁用等这样在使用的时候就能通过属性绑定的方式灵活配置了。 width: {type: Number,default: 500,required: false},value: {type: String,default: ,required: false},disabled: {type: Boolean,required: false,default: false}4.通过vue的watch机制监视value的变化该值变化后调用后端部门服务接口拿到部门名称后更新显示。 watch: {value: {immediate: true,handler: handleValue}},……handleValue() {if (this.value) {this.$api.system.organization.get(this.value).then((res) {this.organizationName res.data.name})}}5.选择项变化时通过change事件调用emit把最新的值传递给使用方这一步很关键。 change(value) {this.$emit(change, value)}接下来看下部门选择页面的实现完整源码如下
templatedivel-dialog title组织机构——单选 :visiblevisible width400px append-to-body closecloseel-input v-modelsearchValue placeholder请输入关键字过滤 stylemargin-bottom:10px /el-tag当前机构{{ selectedName }}/el-tagel-treereftree:datatreeDatanode-keyid:default-expanded-keysdefaultExpandedKeys:filter-node-methodfilterNodecurrent-changehandleTreeSelectChange/div slotfooter classdialog-footerel-button typeprimary clickconfirm确定/el-buttonel-button clickclose关闭/el-button/div/el-dialog/div
/templatescriptexport default {data() {return {visible: false,treeData: [],searchValue: ,defaultExpandedKeys: [],selectedValue: ,selectedName: }},watch: {searchValue(value) {this.$refs.tree.filter(value)}},methods: {show(id, name) {this.searchValue this.defaultExpandedKeys []this.selectedValue idthis.selectedName namethis.loadTree()this.visible true},loadTree() {this.$api.system.organization.tree().then(res {this.treeData res.data// 默认展开根节点this.defaultExpandedKeys.push(this.treeData[0].id)// 默认展开当前节点this.defaultExpandedKeys.push(this.selectedValue)})},close() {this.visible false},confirm() {this.$emit(ok, this.selectedValue)this.visible false},// 树节点选中改变handleTreeSelectChange(data) {this.selectedValue data.idthis.selectedName data.label},filterNode(value, data) {if (!value) return truereturn data.label.indexOf(value) ! -1}}
}/scriptstyle scoped
/style
具体功能包括了数据加载、默认展开、显示已选择值、搜索功能已经可以满足常见的需求了。
多选功能的实现
上面实现了单选功能其实多选功能实现也类似这里只放代码就不再展开介绍了
templatedivel-input v-modelorganizationName disabledel-button slotappend iconel-icon-s-grid clickopenModal //el-inputorganization-modal reforganizationModel okhandleOK //div
/templatescript
import OrganizationModal from ./organizationModal
export default {name: OrganizationMultipleSelect,components: {OrganizationModal},model: {prop: value,event: change},props: {value: {type: String,default: ,required: false},width: {type: Number,default: 500,required: false},disabled: {type: Boolean,required: false,default: false}},data() {return {visible: false,organizationName: }},watch: {value: {immediate: true,handler: handleValue}},methods: {openModal() {this.$refs.organizationModel.show(this.value)},handleValue() {if (this.value) {const idList this.value.split(,)this.$api.system.organization.getOrganization({ idList: idList }).then((res) {this.organizationName res.data.map(x x.name).join(,)})}},handleOK(value) {// 处理父组件绑定值this.$emit(change, value.join(,))}}
}
/scriptstyle scoped
/style
templatedivel-dialog title组织机构——多选 :visiblevisible width400px append-to-body closecloseel-input v-modelsearchValue placeholder请输入关键字过滤 stylemargin-bottom:10px /el-treereftree:datatreeDatanode-keyidshow-checkbox:default-expanded-keysdefaultExpandedKeys:filter-node-methodfilterNode:default-checked-keyscheckedNodesId/div slotfooter classdialog-footerel-button typeprimary clickconfirm确定/el-buttonel-button clickclose关闭/el-button/div/el-dialog/div
/templatescriptexport default {data() {return {visible: false,treeData: [],searchValue: ,defaultExpandedKeys: [],selectedValue: [],checkedNodesId: []}},watch: {searchValue(value) {this.$refs.tree.filter(value)}},methods: {show(idList) {this.searchValue this.defaultExpandedKeys []this.selectedValue idListthis.loadTree()this.visible true},loadTree() {this.$api.system.organization.tree().then(res {this.treeData res.data// 默认展开根节点this.defaultExpandedKeys.push(this.treeData[0].id)this.checkedNodesId []this.getLeafNodeChecked(this.treeData)this.$refs.tree.setCheckedKeys(this.checkedNodesId)})},close() {this.visible false},confirm() {this.$emit(ok, this.$refs.tree.getCheckedKeys())this.visible false},filterNode(value, data) {if (!value) return truereturn data.label.indexOf(value) ! -1},getLeafNodeChecked(node) {// 遍历树节点设置for (const treeNode of node) {// 如果节点有子节点那他的选中状态不被考虑继续往下找if (treeNode.children treeNode.children.length 0) {this.getLeafNodeChecked(treeNode.children)} else {// 是叶子节点如果是check状态就记录if (this.selectedValue.includes(treeNode.id)) {this.checkedNodesId.push(treeNode.id)}}}}}
}/scriptstyle scoped
/style
最后需要说一下的是通过组件化的思想可以将复杂功能拆分成一个个小的功能组件降低复杂性和提高复用度。