关于element:ElementPlus-的特点

ElementPlus 的特点ElementPlus 是由 Element 团队开发的一个全新的组件库,它齐全基于 Vue 3 的新个性和 API 进行开发,充分利用了 Vue 3 的性能劣势和组合式 API。ElementPlus 的组件不仅领有优良的设计格调和交互体验,而且反对多种主题定制和国际化,适应不同的场景和需要。ElementPlus 还提供了一套残缺的 Sketch 设计资源,不便设计师进行原型设计和视觉稿制作。 ElementPlus 的装置ElementPlus 反对通过 npm 或 yarn 装置,也反对通过 CDN 引入。装置 ElementPlus 前,须要先确保我的项目曾经装置了 Vue 3。以下是应用 npm 装置 ElementPlus 的命令: npm install element-plus --save ElementPlus 的应用ElementPlus 反对全局引入和按需引入两种形式。全局引入是指在我的项目的入口文件中一次性导入所有的组件和款式,这样能够不便地应用任何一个组件,但会减少我的项目的打包体积。按需引入是指在每个页面或组件中只导入须要应用的组件和款式,这样能够缩小我的项目的打包体积,但须要手动治理每个组件的依赖。 全局引入如果要应用全局引入的形式,能够在我的项目的入口文件(如 main.js)中增加以下代码: import { createApp } from 'vue'import App from './App.vue'import ElementPlus from 'element-plus'import 'element-plus/lib/theme-chalk/index.css'const app = createApp(App)app.use(ElementPlus)app.mount('#app')这样就能够在任何页面或组件中间接应用 ElementPlus 的组件了,例如: <template> <el-button type="primary">点击</el-button></template>按需引入如果要应用按需引入的形式,须要先装置一个插件 babel-plugin-component,它能够主动转换代码中的 import 语句,实现按需加载组件和款式。以下是装置 babel-plugin-component 的命令: ...

August 18, 2023 · 1 min · jiezi

关于element:黑马Vue3-ElementPlus-Pinia-小兔鲜电商项目2023版

download:黑马Vue3 + ElementPlus + Pinia 小兔鲜电商我的项目2023版ElementPlus:优雅高效的Vue组件库随着Vue.js在前端开发中的广泛应用,越来越多的UI组件库涌现进去。而其中一款备受瞩目的组件库就是ElementPlus。 作为一款基于Vue 3.0的组件库,ElementPlus不仅完满地继承了Element UI的所有个性,并且进行了深度降级和优化,提供了更加欠缺、稳固的组件库解决方案。那么,这个组件库到底有哪些值得咱们关注的特点和劣势呢?接下来,咱们将会对ElementPlus的特点和劣势进行具体介绍。 一、 代码精简ElementPlus采纳了新的Tree-shaking技术,在构建时只打包应用到的组件,减小了整个我的项目的体积,同时也进步了我的项目的加载速度。这种形式不仅让开发者能够自由选择须要的组件以及所需款式,还能够防止因为引入过多未应用的组件造成的节约。 二、TypeScript 反对借助TypeScript的类型查看性能,ElementPlus在编写代码时能够帮忙咱们防止一些非常规的谬误。例如,当咱们在调用某个组件时漏掉了必填参数,甚至连错传了参数类型,这时候TypeScript就能及时发现并提醒咱们批改代码。而且,ElementPlus的源代码都是应用TypeScript编写的,这意味着你能够更加轻松地进行二次开发,并且升高保护老本。 三、组件残缺ElementPlus提供了大量的组件和API反对,包含但不限于布局组件、表单组件、数据展现组件、导航组件等等。在保障与Vue 3.0的兼容性的根底上,ElementPlus还新增了一些罕用的组件,例如Cascader级联选择器等等,这使得咱们再也无需手动去寻找其余第三方插件来实现特定性能。 四、自定义主题ElementPlus提供了一个灵便的主题零碎。通过该零碎,你能够轻松地自定义我的项目中的主题,包含色彩、字体、边框等等,以适应我的项目需要,同时也能够缩小CSS冗余代码的应用,从而进步应用程序的性能。 五、易用性最初,ElementPlus领有良好的易用性,它提供了具体的文档和演示示例,让开发者更加方便快捷地学习和应用。同时,ElementPlus还有一个弱小的社区反对,你能够在社区中提出问题,或者和其他人分享你的应用教训。 总的来说,ElementPlus是一款优雅高效的Vue组件库,它让咱们更加轻松、便捷地开发Web应用程序,并且提供了良好的可维护性。如果你正在寻找一款Vue 3.0的UI组件库,无妨试试ElementPlus吧!

May 30, 2023 · 1 min · jiezi

关于element:从实际项目深入理解ElementPlus的导入方式

1.残缺导入本局部内容参考了element-plus官网和vue3.0-ts-admin我的项目。正如官网文档所言,如果你对打包后的文件大小不是很在乎,那么应用残缺的导入比拟不便。留神:残缺导入后,应用的时候间接用1.1 导入main.ts文件import { createApp } from 'vue'import ElementPlus from "element-plus";import "element-plus/lib/theme-chalk/index.css";import App from './App.vue' const app = createApp(App) app.use(ElementPlus)app.mount('#app')复制代码1.2 应用如下代码中用到了el-menu,间接应用即可:<template> <div> <el-menu :collapse="state.isSidebarNavCollapse" text-color="#eee" active-text-color="#4dbcff" :default-active="state.currentMenu" class="theme-bg" id="menu" :unique-opened="true" > <MENU :menuList="state.sidebarMenu"></MENU></el-menu></div></template>复制代码2.按需主动导入按需主动导入是举荐的导入形式。本节内容参考了vue3-music我的项目,您能够clone代码进行具体学习。留神:如果采纳主动按需导入的形式,则在应用组件的时候间接应用,不须要任何显示的导入语句。咱们看一下按需导入的几个关键环节:2.1 装置插件m install -D unplugin-vue-components unplugin-auto-import复制代码2.2 vite配置文件// vite.config.tsimport { defineConfig } from 'vite'import AutoImport from 'unplugin-auto-import/vite'import Components from 'unplugin-vue-components/vite'import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ // ... plugins: [ // ...AutoImport({ resolvers: [ElementPlusResolver()],}),Components({ resolvers: [ElementPlusResolver()],}),],})复制代码unplugin-vue-components/vite是负责组件主动导入的,你能够在不导入和注册组件的状况下在模板中应用想要用到的组件。unplugin-vue-components内置了风行UI组件库的resolvers(例如element-plus的),咱们能够看一下unplugin-vue-components中element-plus的resolver局部源码:// https://github.com/antfu/unpl...// resolveComponent办法中有一段代码:return { from: element-plus/lib/el-${partialName}, sideEffects: getSideEffectsLegacy(partialName, options),}// getSideEffectsLegacy:function getSideEffects(dirName: string, options: ElementPlusResolverOptionsResolved): SideEffectsInfo | undefined { const { importStyle, ssr } = options const themeFolder = 'element-plus/theme-chalk' const esComponentsFolder = 'element-plus/es/components' ...

June 10, 2022 · 1 min · jiezi

关于element:eltable两个表尾合计行联动同步滚动条代码

问题形容最近产品提出一个需要,说是做表格出现统计数据,不过数据源是来自两个中央的,所以须要做两个表格去出现数据,同时在表格最初统计数据。 效果图咱们先看一下效果图 思路获取对应的两个表格设置滚动条的dom,并通过Element.scrollLeft去设置滚动的间隔 官网文档:https://developer.mozilla.org... 滚动容器(审查元素即可得悉): 残缺代码本人演示的话,间接复制粘贴即可,代码中蕴含正文 <template> <div class="kkk"> <div class="myWrap"> <el-table ref="one" :data="tableBody" border :header-cell-style="{ background: '#FAFAFA', color: '#333333', fontWeight: 'bold', fontSize: '14px', }" show-summary > <el-table-column type="index" label="序号" width="60"> </el-table-column> <el-table-column prop="bookType" label="人物附属" width="100" ></el-table-column> <el-table-column prop="name" label="姓名" width="120"></el-table-column> <el-table-column prop="zhifubao" label="支付宝" width="160"> </el-table-column> <el-table-column prop="weixin" label="微信" width="160"> </el-table-column> <el-table-column prop="jingdong" label="京东" width="160"> </el-table-column> <el-table-column prop="yunshanfu" label="云闪付" width="160"> </el-table-column> <el-table-column prop="suning" label="苏宁" width="160"> </el-table-column> <el-table-column prop="lakala" label="拉卡拉" width="160"> </el-table-column> </el-table> <el-table ref="two" :data="tableBody2" border show-summary :show-header="false" > <el-table-column type="index" label="序号" width="60"> </el-table-column> <el-table-column prop="bookType" label="业务类型" width="100" ></el-table-column> <el-table-column prop="name" label="姓名" width="120"></el-table-column> <el-table-column prop="zhifubao" label="支付宝" width="160"> </el-table-column> <el-table-column prop="weixin" label="微信" width="160"> </el-table-column> <el-table-column prop="jingdong" label="京东" width="160"> </el-table-column> <el-table-column prop="yunshanfu" label="云闪付" width="160"> </el-table-column> <el-table-column prop="suning" label="苏宁" width="160"> </el-table-column> <el-table-column prop="lakala" label="拉卡拉" width="160"> </el-table-column> </el-table> </div> </div></template><script>// cnpm i lodash --saveimport _ from "lodash";export default { data() { return { tableBody: [ { bookType: "西游记", name: "孙悟空", zhifubao: 1, weixin: 2, jingdong: 3, yunshanfu: 4, suning: 5, lakala: 6, }, { bookType: "西游记", name: "猪八戒", zhifubao: 6, weixin: 5, jingdong: 4, yunshanfu: 3, suning: 2, lakala: 1, }, ], tableBody2: [ { bookType: "三国演义", name: "刘备", zhifubao: 2, weixin: 2, jingdong: 2, yunshanfu: 2, suning: 2, lakala: 2, }, { bookType: "三国演义", name: "猪八戒", zhifubao: 3, weixin: 3, jingdong: 3, yunshanfu: 3, suning: 3, lakala: 3, }, ], }; }, mounted() { // 1. 初始化的时候,设置横向滚动规定 this.setScrollRule(); }, methods: { setScrollRule() { let that = this; // 存一份this便于取用 this.one = this.$refs.one.bodyWrapper; // 获取带有滚动条的dom元素,留神饿了么UI的el-table的横向滚动条是设置在类名为 this.two = this.$refs.two.bodyWrapper; // class="el-table__body-wrapper is-scrolling-left" 这个dom上。审查元素可知 console.log("滚动条dom容器", this.one); // 2. 绑定滚动事件,顺带加上一个节流函数吧,也算是性能优化 this.one.addEventListener( "scroll", _.throttle( function () { that.fn1(); // 85毫秒触发一次吧 }, 85, { leading: true, //指定调用在节流开始前 trailing: false, //指定调用在节流完结后, } ) ); // 同上... this.two.addEventListener( "scroll", _.throttle( function () { that.fn2(); }, 85, { leading: true, trailing: false, } ) ); }, // 3. 通过Element.scrollLeft属性 能够读取或设置元素滚动条到元素右边的间隔 fn1() { console.log("滚动条一 挪动多少?", this.one.scrollLeft); this.two.scrollLeft = this.one.scrollLeft; /** * 加了节流函数当前,就会呈现当咱们滑动过快的时候,远小于定义节流工夫所触发的距离 * 就会呈现间隔不精确问题,所以再加一个延时定时器从新更正(更新一下地位) * */ setTimeout(() => { this.two.scrollLeft = this.one.scrollLeft; // api文档详情见mdn文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollLeft }, 120); }, // 同上... fn2() { console.log("滚动条二 挪动多少?", this.two.scrollLeft); this.one.scrollLeft = this.two.scrollLeft; setTimeout(() => { this.one.scrollLeft = this.two.scrollLeft; }, 120); }, }, beforeDestroy() { // 移除事件监听 this.one.removeEventListener("scroll", this.fn1); this.one.removeEventListener("scroll", this.fn2); },};</script>好忘性不如烂笔头,记录一下吧 ^_^

May 11, 2022 · 2 min · jiezi

关于element:VueElement

一、Vue 二、Element

April 12, 2022 · 1 min · jiezi

关于element:elementui-vloading和loading的区别

首先v-loading和:loading只在elementui的元素上应用失效,如:<div v-loading="true">有效。 区别:v-loading在表单或表格上应用,(可了解为页面加载):loading在按钮上应用

October 29, 2021 · 1 min · jiezi

关于element:记录Element表格动态表头及数据

实现形式1、取数据列表中第一条作为表头数据,再遍历删除不是表头的固定属性,后果赋值给一个空对象;2、把解决好的数据遍历 key 名 puah 进表头配置数组中,当时在写一个 key 名所对应的中文名办法返回中文名。 数据格式 /*表格数据*/const dataList = [ { name: "李小龙", age: 24, city: "深圳", gender: "男", education: "本科", hobby: "武术" }, { name: "黄飞鸿", age: 25, city: "深圳", gender: "男", education: "本科", hobby: "武术" }, { name: "陈真", age: 26, city: "深圳", gender: "男", education: "本科", hobby: "武术" }, { name: "霍元甲", age: 26, city: "深圳", gender: "男", education: "本科", hobby: "武术" },]/*表头配置*/const headConfig = { 名字: "name", 年龄: "age", 性别: "gender"}实现形式1:删除不是表头配置的属性 ...

June 12, 2021 · 1 min · jiezi

关于vue.js:eltablecolumn根据不同值显示不同颜色

<el-table-column prop="statusDesc" label="状态" width="90"> <template slot-scope="scope"> <div :style="{'color':scope.row.status==1? 'red':'#333'}"> {{scope.row.statusDesc}} </div> </template></el-table-column>

April 20, 2021 · 1 min · jiezi

关于element:element的下拉菜单Dropdown级联做法

官网提供的文档只提供了一层 看到正好有敌人问Dropdown如何做级联 当初把代码贴到上面三联四联做法统一 <el-dropdown trigger='click' :hide-on-click='false'> <span class="el-dropdown-link"> <el-link type="primary" style='margin-left:10px;'>{{title}}</el-link> <!-- <i class="el-icon-arrow-down el-icon--right"></i> --> </span> <el-dropdown-menu slot="dropdown"> <template v-for="item in menu"> <el-dropdown-item v-if='!item.childer'>{{item.title}}</el-dropdown-item> <el-dropdown-item v-else> <el-dropdown placement='right-start' > <span class="el-dropdown-link"> {{item.title}}<i class="el-icon-arrow-down el-icon--right"></i> </span> <el-dropdown-menu slot="dropdown"> <template v-for='items in item.childer'> <el-dropdown-item>{{items.title}}</el-dropdown-item> </template> </el-dropdown-menu> </el-dropdown> </el-dropdown-item> </template> </el-dropdown-menu> </el-dropdown>menu : [ { title : "分类", url : "", childer :[ { title : '分类1', url : '1111' }, { title : '分类2', url : '2222' }, { title : '分类3', url : '3333' } ] }, { title : "我的", url : "", childer :[ { title : '集体核心', url : 'b1111' }, { title : '我的订单', url : 'b2222' }, { title : '购物车', url : 'b3333' }, { title : '零钱', url : 'b4444' }, { title : '账户平安', url : 'b5555' } ] }, { title : '首页', url : 'https://segmentfault.com/' } ]

November 13, 2020 · 1 min · jiezi

关于element:element中MessageBox-弹框使用

在应用vue+element中,咱们时常会应用到element中的MessageBox 弹框,当初我分享一下我的教训1.开发环境vue+element 要实现上面的成果 我简略说我一下我的思路,首先是应用element的MessageBox 弹框,代码如下 <el-dialog title="增加账号" :visible.sync="centerDialogVisible" width="60%" center :before-close="handleClose" id="chen-show"><!-- 设置上部门的按钮 --> <div class="chen-xinz-botton"> <!-- 设置按钮1 --> <el-button type="info" round @click="showryxx">人员信息</el-button> <!-- 按钮1 完结啦 --> <!-- 设置按钮2 --> <el-button type="info" round @click="showjnxx">技能信息</el-button> <!-- 设置按钮2 完结啦 --> </div> <!-- 设置上局部的按钮完结啦 --> </el-dialog> </div> 在ruturn上面定义两个变量在methods中定义事件整体思路其实很简略,点击一个按钮呈现弹框,这段代码写在template中那个地位都能够,里边的布局跟失常的力其实没有区别。//留神在这块弹窗里边,其实有5块内容,父级就是弹框自身,在.el-dialog--center 中,有一个默认的margin-top是15vh,只能通过以下的形式去批改,留神,此时设置的高度是笼罩了弹框的高度 *这一块是弹框两头局部的高度,最好是应用最高权限 最初是设置底部的两个按钮,确认和勾销,默认在底部的两头地位,此时这个值设置为向右居中,示意:确认和勾销在左边的地位。 //整体思路:定义两个变量,管制点击人员信息和技能信息的模块的切换。而后设置弹框5块的款式,之后就是失常的布局了。//本期的教程到了这里就完结啦,是不是很简略。在这个畛域,不要抬头,不要认输。

July 22, 2020 · 1 min · jiezi

Elementui中ref和scope的使用

ref一般写在el-form中,以作为验证表单时使用<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="250px" class="demo-ruleForm" ></el-form-item>在调接口前作验证 this.$refs[formName].validate(valid => { if (valid) { console.log("11"); upDataPc(updateAddinfo).then(res => { this.resetForm(formName); this.$message.success("修改批次成功"); this.addBatchDialog = false; this.getBatchList(); });在el-table-column中可以添加template插槽通过scped.row加属性拿到data中的对应数据 <el-table-column prop="bzftype" label="保障房类型" align="center"> <template slot-scope="scope"> <span v-if="scope.row.bzftype == 0">公共租赁住房</span> <span v-if="scope.row.bzftype == 1">廉租住房</span> </template> </el-table-column> <el-table-column prop="stime" label="开始日期" align="center"></el-table-column> <el-table-column prop="etime" label="结束日期" align="center"></el-table-column> <el-table-column label="操作" align="center"> <template slot-scope="scope"> <el-button @click="updateBatch(scope.row.id)" type="text" size="small">编辑</el-button> <span v-if="scope.row.sfysy==0">|</span> <el-button v-if="scope.row.sfysy==0" @click="deleteBatch( scope.row.id)" type="text" size="small">删除</el-button> </template> </el-table-column>

September 20, 2019 · 1 min · jiezi

element-tree-获取当前节点和其父级节点的数据

需求:树形菜单点击之后需要形成面包屑,所以需要当前节点和其父级节点的数据。记录一下解决方法,如下。 <el-tree style="height:calc(100vh - 180px)" ref="tree" icon-class="el-icon-caret-right" :data="dataTree" :props="{label:'groupName',children:'groups'}" node-key="key" @node-click="TreeCk" > <!-- :expand-on-click-node="false" --> </el-tree>TreeCk(e){ //树节点点击 let tree:any = this.$refs.tree; this.treeKey = ''; //初始化 this.breadList = []; //初始化 if (!e.groups){ this.getTreeNode(tree.getNode(e.key)); this.treeKey = e.key; this.treeGroupType = e.groupType; this.getData(); } } getTreeNode(node){ //获取当前树节点和其父级节点 if (node) { if (node.label !== undefined) { this.breadList.unshift(node.label); //在数组头部添加元素 this.getTreeNode(node.parent); //递归 } } }this.breadList。可以得到当前节点和其父级的lable数组集合。

July 5, 2019 · 1 min · jiezi

elementui设置下拉选择切换必填和非必填

➢ 需求默认都是必选 下拉选择的时候 选择必填,活动名称为必填,需要校验和显示* 选择非必填,活动名称不做校验,隐藏* ➢ 初始校验规则经测试,网上其他的方式都没有实现需求,动态切换rules中的required没有作用 因为按照以下的写法的话,element-ui在组件初始化后校验规则就定型了,切换也没用 rules: { name: [ { required: true, message: "请输入名称", trigger: "blur" } ], region: [ { required: true, message: "请选择类型", trigger: "blur" } ]}➢ 解决方案第一步: 去除rules中需要动态校验的字段规则 去除name rules: { region: [ { required: true, message: "请选择类型", trigger: "blur" } ]}第二步: 在字段为name的form-item上,添加required属性 下面代码isHaveTo为新字段,根据下拉框选择的值来决定是为true还是false <el-form-item label="活动名称" prop="name" :required="isHaveTo"> <el-input v-model="ruleForm.name"></el-input></el-form-item>第三步: 计算属性,新增字段isHaveTo 下拉选择框非必须是为1,其他都是必填,包括默认 computed: { isHaveTo: function() { return this.ruleForm.region === `0`; }},效果如图: ...

June 16, 2019 · 2 min · jiezi

解决<el-checkbox-group> 数据与UI更新不同步的坑

Bug情景再现<template> <div class=“store-box”> <div v-for="(day, d) in dayList" class=“checkItem-box”> <span>{{day}}</span> <el-checkbox-group v-model=“storeItem.arrange[d]"> <el-checkbox :label=“1”>上午</el-checkbox> <el-checkbox :label=“2”>下午</el-checkbox> <el-checkbox :label=“3”>晚上</el-checkbox> </el-checkbox-group> </div> </div></template><script>export default{ data(){ dayList: [‘周一’, ‘周二’, ‘周三’, ‘周四’, ‘周五’, ‘周六’, ‘周日’], storeItem: { arrange: [] }, }, mounted(){ const week = [ [1,2], //周一的选择情况 [1], //周二的选择情况 [], //周三的选择情况 [2,3], //周四的选择情况 [2,1], [1,2,3], [3] ] //为checkbox-group 赋值 this.storeItem.arrange = week; }}</script>得到这样的结果:但是当我们点击其它选择框的时候,没有反应。尝试解决最先想到的原因应该是vue没有对arrange的改变监控到, 于是解决办法是使用 vue. setthis.$set(this.storeItem, ‘arrange’, week)这样修改后确实也起作用了。⭐ 注意:这里使用 vue.set 起作用根本是,瞎猫碰上死耗子,<el-checkbox-group>不能相响应的原因根本不是这个而且我们仔细读 Vue 的官方文档Vue.set( target, key, value )作用是向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = ‘hi’)这里我们根本没有添加 arrange属性,而只是去改变了arrange 属性的值,vue按理说应该是能够检测到的。后面的实验也认证了我的观点。实验:让我们再把表单复杂一些。注:部分代码已经省略<template> <div v-for="(store, st) in serviceStoreList” class=“store-box”> <label>{{store.name}}</label> <div v-for="(day, d) in dayList" class=“checkItem-box”> <span>{{day}}</span> <el-checkbox-group v-model=“store.arrange[d]"> <el-checkbox :label=“1”>上午</el-checkbox> <el-checkbox :label=“2”>下午</el-checkbox> <el-checkbox :label=“3”>晚上</el-checkbox> </el-checkbox-group> </div> </div></template><script>export default{ data(){ dayList: [‘周一’, ‘周二’, ‘周三’, ‘周四’, ‘周五’, ‘周六’, ‘周日’], serviceStoreList: [ name: ‘’, arrange: [], ], }, mounted(){ const week = [ [1,2], //周一的选择情况 [1], //周二的选择情况 [], //周三的选择情况 [2,3], //周四的选择情况 [2,1], [1,2,3], [3] ] //为checkbox-group 赋值 for (let i=0; i<3; i++){ this.serviceStoreList[i].name = 这是 ${i} 号; this.serviceStoreList[i].arrange = week; } }}</script>这样写了之后, checkBox 还是: 能够展示勾选,但是点击其它选择框没有任何反应。于是我们将 mounted 里面的代码改成const week = [ [1,2], //周一的选择情况 [1], //周二的选择情况 [], //周三的选择情况 [2,3], //周四的选择情况 [2,1], [1,2,3], [3] ] //为checkbox-group 赋值 const _obj = {}; const self = this; for (let i=0; i<3; i++){ _obj = {}; _obj.name = 这是 ${i} 号; _obj.arrange = week; self.$set(self.serviceStoreList, i, _obj) // 或 self.serviceStoreList.splice(i, 1, _obj) }还是不会起任何作用,点击其它选择框依然是点不动,不能进行交互。这里我反复实验了几次,发现了一个特殊的现象。就是当你去点击其它选择框的时候, vue-devtool 里面显示的数据其实是已经改变了的。而且,当你点击了一个checkBox, 然后去填写另外的一个表单项,比如去选择下拉,或者填写其它<el-input> 的时候,checkBox 立刻就改变了。相当于它之前的v-model 的数据其实是正常的,只是视图卡住了。最后的解决办法vue 的数据没有问题,那么肯定是 element 埋下的坑。个人认为 <el-checkbox-group> 与 <el-check> 的数据同步有些问题。这样写就好了<el-checkbox-group v-model=“store.arrange[d]"> <el-checkbox :label=“1” :checked=“checked” @change=“checked=!checked”>上午</el-checkbox> <el-checkbox :label=“2” :checked=“checked” @change=“checked=!checked”>下午</el-checkbox> <el-checkbox :label=“3” :checked=“checked” @change=“checked=!checked”>晚上</el-checkbox></el-checkbox-group>//data 里面增加一个字段data (){ checked:false , //这个 checked没有任何作用,只是为了绕开elment 的这个坑}这样我们不用设置 vue.set(因为vue 其实重头到尾都能够监视到数据的改变)const week = [ [1,2], //周一的选择情况 [1], //周二的选择情况 [], //周三的选择情况 [2,3], //周四的选择情况 [2,1], [1,2,3], [3] ]//为checkbox-group 赋值const _obj = {};const _store = [];for (let i=0; i<3; i++){ _obj = {}; _obj.name = 这是 ${i} 号; _obj.arrange = week; _store.push(_obj);}this.checked = false; //需将checked 设置为false,不然选择框可能会出现全部选中的情况this.serviceStoreList = _store; //直接设置,checkbox也能正常交互心得vue 只是 无法探测普通的新增属性 ,但是 Vue 能够探测到data 里面已经注册过的对象的改变,比如重新给这个对象赋值,或改变它已经注册过的属性的值(非给它新增其它属性)。无论这个对象的数据结构有多么的复杂。少用 vue.set, 多在 <el-check> 上面显示指明 @change,让它状态改变。再每次修改 <el-checkbox-group> 的 v-model 的值的时候,先将 checked 设置为 false1. this.checked = false2. this.serviceStoreList = _store ...

March 20, 2019 · 2 min · jiezi

一个完整的增删改查模块(以我们的项目‘危化品库管理’模块为例)

父组件列表页面<!– 危化品库管理 –><template> <div> <!– 添加 –> <div class=“right add” @click=“add”> </div> <!– 搜索 –> <div class=“searchPart”> <div class=“search_row”> <el-form :inline=“true” :model=“form” :rules=“rules” ref=“elform”> <el-form-item label=“危化品名称:” prop=“dangerousname”> <div><input type=“text” @keyup.enter=“handleFilter” v-model.trim=“listQuery.dangerousname” class=“search_input”></div> </el-form-item> <el-form-item label=“CAS号:” prop=“cascode”> <div><input type=“text” @keyup.enter=“handleFilter” v-model.trim=“listQuery.cascode” class=“search_input”></div> </el-form-item> <el-form-item label=“危化品类型:” prop=“dicDangeroustype”> <el-select placeholder=“请选择危化品类型” size=“mini” v-model=“listQuery.dicDangeroustype” @change=“handleFilter”> <el-option v-for=“item in localWord.category” :key=“item.code” :label=“item.codename” :value=“item.code”> </el-option> </el-select> </el-form-item> <el-form-item label=“别名:” prop=“othername”> <div><input type=“text” @keyup.enter=“handleFilter” v-model.trim=“listQuery.othername” class=“search_input”></div> </el-form-item> <el-form-item> <el-button size=“mini” type=“primary” icon=“el-icon-search” @click=“handleFilter”>查询</el-button> <el-button size=“mini” type=“primary” icon=“el-icon-download” @click=“exportData”>导出</el-button> </el-form-item> </el-form> </div> </div> <!– table列表展示 –> <el-row> <el-table :data=“girdData” highlight-current-row :max-height=“gridTableMaxHeight” :header-cell-style="{background:‘rgb(212, 232, 255)’,color:‘rgba(0, 0, 0, 0.85)’}" border style=“width: 100%” @selection-change=“handleSelectionChange”> <el-table-column type=“selection” width=“55”> </el-table-column> <el-table-column property=“serialNumber” label=“序号” min-width=“35” align=“center”> <template slot-scope=“scope”> <span>{{scope.$index+(listQuery.page - 1) * listQuery.rows + 1}}</span> </template> </el-table-column> <el-table-column property=“dangerousname” label=“危化品名称” min-width=“140”></el-table-column> <el-table-column sortable label=“CAS号” property=“cascode” min-width=“120”></el-table-column> <el-table-column label=“别名” property=“othername” min-width=“120”></el-table-column> <el-table-column label=“危化品类型” property=“dicDangeroustypeStr” min-width=“140”></el-table-column> <el-table-column label=“英文名称” property=“englishname” min-width=“120”></el-table-column> <el-table-column label=“分子式” property=“molecularFormula” min-width=“120”></el-table-column> <el-table-column label=“熔点” property=“meltingPoint” min-width=“120”></el-table-column> <el-table-column label=“密度” property=“theDensityOf” min-width=“120”></el-table-column> <el-table-column label=“溶解性” property=“solubility” min-width=“120”></el-table-column> <el-table-column label=“操作” width=“140” align=“center” fixed=“right”> <template slot-scope=“scope”> <el-button type=“text” size=“small” @click=“editCheckBtn(scope.$index, scope.row, ’edit’)"><span class=“icons edit_icon”></span></el-button> <el-button type=“text” size=“small” @click=“editCheckBtn(scope.$index, scope.row, ‘check’)"><span class=“icons check_icon”></span></el-button> <el-button type=“text” size=“small” @click=“del(scope.$index, scope.row)"><span class=“icons delete_icon”></span></el-button> </template> </el-table-column> </el-table> </el-row> <!– 分页 –> <el-row type=“flex” justify=“end” style=“padding:20px” class=“page”> <el-pagination v-show=“total>0” background @size-change=“handleSizeChange” @current-change=“handleCurrentChange” :current-page=“listQuery.page” :page-sizes="[10, 20, 30]” :page-size=“listQuery.rows” layout=“total, sizes, prev, pager, next, jumper” :total=“total”> </el-pagination> </el-row> <router-view></router-view> </div></template><script> import download from ‘js-file-download’ import moment from ‘moment’ import DChemStoreManagementAPI from “@/api/DChemStoreManagementAPI”; export default { data() { return { // 查询条件 listQuery: { page: 1, //当前第几页 rows: 10, //每页显示多少条 pkEntid: “1”, dangerousname: “”, cascode: “”, dicDangeroustype: “”, othername: "” }, total: null, //共多少条数据 girdData: [], // 字典查询 localWord: {}, multipleSelection: [], multipleSelectionIdArr: [], gridTableMaxHeight: document.body.clientHeight - 310, rules: {}, form: { dangerousname: “”, cascode: “”, othername: “”, dicDangeroustype: “”, dicDangeroustypeStr: “”, toxicity: “”, environmentalparameter: “”, englishname: “”, molecularFormula: “”, molecularWeight: “”, meltingPoint: “”, theDensityOf: “”, solubility: “”, purpose: “”, dangerousinfo: “”, testmethod: “”, eliminationmethod: "” } }; }, watch: { “listQuery.dicDangeroustypeStr”(v) { } }, methods: { handleSizeChange(val) { this.listQuery.rows = val; this.initTable(); }, handleCurrentChange(val) { this.listQuery.page = val; this.initTable(); }, handleFilter() { this.listQuery.page = 1; this.initTable(); }, initTable() { DChemStoreManagementAPI.getList(this.listQuery).then(data => { this.total = data.data.total; this.girdData = data.data.rows; this.multipleSelectionIdArr = data.data.rows.map(item=>{ return item.pkDangerid }) }); }, exportData () { DChemStoreManagementAPI.exportData(this.listQuery).then((data)=>{ if(this.listQuery) { download(data, 危化品名称${moment(new Date().getTime()).format('YYYYMMDDHHmmss')}.xls) this.$message({ type: “success”, message: “导出成功!” }); } }) }, handleSelectionChange(row) { this.multipleSelection = row.map(item=>{ return item.pkDangerid }) }, add() { this.$router.push({ name: “dchemstoremanagementform”, query: { status: “add” } }); }, del(index, row) { this.$confirm(“此操作将永久删除该选项, 是否继续?”, “提示”, { confirmButtonText: “确定”, cancelButtonText: “取消”, type: “warning” }) .then(() => { DChemStoreManagementAPI.del(row.pkDangerid).then(()=>{ this.initTable(); }); this.$message({ type: “success”, message: “删除成功!” }); }) .catch(function(response) {}); }, editCheckBtn(index, row, typeBtn) { this.$router.push({ name: “dchemstoremanagementform”, query: { status: typeBtn, pkDangerid: row.pkDangerid } }); } }, created(){ DChemStoreManagementAPI.getSelect().then(data => { this.localWord = data; this.localWord.category.unshift({ code: “”, codeenname: “all”, codename: “全部” }); }); }, mounted() { this.initTable(); let that = this; window.onresize = () => { return (() => { that.gridTableMaxHeight = document.body.clientHeight - 310; })(); }; } }; </script> 子组件 增改查页面<template><div> <el-dialog :title="危化品库管理 - ${formTitle}" :visible=“true” :lock-scrol=“true” width=“780px” @close=“closeDlg” center> <el-row :gutter=“24”> <el-col :span=“24”> <el-form status-icon :model=“form” :inline=“true” :rules=“rules” ref=“elform” label-width=“140px”> <el-row :gutter=“0”> <el-col :span=“12”> <el-form-item label=“危化品名称:” prop=“dangerousname”> <el-input size=“small” v-model=“form.dangerousname” placeholder=“请输入危化品名称” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.dangerousname}}</span> </el-form-item> </el-col> <el-col :span=“12”> <el-form-item label=“CAS号:” prop=“cascode”> <el-input size=“small” v-model=“form.cascode” placeholder=“请输入CAS号” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.cascode}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“0”> <el-col :span=“12”> <el-form-item label=“别名:” prop=“othername”> <el-input size=“small” v-model=“form.othername” placeholder=“请输入别名” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.othername}}</span> </el-form-item> </el-col> <el-col :span=“12”> <el-form-item label=“危化品类型:” prop=“dicDangeroustype”> <el-select placeholder=“请选择危化品类型” size=“small” v-model=“form.dicDangeroustype” v-if=“status==‘add’|| status==‘edit’"> <el-option v-for=“item in localWord.category” :key=“item.code” :label=“item.codename” :value=“item.pkCodenum”> </el-option> </el-select> <span v-else>{{form.dicDangeroustypeStr}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“0”> <el-col :span=“12”> <el-form-item label=“毒性:” prop=“toxicity”> <el-input size=“small” v-model=“form.toxicity” placeholder=“请输入毒性” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.toxicity}}</span> </el-form-item> </el-col> <el-col :span=“12”> <el-form-item label=“环境参数:” prop=“environmentalparameter”> <el-input size=“small” v-model=“form.environmentalparameter” placeholder=“请输入环境参数” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.environmentalparameter}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“0”> <el-col :span=“12”> <el-form-item label=“英文名称:” prop=“englishname”> <el-input size=“small” v-model=“form.englishname” placeholder=“请输入英文名称” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.englishname}}</span> </el-form-item> </el-col> <el-col :span=“12”> <el-form-item label=“分子式:” prop=“molecularFormula”> <el-input size=“small” v-model=“form.molecularFormula” placeholder=“请输入分子式” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.molecularFormula}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“0”> <el-col :span=“12”> <el-form-item label=“分子量:” prop=“molecularWeight”> <el-input size=“small” v-model=“form.molecularWeight” placeholder=“请输入分子量” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.molecularWeight}}</span> </el-form-item> </el-col> <el-col :span=“12”> <el-form-item label=“熔点:” prop=“meltingPoint”> <el-input size=“small” v-model=“form.meltingPoint” placeholder=“请输入熔点” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.meltingPoint}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“0”> <el-col :span=“12”> <el-form-item label=“密度:” prop=“theDensityOf”> <el-input size=“small” v-model=“form.theDensityOf” placeholder=“请输入密度” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.theDensityOf}}</span> </el-form-item> </el-col> <el-col :span=“12”> <el-form-item label=“溶解性:” prop=“solubility”> <el-input size=“small” v-model=“form.solubility” placeholder=“请输入溶解性” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.solubility}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“24”> <el-col :span=“24”> <el-form-item label=“用途:” prop=“purpose”> <el-input size=“small” type=“textarea” class=“special-530” :autosize=”{ minRows: 3}” v-model=“form.purpose” placeholder=“请输入用途信息” v-if=“status==‘add’|| status==‘edit’"></el-input> <el-input size=“small” type=“textarea” resize=“none” class=“readonly special-530” :autosize=”{ minRows: 1}” v-model=“form.purpose” placeholder=“请输入用途信息” v-else readonly></el-input> <!– <span v-else>{{form.purpose}}</span> –> </el-form-item> </el-col> </el-row> <el-row :gutter=“24”> <el-col :span=“24”> <el-form-item label=“环境危害:” prop=“dangerousinfo”> <el-input size=“small” type=“textarea” class=“special-530” :autosize=”{ minRows: 3}” v-model=“form.dangerousinfo” placeholder=“请输入环境危害信息” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.dangerousinfo}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“24”> <el-col :span=“24”> <el-form-item label=“检测方法:” prop=“testmethod”> <el-input size=“small” type=“textarea” class=“special-530” :autosize=”{ minRows: 3}” v-model=“form.testmethod” placeholder=“请输入检测方法信息” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.testmethod}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“24”> <el-col :span=“24”> <el-form-item label=“控制消除方法:” prop=“eliminationmethod”> <el-input size=“small” type=“textarea” class=“special-530” :autosize=”{ minRows: 3}” v-model=“form.eliminationmethod” placeholder=“请输入控制消除方法信息” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.eliminationmethod}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“24”> <el-col :span=“24”> <el-form-item label=“危险特性:” prop=“characteristic”> <el-input size=“small” type=“textarea” class=“special-530” :autosize=”{ minRows: 3}” v-model=“form.characteristic” placeholder=“请输入危险特性信息” v-if=“status==‘add’|| status==‘edit’"></el-input> <span v-else>{{form.characteristic}}</span> </el-form-item> </el-col> </el-row> <el-row :gutter=“24” class=“text-center”> <el-col :span=“24”> <el-form-item v-if=“status==‘add’|| status==‘edit’"> <el-button type=“primary” size=“small” @click=“onSubmit”>保存</el-button> <el-button @click=“closeDlg” size=“small”>取消</el-button> </el-form-item> <el-form-item v-else> <el-button type=“primary” size=“small” @click=“closeDlg”>关闭</el-button> </el-form-item> </el-col> </el-row> </el-form> </el-col> </el-row> </el-dialog> </div></template><script>import { mapGetters } from “vuex”;import { validatorRules } from “@/comman/validator”;import DChemStoreManagementAPI from “@/api/DChemStoreManagementAPI”;export default { data() { return { formTitle: ‘添加’, status: this.$route.query.status, localWord: {}, form: { pkEntid: “”, dangerousname: “”, cascode: “”, othername: “”, dicDangeroustype: “”, dicDangeroustypeStr: “”, toxicity: “”, environmentalparameter: “”, englishname: “”, molecularFormula: “”, molecularWeight: “”, meltingPoint: “”, theDensityOf: “”, solubility: “”, purpose: “”, dangerousinfo: “”, testmethod: “”, eliminationmethod: "” }, rules: { dangerousname: [ { required: true, message: “请输入危化品名称”, trigger: “blur” }, validatorRules.shortRules ], cascode: [ { required: true, message: “请输入CAS号”, trigger: “blur” }, validatorRules.shortRules ], othername: [ { required: true, message: “请输入别名”, trigger: “blur” }, validatorRules.shortRules ], dicDangeroustype: [ { required: true, message: “请输入危化品类型”, trigger: “blur” } ], toxicity: [ { required: true, message: “请输入毒性”, trigger: “blur” }, validatorRules.shortRules ], environmentalparameter: [ { required: true, message: “请输入环境参数”, trigger: “blur” }, validatorRules.shortRules ], englishname: [ { required: true, message: “请输入英文名称”, trigger: “blur” }, validatorRules.shortRules ], molecularFormula: [ { required: true, message: “请输入分子式”, trigger: “blur” }, validatorRules.shortRules ], molecularWeight: [ { required: true, message: “请输入分子量”, trigger: “blur” }, validatorRules.shortRules ], meltingPoint: [ { required: true, message: “请输入熔点”, trigger: “blur” }, validatorRules.shortRules ], theDensityOf: [ { required: true, message: “请输入密度”, trigger: “blur” }, validatorRules.shortRules ], solubility: [ { required: true, message: “请输入溶解性”, trigger: “blur” }, { min: 0, max: 30, message: ‘长度在 0 到 30 个字符’, trigger: ‘blur’ } // validatorRules.shortRules ], purpose: [ { required: true, message: “请输入用途”, trigger: “blur” }, { min: 0, max: 200, message: ‘长度在 0 到 200 个字符’, trigger: ‘blur’ } ], dangerousinfo: [ { required: true, message: “请输入环境危害”, trigger: “blur” }, { min: 0, max: 200, message: ‘长度在 0 到 200 个字符’, trigger: ‘blur’ } ], testmethod: [ { required: true, message: “请输入检测方法”, trigger: “blur” }, { min: 0, max: 200, message: ‘长度在 0 到 200 个字符’, trigger: ‘blur’ } ], eliminationmethod: [ { required: true, message: “请输入控制消除方法”, trigger: “blur” }, { min: 0, max: 200, message: ‘长度在 0 到 200 个字符’, trigger: ‘blur’ } ], characteristic: [ { required: true, message: “请输入危险特性”, trigger: “blur” }, { min: 0, max: 200, message: ‘长度在 0 到 200 个字符’, trigger: ‘blur’ } ] } }; }, beforeRouteEnter(to, from, next) { DChemStoreManagementAPI.getSelect().then(data => { next(vm => { console.log(data); vm.localWord = data; }); }); }, methods: { onSubmit() { this.$refs[“elform”].validate(valid => { if (valid) { DChemStoreManagementAPI.add(this.form).then(data => { this.$parent.initTable(); this.$router.back(); }); } else { return false; } }); }, closeDlg() { this.$router.back(); } }, mounted() { var that = this; if(this.status == ’edit’) { this.formTitle = ‘修改’ } else if(this.status == ‘check’) { this.formTitle = ‘详情’ } if (this.$route.query.pkDangerid) { DChemStoreManagementAPI.getById(this.$route.query.pkDangerid).then( obj => { that.form = obj.data; // that.form.dicDangeroustype = obj.data.dicDangeroustype.toString(); } ); } }};</script>APIimport axios from “axios”;import qs from “qs”;let DChemStoreManagementAPI = { getList(params) { return axios.get(”…”, { params }); }, add(params){ return axios({ method: “post”, url: “…/save”, data: qs.stringify(params) }) }, getSelect(params) { return axios(”…”, { params }) }, getById(id) { return axios.get(”…?id="+ id, { }); }, del(id) { return axios.delete("…?id=" + id, { }); }, exportData(params) { return axios.get("…", { responseType: ‘arraybuffer’, params }); }, deleteFile(params) { return axios.delete("…", { params: { filePath: params.filepath } }); }};export default DChemStoreManagementAPI;以上便是模块的增删改查内容,至于上传模块,没有过多的解释,上传用的是封装过的组件,代码太多,不便复制,不过有下载功能^_^,这也是一点小小的总结。 ...

December 14, 2018 · 7 min · jiezi