学一个新的东西
1是什么 2解决什么问题 3怎么使用 4原理
init create destroy
一个页面或者组件 入口函数 init()这样方便整体刷新 不需要每个子组件都watch create中创建 destroy中销毁
写功能注意事项
1、布局layout row col card
<el-container direction="vertical" style="background: #f0f2f5;height: 100%;">
<!-- 头部菜单 -->
<Header :headerActiveMenu="headerActiveMenu"></Header>
<!-- 头部以下的整体 -->
<el-container style="height: calc(100% - 50px);"> <!-- 头部以下的整体高度固定,头部就可以固定.不会因下文高度过长把头部挤上去 -->
<!-- 左侧菜单 -->
<LeftSide :leftSideMenus="leftSideMenus" :activeMenu="activeMenuDetail.path"></LeftSide>
<!-- 中间部分 -->
<el-container direction="vertical" style="height: 100%;">
<!-- 展示主要信息部分 -->
<el-main style="padding:0;height: 100%; overflow: hidden;"> <!-- 固定主域高度,内部高度过长时,主域出现滚动条 -->
<Tabs :activeMenu="activeMenuDetail.path">
<router-view></router-view>
</Tabs>
</el-main>
<!-- 底部信息 -->
<el-footer style="height: 30px;line-height: 30px;padding: 0 50px;background-color: rgba(0,0,0,.05);color: rgba(0,0,0,.65);font-size: 14px;">Copyright © 2022 连连(杭州)信息技术公司 LianLian</el-footer>
</el-container>
</el-container>
</el-container>
// 嵌套路由 Layout被渲染到最外层APP.vue中的<router-view>中,View 会被渲染到Layout的<router-view>内部, Database会被渲染到View的<router-view>内部
const metaDataRoute = {
name: '元数据',
path: '/metaData',
component: Layout,
redirect: '/dataSource/database',
children: [
{
name: '业务源管理',
path: '/dataSource',
component: View,
icon: 'Coin',
redirect: '/dataSource/database',
children: [
{
name: '业务源数据库',
path: '/dataSource/database',
component: Database,
},
{
name: '业务元数据管理',
path: '/dataSource/metaData',
component: MetaData,
},
{
name: '库分析',
path: '/dataSource/databaseAnalysis',
component: DatabaseAnalysis,
hidden: true,
}
]
}]
2、form表单要校验,重置(form上写ref、rule、form-item加上prop),table一般留出一列不写宽度自适应,编辑table表的某一行把这一行的info {...info}一下传递给子组件,防止子组件resetFields()改变table中的这行数据
是否必填,填写格式、填写错误提示,
删除要二次确认
dialog中,从父元素传递过来的dialogVisible要const visible = computed(() => props.dialogVisible);再在中使用,因为v-model会改变他的值,props中的数据不可以改变。dialog在页面渲染的时候就挂载到页面里,以后每次通过visible更新显隐会触发onUpdated
如果需要强制刷新dialog可以在使用dialog组件的地方中v-if控制dialog的出现与否
3、http 请求要有loading ,但是请求一些select中的列表不需要loading
返回信息要有成功或这错误提示以及后续刷新,
如果是获取列表只需有错误提示正常无需提示,提示可关闭
如果是提交操作提交成功错误都有提示,错误的时候要把loading关掉
操作成功刷新列表 pageSize pageNo停留在当前页,删除会可能最后一页没了要注意处理一下 query保持原样
const defaultPagination = {
pageNum: 1,
limit: 10,
total: 0,
}
**
* 查询停车记录列表
*/
const getRecordsGroupList = (pagination = defaultPagination) => {
state.loading = true;
getRecordsGroup({
pageNum: pagination.pageNum,
limit: pagination.limit,
...state.queryForm
})
.then((res) => {
state.loading = false;
state.recordList = res.records
state.pagination = {
pageNum: pagination.pageNum,
limit: pagination.limit,
total: res.count
}
})
}
// 改变每页条数
const handleSizeChange = (val: number) => {
getRecordsGroupList({ ...state.pagination, pageNum: 1 , limit: val})
}
// 翻页
const handleCurrentChange = (val: number) => {
getRecordsGroupList({ ...state.pagination, pageNum: val })
}
图片要压缩 http请求压缩与解压缩
4、子组件中的数据如果和父组件无关可以子组件单独写,如果和父组件相关从父组件中传递过来。 虽然说数据向上提升,父组件逻辑组件 子组件展示组件,也要看实际情况
5、按道理说只在这个页面使用的组件写在这个页面的components下,其他页面也会用的组件写在公共的components下,但后裔项目有些特殊
6、看别人的代码 熟悉每个函数大致的意思后,可以通过打断点把各种情况的函数流程串起来
命名
熟练使用 create增 delete删 update改 查search select
详情detail getOrderDetail 列表list
查询search searchProduct(No)
assemble组装 如assembleOrder generate生成 如generateOrderNo
handleNodeClick() 或 nodeClickHandler
desc 降序 asc升序
synchronization sync 同步 默认代码同步 async异步
status 状态 计算机常用
后端如果让同时传选中的id和name,可以考虑name如果改变了,以前存储的name就会有问题,所以让他们用id去查name比较好
element UI源码阅读
(1)、枚举 如果在多个地方使用可以写成枚举常量,如果只用一次可以不写
// type
<template v-if="type!== 'textarea'">
<input
ref="input"
@change="changeHandle"/>
</template>
<template v-else>
<textarea
ref="textarea"
@change="changeHandle"></textarea>
</template>
(2)、边界条件判断,是否为空判断
computed: {
nativeInputValue() {
return this.value === undefined || this.value === null ? '' : String(this.value);
}
},
methods: {
setNativeInputValue() {
const input = this.getInput();
if (!input) return;
if (input.value === this.nativeInputValue) return;
input.value = this.nativeInputValue;
},
}
样式class命名
// panel-group-->card-panel-->card-panel-icon-wrapper-->card-panel-icon
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
New Visits
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
<el-row>
动作函数要以动词开头
function sendEmailToUser(user) {
}
npm 命令行工具开发
vite不能用require
webpack里可以用 vite不能用require 用在函数里写new URL()加载资源
更改elementui样式
>>>父元素 里面写子元素 注意css选择器 加载elementui按需加载引入样式css或scss文件 table min-width dropdown.show()展示drop的下拉菜单
prevent auto
prevent auto 保持原来的事件 none去掉原来的事件可以操作地图 如果操作不到地图看一下是否上面有层遮挡
vue-router
子组件按路由加载 子组件会反复mount 父组件只在最初mount一次 其他时间要改动需要 watch route或其他
flex
flex 1可以让这个子元素大小随容器大小自适应 平均排布在父容器里
skew
矩形skew变平行四边形
背景 图片 阴影
图片做背景 可以设置位置大小 shadow 阴影 内阴影 text-shandow 文字发光
nodejs node-sass pnpm 版本对应
nodejs版本号和node-sass要对应 14-4 16-5 node14可以用pnpm7 pnpm8不行
布局
大屏左右两侧 前几个模块flex 不为1 有固定高度,最后一个flex可以为1 height:100% 外层oveflow hidden 内层overflow scroll
flex: 1可以使元素均匀的排列 不够长可以底部加长 否则会挤在一起
如果flex:1的元素被撑大,写min-height:0,就不会被撑大了,里面的滚动
flex: 1; 且min-width: 0或min-height: 0 超出后overflow auto 自然会滚动 其他不写flex:1的都自动不变
一行其中一个写flex:1自适应 其他写固定宽度flex 0 0 4.12rem 如果flex 0 0 4.12rem不管用 可以用calc(100% - xxrem)
一个模块中有上下两块,设置父组件display flex, 子组件都不设置高度,可以上个组件占用自动适应,下个组件铺满
如果设置了padding后里面超出的内容不好处理,可以改成设置margin
如果上面的模块有列表,且高度不固定,可以设置最大高度50% 让他在下面元素很矮时不要太长
文本行不设高度 和别的间隙用margin
明眼看出来是一个框中间有内容的时候 可以设框高度 内部居中
margin为正负 稍微偏移
button width xxrem min-width 38px 按钮宽度大的时候自动缩放 小于38px时不缩放 里面文字不会被挤换行
注意数字英文的换行 word-break: break-all
可以不设高度,高度自动撑起来
class选择器
p:first-child 第一个p
p>:first-child p内的第一个子元素
.ppp.xxx class=“ppp xxxx”
组件层级按照逻辑层级,组建的间隙处理
一个组件最外层不写margin
可以在父组件内写padding
有的图片带阴影 切下来比在图上量的大 自己看着设置大小
Overflow-y auto 滚动条出来时 会导致宽度有问题
http请求 设置了超时时间timeout http请求超时结果返回空
failed to load response data: no data found for resource with given identifier failed to load response data: request content was evicted from inspector cache
大屏 不接ws 每隔1-2分钟刷新大屏数据
同一个域名下所有标签页都关闭的时候session才会清除
sessionStorage www.baidu.com/ 下有 sessionStorage.setItem('test', '1234556') 关闭这个tab页再打开就没有了
刷新当前tab页还是存在
跳转到别的页再跳回来 还在
Ant Design的设计
lucifier129.github.io/ant-design/…
element-ui 传参
<sc-checkbox class="check-all" @change="handleCheckAll($event, 'state')" :indeterminate="isIndeterminateState" v-model="checkAllState" >全选</sc-checkbox>
handleCheckAll(val, type) {
// val -- checkAllState type-'state'
}
sortablejs
1、每个元素要有唯一标志 id phase.num_phase
2、拖拽后$nextTick 赋值 _this.currentScheme.phase_timing_paras = [...phaseTimingParas]
<div id="phaseList">
<div
class="phase-con"
:key="phase.num_phase"
v-for="(phase, index) in currentScheme.phase_timing_paras"
>
</div>
</div>
rowDrop() {
const tbody = document.querySelector(
`#phaseList`
);
const _this = this
tbody && Sortable.create(tbody, {
animation: 100,
draggable: "#phaseList .phase-con",
onEnd({ newIndex, oldIndex }) {
const phaseTimingParas = _this.currentScheme.phase_timing_paras
const currRow = phaseTimingParas.splice(oldIndex, 1)[0]
const aa = phaseTimingParas.splice(newIndex, 0, currRow)
_this.currentPhaseIndex = newIndex
_this.$nextTick(() => {
_this.updatePhaseNum(phaseTimingParas)
_this.currentScheme.phase_timing_paras = [...phaseTimingParas]
})
}
})
},
iframe
iframe 可以通过 window.parent.location 访问并改变父窗口的 location,从而导航到新的 URL。但是,iframe 不能直接修改父窗口的 DOM 元素,除非满足同源策略(Same-Origin Policy)。
1. 改变父窗口的 location
如果 iframe 和父窗口是同源的(即协议、域名和端口相同),iframe 可以通过以下代码改变父窗口的 location:
window.parent.location.href = 'https://example.com';
2. 修改父窗口的 DOM 元素
如果 iframe 和父窗口是同源的,iframe 可以通过 window.parent.document 访问并修改父窗口的 DOM 元素:
window.parent.document.getElementById('someElement').innerText = 'New Content';
3. 跨域限制
如果 iframe 和父窗口是不同源的,浏览器会阻止 iframe 访问或修改父窗口的 DOM 元素。这是出于安全考虑,防止跨站脚本攻击(XSS)。
4. 跨域通信
如果需要在跨域情况下进行通信,可以使用 postMessage API。父窗口和 iframe 可以通过 postMessage 发送消息,并通过监听 message 事件来接收消息。
父窗口代码:
window.addEventListener('message', function(event) {
if (event.origin !== 'https://iframe-origin.com') return; // 验证来源
console.log('Received message:', event.data);
});
// 向 iframe 发送消息
var iframe = document.getElementById('myIframe');
iframe.contentWindow.postMessage('Hello from parent', 'https://iframe-origin.com');
iframe 代码:
window.addEventListener('message', function(event) {
if (event.origin !== 'https://parent-origin.com') return; // 验证来源
console.log('Received message:', event.data);
});
// 向父窗口发送消息
window.parent.postMessage('Hello from iframe', 'https://parent-origin.com');
总结
iframe可以改变父窗口的location,无论是否同源。iframe只能修改父窗口的 DOM 元素,如果它们是同源的。- 跨域情况下,可以使用
postMessage进行安全的通信。
设计
摘要 产品设计 自然
确定性 完美不在于无以复加,而在于无可删减,万事莫不如此
布局 统一画板 为了尽可能减少沟通与理解的成本,有必要在组织内部统一设计板的尺寸。蚂蚁中台设计团队统一的画板尺寸为 1440。 宽度用百分比 flex
适配# 在设计过程中,设计师还需要建立适配的概念,根据具体情况判断系统是否需要进行适配,以及哪些区块需要考虑动态布局。据统计,使用中台系统的用户的主流分辨率主要为 1920、1440 和 1366,个别系统还存在 1280 的显示设备。
网格单位# Ant Design 通过网格体系来实现视觉体系的秩序。网格的基数为 8,不仅符合偶数的思路同时能够匹配多数主流的显示设备。通过建立网格的思考方式,还能帮助设计者快速实现布局空间的设计决策同时也能简化设计到开发的沟通损耗 关于栅格# Ant Design 采用 24 栅格体系。以上下布局的结构为例,对内容区域进行 24 栅格的划分设置,如下图所示。我们为页面中栅格的 Gutter 设定了定值,即浏览器在一定范围扩大或缩小,栅格的 Column 宽度会随之扩大或缩小,但 Gutter 的宽度值固定不变。
在大量的实践中,我们提取了一组可以用于 UI 布局空间决策的数组,他们都保持了 8 倍数的原则、具备动态的韵律感。经过验证,可以在一定程度上帮助我们更快更好的实现布局空间上的设计决策。
是启发,而非限制
主字体# 我们基于电脑显示器阅读距离(50 cm)以及最佳阅读角度(0.3)对 Ant Design 的主字体进行了一次升级,从原先的 12 上升至 14,以保证在多数常用显示器上的用户阅读效率最佳
形式,是构成一个图形最初始的结构。Ant Design 整套基础图标基本上都是由圆、方、三角这样的图形演变而成的 Ant Design 图标的韵律感通过两个方面来体现:元素的韵律和构图的韵律。系统图标中最常见的元素基本上可以归纳称为:点、线、圆角、三角。
正如 Alan Cooper 所言:「需要在哪里输出,就要允许在哪里输入」。这就是直接操作的原理。eg:不要为了编辑内容而打开另一个页面,应该直接在上下文中实现编辑。
能在这个页面解决的问题,就不要去其它页面解决,因为任何页面刷新和跳转都会引起变化盲视(Change Blindness),导致用户心流(Flow)被打断。频繁的页面刷新和跳转,就像在看戏时,演员说完一行台词就安排一次谢幕一样。
二次确认覆盖层:避免滥用 Modal 进行二次确认,应该勇敢的让用户去尝试,给用户机会「撤销」即可。 或用Popconfirm进行二次确认,在当前页面完成任务。
列表嵌入层:在列表中,显示某条列表项的详情信息,保持上下文不中断。
弹出框覆盖层:虽然弹出框的出现会打断用户的心流,但是有时候在弹出框中使用「步骤条」来管理复杂流程也是可行的。
如果某个操作非常重要,就应该把它放在界面中,并实时可见。 如果某个操作不那么重要,或者使用「实时可见工具」过于啰嗦会影响用户阅读时,可以在悬停在该对象上时展示操作项。 如果某些操作只需要在特定模式时显示,可以通过开关来实现。
在使用 Table 时,文字链的点击范围受到文字长短影响,可以设置整个单元格为热区,以便用户触发。当需要增强按钮的响应性时,可以通过增加用户点击热区的范围,而不是增大按钮形状,从而增强响应性,又不缺失美感。
中国默认使用 yyyy-mm-dd 格式。(其它国家参考链接)。 2019-12-08 含有月日的专用名词采用阿拉伯数字表示时,应采用间隔号 · 将月、日分开,并在数字前后加引号。 6.1 儿童节 在日期或时间范围之间显示一个波浪号 (前后需要空格)。 2018-12-08 ~ 2019-12-07 二十四小时时间格式 HH:mm:ss 。 14:08:00
十二小时时间格式 h:mm:ss 。 2:08:00 PM | 2:08:00 AM 期与时间连在一起时,两者之间用「空格」隔开,如“2019-12-08 06:00:00”。
在表述内容时,关注点应该是用户和他们能用你的产品做什么,而不是你和你的产品在为他们做什么,所以内容表述的立足点很重要。既然以用户为中心,文案就应该尽量以用户为主体来写作。
省略无用词汇,不重复用户已知事实;在绝大多数交互场景下,都无需界面描述出全部的细节。尽量提供简短、易于快速获取的内容。
使用 不使用
其他 其它 「其他」的应用范围更广
抱歉 对不起 如果是我们系统造成的结果,可以使用「抱歉」,如果是用户自己造成的结果,不能使用。
登录 登陆 登记记录用户输入的注册账号和密码。
此 该 当要表达当前事物时,「此」更加明确。
直接使用「你」、「我」来和用户对话,与用户建立亲密感。避免使用「您」,让用户感觉太过疏远。 多给用户支持与鼓励,不要命令和强迫用户。
如果你想留住你的用户,当出错的时候就不要责怪用户。专注于解决问题,而不是指责。 不要使用过于绝对的表述,这样会让用户觉得不适。 产品名称全称,首字母大写。产品名称缩写需要全部大写,如:ESC、SLB 等;