测试页面加载速度

一级标题

一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题

二级标题

一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题

三级标题

一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题

四级标题

一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题

五级标题

一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题

六级标题

一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题一级标题

 
 
 
 
Ant Design of Vue

页面结构 vue

<template>
     <div>{{testData}}</div>
</template>


<script>
// import {getAction} from '@api/manage'
export default{
    data(){
        return{
            testData:'',//我是测试数据
        }
    },
}
</script>


<style scoped>


</style>

设置标题

设置单页面标题

//router/index.js

{
    path: '/Userlist',
    name: 'Userlist',
    component: Userlist,
    meta: {
        title: '员工列表'
    }
},

watch:{
    // 获取路由的相关数据参数
    $route(){
      console.log(this.$route.meta);
      // 设置单页面 的 标题 内容
      document.title = '海尔后台管理系统' +'---'+ this.$route.meta.title;
    }
  },
  created(){
    this.selectedKeys = [this.$route.path];//
    console.log('this.$rounte',this.$route);
  },

 

请求的书写
import {getBindAccountZoneList,accountSaveOrUpdate} from '@/api/api'


// 园区选择搜索框方法
handleZoneSearch(val = "") {
   getBindAccountZoneList({
       zoneName:val
   }).then(res => {
       if(res.code == 0) {
           this.zoneOption = res.result
       }
   })
},


// 导入 接口数据
import {getAllZoneList} from '@/api/api'


// 获取园区列表
getZoneList() {
    getAllZoneList().then(res => {
        if(res.code == 200) {
            this.dataSource = res.result
            console.log('res999999',res);
        }
    })
},

 

<script>
import {getAction} from '@api/manage'  //api 文件
export default{
    data(){
        return{
            testData:'',
            url:'/test/jeecgDemo/testData'
        }
    },
    created(){
        // this.loadData();
    },
    methods:{
      // 获取请求
      loadData(){
          getAction(this.url).then((res)=>{
              this.testData = res.data;
          })
      },
      getUserList(){
        async getList(){
          let res = await this.$get('/user/userlist');
          this.data = res.data.list;
        }
      }
  }
}
</script>

 

 

 

Card 卡片的headStyle和bodyStyle设置

https://blog.csdn.net/weixin_40425415/article/details/101537089

从官网上可以看到Card的相关使用和API https://vue.ant.design/components/card-cn/

 

这里可以看到headStyle 和 bodyStyle 的类型都是object,但是为它赋值的需要注意一些问题。

如果只设置一个样式,可以直接在行内写

<a-card title="title" :bordered=false :headStyle="{color:'#0785fd'}" :bodyStyle="{padding:'0'}"></a-card>

但是如果要设置多个CSS样式这样的书写方式就会报错出问题了

解决办法:(以headStyle为例)

在js中定义一个变量,再将变量值赋予headStyle即可

html:

<a-card title="title" class="bg" :bordered=false :headStyle='tstyle'></a-card>
js:
<script>
	export default {
		data() {
			return {
				tstyle:{"color": "#0785fd","font-weight": "bold"}
			}
		},
		methods: {
 
		}
	}
</script>

删除头部底部边框

<a-card style="width: 96%;margin-top:20px;" title="#1108" :headStyle="{border:'none'}">
</a-card>

 

Drawer 抽屉 内部样式修改

<a-drawer
  width="300"
  title="我的园区"
  placement="left"
  :closable="false"
  :visible="drawerVisible"
  :bodyStyle="bodyStyle"
  :headerStyle="headerStyle"
  :after-visible-change="afterVisibleChange"
  @close="onClose"
>


bodyStyle:{'padding':'0px'},
headerStyle:{'border': '0','position':'fixed','width':'300px','z-index': '9999',}
Statistic 统计数值 修改 后缀颜色

<a-statistic :value="47">
  <template #suffix>
      <span style="color:rgba(0,0,0,.45);">个</span>
  </template>
</a-statistic>


<a-statistic :precision="2" :value="1800" suffix="㎡" />
.ant-statistic-content{
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    word-break: break-all;
    color: rgba(0,0,0,.45);
    font-size: 14px;
    line-height: 1.5;
}
<div class="header_right">
    <div class="rig_title">招商状态</div>
    <div class="rig_info">
        <a-statistic  value="可招商"/>
    </div>
</div>
样式
.header_right{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 130px;
  margin-left: 15px;
  line-height: 1.5;
  flex: 1;
}
.header_right .rig_title{
  margin-bottom: 4px;
  color: rgba(0,0,0,.45);
  font-size: 14px;
}
.header_right .rig_info{
  font-size: 22px;
color: rgba(0,0,0,.45);
}
 
 

 

 

Tabs 标签页

设置默认底部的 padding 为 0

<a-tabs default-active-key="1" @change="callbacktabs" :tabBarStyle="tabBarStyle"  style="margin-top: 15px;" >
    <a-tab-pane key="1" tab="基本信息"></a-tab-pane>
    <a-tab-pane key="2" tab="独立房源" force-render></a-tab-pane>
    <a-tab-pane key="3" tab="联合办公"></a-tab-pane>
</a-tabs>


return{
    tabBarStyle:{'marginBottom':'0px'},

 

Progress 进度条 strokeWidth 设置问题

type check failed for prop "strokeWidth". Expected Number with value 9

数据类型是字符串类型不是数字类型 给前面加:可以解决

Select 选择器 单项

https://www.antdv.com/components/select-cn/

<div>
    <a-select style="width: 120px" placeholder="请选择" @change="handleChange">
        <a-select-option v-for="(item,index) in selectList" :key="index">{{item.name}}</a-select-option>
    </a-select>
    <div>{{testData3}}</div>
</div>
<script>
export default{
    data(){
        return{
            selectList:[
                {
                    name:'男',
                    value:1,
                },
                {
                    name:'女',
                    value:2,
                },
                {
                    name:'未知',
                    value:0,
                },
            ],
        }
    },
    methods:{
        handleChange(e){
            console.log('e',e);
        },
    }
}
</script>

//v-model  双向数据绑定
<a-form-model-item label="招商状态" ref="zsStatus"  prop="zsStatus">
  <a-select placeholder="请选择" v-model="form.zsStatus">
      <a-select-option :value="item.value" v-for="(item,index) in selectList" :key="index">{{item.name}}</a-select-option>
 </a-select>
</a-form-model-item>


<script>
export default{
    data(){
        return{
            form: {
                zsStatus:1,//招商状态
            },
            rules: {
                zsStatus: [
                    { required: true, message: '请输入选择招商状态', trigger: 'blur' },
                ],
            },
            // 修改基本信息 招商状态
            selectList:[
                {
                    name:'可招商',
                    value:1,
                },
                {
                    name:'不可招商',
                    value:2,
                },
            ],
        }
    },
}
</script>

v-model="item.id"

<a-select mode="tags" allowClear style="width: 45%;margin: 5px 0px 21px 0px;" placeholder="请选择园区" @change="handleChange">
  <a-select-option v-for="(item,index) in dataSource" :key="index" v-model="item.id">
    {{ item.name }}
  </a-select-option>
</a-select>
Select 选择器 联动
<a-col :span="12" style="margin-right:20px;">
    <a-form-model-item label="楼宇" ref="floorNum" prop="floorNum">
        <a-cascader
            v-model="form.floorNum"
            :options="options"
            :default-value="['01栋', '2F']"
            @change="onChangeLy"
            placeholder="请选择"
        />
    </a-form-model-item>
</a-col>


data(){
  form: {
        floorNum:['01栋', '2F'],//楼宇
    },
    rules: {
        floorNum: [
            { required: true, message: '请输入楼宇', trigger: 'blur' },
        ],
    },
    // 楼宇
    options: [
        {
            value: '01栋',
            label: '01栋',
            children: [
                {
                value: '1F',
                label: '1F',
                },
                {
                value: '2F',
                label: '2F',
                },
                {
                value: '3F',
                label: '3F',
                },
            ],
        },
    ],
}


//楼宇选择
onChangeLy(value) {
    console.log(value);
},
Radio 单选框
<a-radio-group default-value="a" @change="radioClick" button-style="solid">
  <a-radio-button defaultChecked value="a" class="rabtn">房源</a-radio-button>
  <a-radio-button value="b" class="rabtn">工位</a-radio-button>
</a-radio-group>


//方法
methods:{
    // Radio 选中的事件
    radioClick(e){
        console.log('e',e.target.value);
    }
}


//样式
.ant-radio-button-wrapper-checked{
    border-radius: 2px !important;
}
.ant-radio-button-wrapper{
    border: none !important;
}
.ant-radio-button-wrapper:not(:first-child)::before{
    width: 0;
}
标签

<a-form-model-item label="标签">
    <template v-for="tag in tags">
        <a-checkable-tag
            :key="tag"
            style="border:1px solid #d9d9d9;cursor: pointer;"
            :checked="selectedTags.indexOf(tag) > -1"
            @change="checked => handleChangetag(tag, checked)"
        >
            {{ tag }}
        </a-checkable-tag>
    </template>
</a-form-model-item>


data(){
   // 标签
  tags: ['适合科技型企业', '初创企业优选', '制造型企业定制'],
  selectedTags: [],//标签选中
}


// 标签
handleChangetag(tag, checked) {
    const { selectedTags } = this;
    const nextSelectedTags = checked
        ? [...selectedTags, tag]
        : selectedTags.filter(t => t !== tag);
    console.log('You are interested in: ', nextSelectedTags);
    this.selectedTags = nextSelectedTags;
},
CheckBox change事件 有附加参数 事件参数通过$event传入

Ant Design Vue 中CheckBox change事件 有附加参数 事件参数通过$event传入,如

@change="onSimpleFourSelect($event,item.id,2)"

Vue前端 不刷新值时可以 调用

this.$forceUpdate()

 

<a-checkbox @change="onChangeChecked($event,items,indexs)"></a-checkbox>


//每一项上面的checked
onChangeChecked(e,items,indexs) {
    console.log('e9999',e,items,indexs); 


    this.checkVal = e.target.checked;  //获取选中状态  true  false


    console.log('items',items.id);//输出当前选中的 id
    if(this.checkVal){  //如果是true  则向选中数组中添加  元素
        this.checkedArr.push(items.id);
    }else{   // 否则删除没选中的元素
         this.checkedArr.splice( this.checkedArr.findIndex(item => item.id === items.id), 1)
    }
    console.log('this.checkedArr111',this.checkedArr); 
},

 

输入框的组合展现

<a-form-model
  @submit="submit"
  :model="aadForm"
  ref="ruleForm"
  :rules="rules"
  style="width:328px"
  >
  <a-form-model-item label="签订信息" prop="username" ref="username" >
      <a-input-group compact>
          <a-select v-model="aadForm.qdxx" style="width:30%">
              <a-select-option :value="item.value" v-for="(item,index) in adSelectList" :key="index">{{item.name}}</a-select-option>
          </a-select>
          <a-date-picker @change="qdOnChange" style="width:70%"/>
      </a-input-group>
  </a-form-model-item>
</a-form-model>


// 签订信息
adSelectList:[
    {
        name:'李四',
        value:1,
    },
    {
        name:'王五',
        value:2,
    },
    {
        name:'小六',
        value:3,
    },
],
aadForm:{
  qdxx:1,//签订信息  人
  qddate:'',//签订日期
},
rules: {
    qdxx: [
        { required: true, message: '请选择', trigger: 'blur' },
    ],
},


//签订信息日期
qdOnChange(date, dateString) {
    console.log(date, dateString);
    this.aadForm.qddate = dateString
},

 

DatePicker 日期选择框

<a-form-model-item label="租赁周期" prop="zlzq" ref="zlzq" >
    <a-range-picker @change="zlzqOnChange" separator="⇀"/>
</a-form-model-item>


aadForm:{
   zlzq:'',// 租赁周期
},
rules: {
    zlzq: [
        { required: true, message: '请选择', trigger: 'blur' },
    ],}
//租赁周期
zlzqOnChange(date, dateString) {
    console.log(date, dateString);
},

 

 

 

Form表单

上下布局

<a-form-model
    @submit="submit"
    :model="form"
    ref="ruleForm"
    :rules="rules"
    >
    <a-form-model-item label="用户名" prop="username" ref="username" >
        <a-input v-model="form.username" placeholder="请输入用户名"/>
    </a-form-model-item>
</a-form-model>

 

https://blog.csdn.net/weixin_43995405/article/details/112312346

<div>
    <!-- v-bind="layout" : label 和 输入内容的 百分比
    :model="form" 必须优先注册
    :labelCol="{ span: 5 }"   标题 label 的宽度
    :wrapperCol="{ span: 3, offset: 0 }" label 后面内容的 宽度 offset 后面内容的偏移量 -->
    <a-form-model
    @submit="submit"
    :model="form"
    ref="ruleForm"
    :rules="rules"
    :labelCol="{ span: 5 }"
    :wrapperCol="{ span: 3, offset: 0 }"  
    >
        <!-- 纵向 排列的方式 -->
        <a-form-model-item>
            <label>密码</label>
            <a-input type="password" v-model="form.password" placeholder="请输入密码"/>
        </a-form-model-item>


        <!-- 横向 排列的方式 -->
        <!-- 常规的手机号验证 -->
        <a-form-model-item label="用户名" prop="username" ref="username" >
            <a-input v-model="form.username" placeholder="请输入用户名"/>
        </a-form-model-item>
        <a-form-model-item label="新密码" prop="newPassword" ref="newPassword">
            <a-input-password v-model="form.newPassword"/>
        </a-form-model-item>
        <a-form-model-item label="新密码确认" prop="cfmNewPassword" ref="cfmNewPassword">
            <a-input-password v-model="form.cfmNewPassword"/>
        </a-form-model-item>


        <a-form-model-item label="手机号" prop="phone" ref="phone">
            <a-input v-model="form.phone" placeholder="请输入手机号"/>
        </a-form-model-item>


        <!-- 通过失去焦点 自定义的 校验 -->
        <a-form-model-item label="手机号" prop="phone" ref="phone">
            <a-input v-model="form.phone" placeholder="请输入手机号" @blur="validatePhoneBlur"/>
        </a-form-model-item>
        <a-form-model-item label="邮箱" prop="email" ref="email">
            <a-input v-model="form.email" placeholder="请输入邮箱" />
        </a-form-model-item>
        <!-- 提交 重置 按钮 -->
        <a-form-model-item>
            <a-button type="primary" html-type="submit" block>提交</a-button>
            <a-button type="primary" @click="resetForm" block>重置</a-button>
        </a-form-model-item>              
    </a-form-model>
</div>


data(){
    // 在线请求 校验  用户名是否唯一
    let validateUsername = (rule, value, callback) => {
        var params = {
            id:this.model.id,
            username:value
        };
        checkUsername(params).then((res)=>{  //请求接口数据  true 就是不存在可以使用  false 存在不能使用
            if(res.success){
                callback();
            }else{
                callback(new Error("用户账号已存在!"));
            }
        })
    };
    //两次密码校验
    let validatePassword = (rule, value, callback) => {
        console.log('this.newPassword.form',this.form.newPassword);
        console.log('value',value);
        if (value !== this.form.newPassword) {
            callback(new Error('两次输入的密码不一致'));
        } else {
            callback();
        }
    };
    return{
        form:{
            username:'',
            password:'',
            phone:'',
            email:'',
            newPassword:'',//新密码
            cfmNewPassword:''//新密码确认
        },
        rules: {
            username: [
                { required: true, message: '请输入用户名', trigger: 'blur' },
                { min: 3, max: 5, message: '用户名长度3至5位', trigger: 'blur' },
            ],
            phone: [
                { required: true, message: '手机号必填', trigger: 'blur' },
                { pattern: /^1\d{10}$/, message: '您输入的手机格式不正确!', trigger: 'blur' }
            ],
            email: [
                { required: true, message: '请填写邮箱', trigger: 'blur' },
                { type: 'string',
                    message: '邮箱格式不正确',
                    trigger: 'blur',
                    transform (value) {
                    if (!/^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)) {
                        return true
                    }else{
                    }
                    }
                },
                { type: 'string', message: '长度不能超过30位', trigger: 'blur', max: 30 }
            ],
            newPassword: [
                {required: true, message: '请填写新密码', trigger: 'blur' },
            ],
            cfmNewPassword: [
                {required: true, message: '请填写密码', trigger: 'blur' },
                {validator: validatePassword, trigger: 'blur'}
            ],
        }
        
    }
},
methods:{
    // 表单内容重置
    resetForm() {
        this.$refs.ruleForm.resetFields();
    },
    // 表单提交事件
    submit(){
        // 提交表单数据前 校验 数据是否符合条件 符合就提交 不符合就不提交
        this.$refs.ruleForm.validate(valid => {
            if (valid) {
                alert('submit!');
            } else {
                console.log('error submit!!');
                return false;
            }
        });
    },
}

vue 校验规则

邮箱:

// 邮箱
email: [
  { required: true, message: '请填写邮箱', trigger: 'blur' },
  { type: 'string',
    message: '邮箱格式不正确',
    trigger: 'blur',
    transform (value) {
      if (!/^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)) {
        return true
      }else{
      }
    }
  },
  { type: 'string', message: '长度不能超过30位', trigger: 'blur', max: 30 }
],

 

rules: {
    //验证非空和长度
    name: [
        {required: true,message: "站点名称不能为空",trigger: "blur"},
        {min: 3,max: 5,message: '长度在 3 到 5 个字符',trigger: 'blur'
    }],
    //验证数值
    age: [
        {type: 'number',message: '年龄必须为数字值',trigger: "blur"
    }],
    //验证日期
    birthday:[
        {type: 'date',required: true,message: '请选择日期',trigger: 'change'
    }],
    //验证多选
    habit: [
        {type: 'array',required: true,message: '请至少选择一个爱好',trigger: 'change'
    }],
    //验证邮箱
    email: [
        {type: 'email',message: '请输入正确的邮箱地址',trigger: ['blur', 'change']
    }],
    // 验证手机号
    telephone: [
        {pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,message: "请输入正确的手机号码",trigger: "blur"
    }],
    // 验证经度 整数部分为0-180小数部分为0到7位
    longitude: [
        {pattern: /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,7})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,6}|180)$/,message: "整数部分为0-180,小数部分为0到7位",trigger: "blur"
    }],
    // 验证维度 整数部分为0-90小数部分为0到7位
    latitude: [
        {pattern: /^(\-|\+)?([0-8]?\d{1}\.\d{0,7}|90\.0{0,6}|[0-8]?\d{1}|90)$/,message: "整数部分为0-90,小数部分为0到7位",trigger: "blur"
    }]          
}

 

Upload 上传

https://www.antdv.com/components/upload-cn/

<div class="clearfix">
  <!-- action 上传地址 -->
  <!-- listType 上传列表的内建样式,支持三种基本样式 text, picture 和 picture-card -->
  <!-- fileList 已经上传的文件列表(受控)  -->
  <!-- headers 设置上传的请求头部,IE10 以上有效 -->
  <!-- multiple 是否支持多选 -->
  <!-- preview 点击文件链接或预览图标时的回调     -->
  <!-- change  上传文件改变时的状态 -->
  <a-upload
      action="url.fileUpload"
      list-type="picture-card"
      :file-list="fileList"
      :headers="headers"
      multiple
      @preview="handlePreview"
      @change="handleChange"
      >
      <div v-if="fileList.length < 8">
          <a-icon type="plus" />
          <div class="ant-upload-text">Upload</div>
      </div>
  </a-upload>
  <!-- 预览的弹框 -->
  <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
  </a-modal>
</div>


data(){
  return{
    headers: {}, //请求头 下方的 created 中进行了定义 含 token
    url:{ //文件上传 公共 的地址
        fileUpload:'/sys/common/upload'
    },
    previewVisible: false, //判断 预览 弹框是否显示
    previewImage: '', //预览的图片地址
    fileList: [
        {
        uid: '-1',
        name: 'image.png',
        status: 'done',
        url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
        },
    ],
  }
},
created(){
    const token = Vue.ls.get(ACCESS_TOKEN);
    this.headers = {"X-Access-Token":token}
},
methods:{
  //  关闭预览事件
  handleCancel() {
      this.previewVisible = false; //上传的时候将 弹框 隐藏
  },
  // 点击预览
  async handlePreview(file) {
      if (!file.url && !file.preview) {
          file.preview = await getBase64(file.originFileObj);
      }
      this.previewImage = file.url || file.preview;
      this.previewVisible = true;
  },
  // 点击上传
  handleChange({ fileList }) {
      this.fileList = fileList;  
  },
}

 

Modal 对话框
<div>
    <a-button type="primary" @click="showModal">弹窗</a-button>
    <a-modal
    title="标题"
    :width="300"
    :visible="visible"
    :confirm-loading="confirmLoading"
    cancelText="取消"
    okText="确认"
    @ok="handleOk"
    @cancel="handleCancel"
    >
    <p>内容</p>
    </a-modal>
</div>  
data(){
  return{
     visible: false, //模态框默认关闭
  }
}
methods:{
    // 显示弹窗
    showModal() {
        this.visible = true;
    },
    //点击关闭 弹窗
    handleOk(e) {
        this.visible = false;
    },
    //
    handleCancel(e) {
        this.visible = false;
    },
}
图片 image
<img src="http://8.136.101.171:84/static/default-park-avatar_377x248.c777fe4a.png" width="200" alt="">d

 

Table 表格1 单项数据操作

 

 

<template>
    <div>
        <h3>{{name}}</h3>
        <div>
            <!-- bordered 是否展示外边框和列边框    -->
            <!-- columns 表头 -->
            <!-- dataSource 数据源  -->
            <!-- loading 页面是否加载中 可配合方法使用 -->
            <!-- pagination 分页器 -->
            <a-table :columns="columns" :dataSource="data" bordered style="width:80%;" :pagination="pagination" @change="tableChange">
                <template slot="customTitle"><a-icon type="smile-o" />  姓名</template>
                <template slot="avatar" slot-scope="record">
                    <img :src="record.avatar" style="width: 50px;height: 50px;border-radius: 50px;" alt="">
                </template>
                <a slot="name" slot-scope="text">{{ text }}</a>
                <!-- tags 在表格中的使用 遍历数组 通过三元表达式判断-->
                <template slot="tags" slot-scope="tags">
                    <a-tag
                        v-for="tag in tags"
                        :key="tag"
                        :color="tag === '特殊' ? 'red' : tag.length > 5 ? 'blue' : 'green'"
                    >
                        {{ tag.toUpperCase()}}
                    </a-tag>
                </template>
                <!-- 通过插槽传值 -->
                <template slot="action" slot-scope="action">
                    <!-- slot="action" 插槽名
                    slot-scope="record" 该插槽内部能搞抓取到的改行的数据
                    也可展示改行对应的内容 {{ record.name }} -->
                    {{action}}
                    <a href="javascript:;"  @click.stop="editHandle(action)">编辑</a>
                    <a-divider type="vertical"/>
                    <a href="javascript:;" @click.stop="deleteRecord(action)">删除</a>
                    <a-divider type="vertical" />
                    <a-popconfirm
                    v-if="data.length"
                    title="确定删除吗?"
                    cancelText="取消"
                    okText="确认"
                    @confirm="() => onDelete(action.key)"
                    >
                    <a href="javascript:;">Delete</a>
                    </a-popconfirm>
                    <a-divider type="vertical" />
                    <a-dropdown>
                        <a class="ant-dropdown-link">更多<a-icon type="down" /></a>
                        <a-menu slot="overlay">
                            <a-menu-item>
                                <a href="javascript:;">账户详情</a>
                            </a-menu-item>
                            <a-menu-item>
                                <a href="javascript:;">积分余额</a>
                            </a-menu-item>
                            <a-menu-item>
                                <a href="javascript:;">赠送会员</a>
                            </a-menu-item>
                            <a-menu-item>
                                <a href="javascript:;">设置标签</a>
                            </a-menu-item>
                        </a-menu>
                    </a-dropdown>
                </template>
            </a-table>
        </div>
    </div>
</template>


<script>
// columns 表头
const columns = [
    {
        slots: { title: 'customTitle' }, //插槽式标题
        dataIndex: 'name', //列数据在数据项中对应的 key,支持 a.b.c 的嵌套写法  dataIndex  添加上就是 slots 一条数据  手机号
        // key: 'name',
        align:'left',  //设置列内容的对齐方式
        width:'100px', //列宽度    
        scopedSlots: { customRender: 'name' },
    },
    {
        title: '头像', //列头显示文字   
        // dataIndex: 'avatar',   dataIndex 隐藏则是  一个 object全部参数
        //  key: 'avatar',
        scopedSlots: { customRender: 'avatar' },
        align:'center',  //设置列内容的对齐方式
    },
    {
        title: '年龄', //列头显示文字   
        dataIndex: 'age',
        //  key: 'age',
    },
    {
        title: '地址',
        dataIndex: 'address',
        // key: 'address',
        ellipsis: true, //可以让单元格内容根据宽度自动省略
    },
    {
        title: '标签',
        // key: 'tags',
        dataIndex: 'tags',
        scopedSlots: { customRender: 'tags' },
    },
    {
        title: '其他操作',
        // key: 'action',
        scopedSlots: { customRender: 'action' },
        //  获取整列数据的话 就需要 删除 dataIndex: '',
    },
];
// 数据源
const data = [
    {
        key: '1',
        name: '张三',
        avatar:'https://wx.qlogo.cn/mmhead/PuL96pVthdbAm92VzhJcOA1x8gYkL2fRVibSXnyehCsE/0',
        age: 32,
        address: '安徽省合肥市瑶海区创造世纪广场的104高地',
        tags: ['标签1', '标签2'],
    },
    {
        key: '2',
        name: '李四',
        avatar:'https://wx.qlogo.cn/mmhead/YueYOwgxa7vStHEdHH75TLbp1A4hGnIQCQvSvb0Xsuc/0',
        age: 42,
        address: '江苏省南京市',
        tags: ['标签33333'],
    },
    {
        key: '3',
        name: '王五',
        avatar:'https://wx.qlogo.cn/mmhead/Q3auHgzwzM6TRVicNfqvBM9xQEsJJsNliaCCLqzrueTQ7ZhtjE0UiaWWw/0',
        age: 32,
        address: '福建省莆田市',
        tags: ['特殊', '标签5'],
    },
];
export default {
    name:'Table',
    data() {
        return{
            name:'表格',
            data,
            columns,
            // 分页器
            pagination:{
                total:100, //默认的总条数,在从后台获取数据列表成功之后对其进行赋值
                defaultPageSize:10, //默认每页的显示条数 
                showTotal: total => `共 ${total} 条数据`, //用于显示数据总量和当前数据顺序
                showSizeChanger:true, //是否可以改变 pageSize,布尔值,一般情况设置为true
                pageSizeOptions: ['5', '10', '15', '20'], //可选的页面显示条数
                onShowSizeChange:(current, pageSize)=>this.pageSize = pageSize, //pageSize 变化的回调,可以拿到当前的页数和pageSize,直接再将其赋值给pagination即可    
            },
        }
    },
    methods:{
        // 修改  通过 插槽  可获取到对应项的  数据  
        editHandle(e){
            // alert('修改事件');
            console.log('e',e);
        },
        // 删除
        deleteRecord(e){
            // alert('删除事件');
            console.log('e',e);
        }, 
        // 改变分页器
        tableChange(e){
            const { current, pageSize } = e;
            this.pagination.current = current;
            this.pagination.pageSize = pageSize;
            this.getTableList();
        },
    }
}
Table 表格2 获取全部数据操作

<template>
  <div>
      <!-- a-config-provider  pagination页码 page  进行  汉化
      columns   表头
      data  表内数据
      v-for="col in ['name', 'age', 'address']" 遍历循环  一一对应 便于 操作单项数据-->
      <a-config-provider :locale="locale">
        <a-table :pagination="pagination" :columns="columns" :data-source="data">
          <!-- text 单项对应的 value
          record 全部的数据 object
          index  索引 -->
          <template
            v-for="col in ['name', 'age', 'address']"
            :slot="col"
            slot-scope="text, record, index"
            >
            {{ text?text:'--' }}
          </template>
          <template slot="tags" slot-scope="tags">
              <a-tag
                v-for="tag in tags"
                :key="tag"
                :color="tag === 'aaa' ? 'blue' : tag === 'bbb' ? 'yellow' : 'red'"
              >
                {{ tag.toUpperCase() }}
              </a-tag>
          </template>
          <template slot="action" slot-scope="text, record">
              <a>编辑</a>
              <a-divider type="vertical" />
              <a-popconfirm
                  title="确定删除?"
                  ok-text="确定"
                  cancel-text="取消"
                  @confirm="confirm"
                  @cancel="cancel"
              >
                <a @click="del">删除</a>
              </a-popconfirm>
          </template>
        </a-table>
      </a-config-provider>
  </div>
</template>
<script>
const columns = [
  {
    dataIndex: 'name',//绑定 可以 一一对应 显示 便于 操作单项数据
    title: '姓名',
    key: 'name',
    width:'10%',//表格宽度
    scopedSlots: { customRender: 'name' },
  },
  {
    title: '年龄',
    dataIndex: 'age',
    key: 'age',
    width:'10%',
    scopedSlots: { customRender: 'age' },
  },
  {
    title: '地址',
    dataIndex: 'address',
    key: 'address',
    width:'40%',
    scopedSlots: { customRender: 'address' },
  },
  {
    title: '标签',
    key: 'tags',
    width:'20%',
    dataIndex: 'tags',
    scopedSlots: { customRender: 'tags' },
  },
  {
    title: '操作',
    key: 'action',
    width:'20%',
    scopedSlots: { customRender: 'action' },
  },
];


const data = [
  {
    key: '1',
    name: '张三',
    age: 5,
    width:'20%',
    address: '',
    tags: ['aaa', 'bbb'],
  },
  {
    key: '2',
    name: '李四',
    age: 8,
    address: '安徽安庆',
    tags: ['ccc','aaa'],
  },
  {
    key: '3',
    name: '王五',
    age: '',
    address: '安徽寿县',
    tags: ['bbb', 'ccc'],
  },
];
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
export default {
    name:'Userlist',
    data() {
        return {
            data,
            columns,
            // 分页器
            pagination:{
                defaultPageSize:10, //默认每页的显示条数 
                showSizeChanger:true, //是否可以改变 pageSize,布尔值,一般情况设置为true
                pageSizeOptions: ['5', '10', '15', '20'], //可选的页面显示条数
                onShowSizeChange:(current, pageSize)=>this.pageSize = pageSize, //pageSize 变化的回调,可以拿到当前的页数和pageSize,直接再将其赋值给pagination即可    
            },
            locale: zhCN,
        }
    },
    methods:{


    }
};
</script>

 

ant-design-vue怎么把分页器的page 改成 页

在需要 修改的 页面 引入

a-config-provider :locale="locale" 包裹在 table 外面

<a-config-provider :locale="locale">
<a-table
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
:columns="columns"
:data-source="data"
:pagination="pagination"
>
    <template slot="email" slot-scope="email">
        <span>{{email.email?email.email:'--'}}</span>
    </template>
    <template slot="money" slot-scope="money">
        <span>{{money.money?money.money:'--'}}</span>
    </template>
    <template slot="person" slot-scope="person">
        <span>{{person.person?person.person:'--'}}</span>
    </template>
    <template slot="action" slot-scope="action">
        <!-- {{action}} -->
        <a href="javascript:;"  @click.stop="editHandle(action)">详情</a>
        <a-divider type="vertical"/>
        <a-popconfirm
            title="确定删除?"
            ok-text="确定"
            cancel-text="取消"
            @confirm="confirm"
            @cancel="cancel"
        >
            <a href="javascript:;">删除</a>
        </a-popconfirm>
    </template>
</a-table>
</a-config-provider>


import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
data () {
  return {
    locale: zhCN,
   }
}
Popover 气泡卡片

<a-popover placement="right" overlayClassName="popovers">
  <template slot="content" style="padding:0px;">
      <div class="li_list" @click="handleClickRouterSwitch('/zone/account')">
        <li><a-icon type="user"/> 个人中心</li>
      </div>
      <div class="li_list" @click="handleClickRouterSwitch('/dashboard/analysis')">
        <li><a-icon type="setting"/> 后台设置</li>
      </div>
      <div class="li_list" @click="handleLogout">
        <li><a-icon type="logout"/> 退出登录</li>
      </div>
  </template>
  <div class="avatar" @click="e => e.preventDefault()">
      <img src="http://8.136.101.171/static/default-user-avatar-female.63b58443.svg" alt="avatar">
  </div>
</a-popover>


//样式
.avatar{
  width: 90%;
  padding: 10px 0px;
  display: flex;
  justify-content: center;
}
.avatar:hover{
  background: rgba(0,0,0,.025);
}
.avatar img{
  width: 32px;
  height: 32px;
  line-height: 32px;
  font-size: 18px;
}
.li_list{
  line-height: 2;
  color: #252525;
  cursor: pointer;
  padding: 2px 10px;
}
.li_list:hover{
  background: #f5f5f5;
}
.ant-popover-inner-content{
  padding: 0px;
}
.popovers{
  width:150px;
}

 

 

 

vue动态绑定class 遍历 动画添加

@mouseenter="enter(index)" 鼠标移上

@mouseleave="leave" 鼠标移开

<a-card :bodyStyle="cardStyle"  @mouseenter="enter(index)" @mouseleave="leave"  class="left_card" hoverable v-for="(item,index) in 6" :key="index">
    <!-- 当前遍历对象的 index 和 animationStatus 相等时,则添加对应的类 -->
   <div class="arrow" v-bind:class="{animation:animationStatus == index}">
    <a-icon type="arrow-right" />
  </div>
</a-card>


data () {
  return {
    cardStyle:{"width":"100%","display": 'flex','justify-content': 'space-between','align-items': 'center'},
    animationShow:false,//箭头动画效果
    animationStatus:'',
  }
},
methods: {
  // 鼠标在 card 上方 添加动画
  enter(e){
    this.animationStatus = e;
  },
}


/* 箭头又移动画 */
.animation{
  /* 动画名称  持续时间 运动曲线 播放次数 */
  animation:  fadeinL 1000ms ease 1; 
}
@keyframes fadeinL{
   0%{opacity:0;transform:translateX(-50px);}
}

 

通过 hover 绑定 实现

 

<div class="parkCard">
  <div class="arrow">
    <a-icon type="arrow-right" style="color:#878787;" />
  </div>
</div>


/* 定义 箭头右移动画 */
@keyframes fadeinL{
   0%{transform:translateX(0px);}
   100%{color:rgb(24, 24, 34);transform:translateX(40px);}
}


/* 在 外层使用  动画效果  hover    */
/deep/ .parkCard:hover .arrow {
  animation:  fadeinL 400ms ease 1 forwards; 
}

 

 

 

 

通过元素hover属性控制显示隐藏

纯CSS控制 https://www.jianshu.com/p/bc663c890906

1. 父子

.father:hover  .children{
  display: none   //  或者  display: block
}

2. 兄弟

// 网上都说是通过 .children1:hover + .children2 { display: **} 方式进行设置,亲测,无效
// 最终还是通过设置共有的父节点来设置样式的,同下
.father:hover  .children{
  display: none   //  或者  display: block
}

操作dom

// 通过jquery来判断元素的hover属性 true  false
if($("#statResourceFather").is(':hover') ) {}

 

 

this.$nextTick
this.$nextTick(()=>{
    this.form.setFieldsValue();
})

 

字体
.content{
  // font-family: 楷体;
  font-family: 宋体;
}
vue过滤器filters获取不到this对象的解决办法

https://blog.csdn.net/ZZQ928000/article/details/105141690

原理:

在data中定义一个属性that,把this存储到that中

在调用filters中的方法sum的时候将that传进去即可

 

下面举个例子用filters计算data中 a+b 的值

注意:filters中的sum方法的第一个参数是|左边那个a,第二个参数才是括号写的that

<template>
  <div>{{a|sum(that)}}</div>
</template>


<script>
  export default {
    name: "test",
    data() {
      return {
        that: this,
        a: 1,
        b: 2
      }
    },
    filters: {
      sum(a, that) {
        console.log(that);
        return a + that.b;
      }
    },
  }
</script>

 

过滤器 vue实现货币三位分隔 三元表达式中使用

$options.filters.DateDiffer(items.dqdate) 找到过滤器 中的方法并传值

:class="[$options.filters.DateDiffer(items.dqdate)<0?'tan_item1':'tan_item6']"

 

methods 同级定义 过滤器

filters:{
    MoneyFormat(money) {
        if (money && money != null) {
        money = String(money);
        var left = money.split('.')[0], right = money.split('.')[1];
        right = right ? (right.length >= 2 ? '.' + right.substr(0, 2) : '.' + right + '0') : '.00';
        var temp = left.split('').reverse().join('').match(/(\d{1,3})/g);
        return (Number(money) < 0 ? '-' : '') + temp.join(',').split('').reverse().join('') + right;
        } else if (money === 0) { // 注意===在这里的使用,如果传入的money为0,if中会将其判定为boolean类型,故而要另外做===判断
        return '0.00';
        } else {
        return '';
        }
    }
},

使用的时候在template里面使用就行了

{{price | MoneyFormat }}
过滤器 vue 计算结束日期与当前时间相差 天数 月数

https://blog.csdn.net/youyanh/article/details/109983767

filters:{
    DateDiffer(Date_end){
        //date1结束时间
        let date1 = new Date(Date_end);
        //date2当前时间
        let date2 = new Date();
        date1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
        date2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
        const diff = date1.getTime() - date2.getTime(); //目标时间减去当前时间
        const diffDate = diff / (24 * 60 * 60 * 1000);  //计算当前时间与结束时间之间相差天数
        console.log('diffDate',diffDate);
        return diffDate;
    },
},


{{items.dqdate | DateDiffer }}




//计算两个日期差值(月)(月)(月)
MonthDiffers(Date_end){
    var startDate = '2022-10-21'; //当前时间
    var endDate = '2021-12-21';
    let date1 = endDate.split('-');//例:将2020-12-21 的-去掉
    date1 = parseInt(date1[0]) * 12 + parseInt(date1[1]);//将字符串转换为数字格式
    let date2 = startDate.split('-');
    date2 = parseInt(date2[0]) * 12 + parseInt(date2[1]);
    var date = date1-date2;
},

 

常规使用方法

<div>1合同{{ $options.filters.search(items.name,items.id,that)}}{{searchVal}}</div>


:class="[searchVal&&!$options.filters.search(items.name,items.id,that)?'bg_none':'']"

基本代码

data(){
    return{
        that:this,//解决在 filters 获取 不到  this指向问题
    }
},
filters:{
    //搜索  val1 val1  分别是数据data  中的值
    search(val1,val2,that){
        if(val1.search(that.searchVal) != -1 ||val2.search(that.searchVal) != -1){
            return true
        }else{
            return false
        }
    }
}

 

vue获取当前日期时间的方法
//获取当前年月日
addDate(){
    const nowDate = new Date();
    const date = {
        year: nowDate.getFullYear(),
        month: nowDate.getMonth() + 1,
        date: nowDate.getDate(),
    }
    console.log('date.month',date.month);
    const newmonth = date.month>=10?date.month:'0'+ date.month;
    console.log('newmonth',newmonth);
    const day = date.date>=10?date.date:'0'+date.date
    this.nowDate = date.year + '-' + newmonth + '-' + day;
    console.log('this.nowDate',this.nowDate);
},
vue html日期去除时分秒 yyyy-mmm-dd变为yyyy.mm.dd
方案一:
var date = "2018-10-08 00:00:00"; 
var newDate=/\d{4}-\d{1,2}-\d{1,2}/g.exec(date)
newDate="2018-10-08";
 
方案二:
var time_str= '2014-9-19 13:19:21';
var t = time_str.substr(0,10);

在 html 中使用 2024-06-21 00:00:00到期

{{items.rent_end.substring(0,10)}},//2024-06-21




{{drawerDetail.rentStart.substring(0,10).replace(/-/g,'/')}}//2021/06/22
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            div {
                width: 249px;
                height: 300px;
                overflow: auto;
            }          
            ::-webkit-scrollbar {
                width: 6px;
                height: 6px;
            }
            /*滚动区域背景*/     
            ::-webkit-scrollbar-track-piece {
                background-color: silver;
                -webkit-border-radius: 6px;
            }  
            /*竖向滚动条*/      
            ::-webkit-scrollbar-thumb:vertical {
                height: 5px;
                background-color: yellow;
                -webkit-border-radius: 6px;
            }
            /*横向滚动条*/          
            ::-webkit-scrollbar-thumb:horizontal {
                width: 5px;
                background-color: red;
                -webkit-border-radius: 6px;
            }
        </style>
    </head>
    <body>
        <div>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
            <p>1111111111111111111111111111111</p>
        </div>
    </body>
</html>
路由 router-link 添加 参数

:to="'/profile/tenants?zoneId='+parkId" parkId 是data 中获取的数据

<router-link :to="'/profile/tenants?zoneId='+parkId" >
  <a-icon type="idcard" style="font-size: 24px; padding: 13px 0px 0px 0px; line-height: 1;" />
  <span> </span>
  <span style="margin-top: -8px;">租客</span>
</router-link>

 

 

vue 路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import Home from '../components/Home.vue'
import Request1 from '../views/request/request1'


// AntvG2 页面导入  
import AntvG2Index from '@/views/AntvG2/AntvG2Index'
import AntvG2Zhuhe from '@/views/AntvG2/AntvG2Zhuhe'
import AntvG2Welcome from '@/views/AntvG2/AntvG2Welcome'


Vue.use(VueRouter)




const router = new VueRouter({
    routes: [
        { path: '/', redirect: '/login' }, //路由的重定向
        { path: '/login', component: Login },
        { path: '/Home', component: Home },
        { path: '/Request1', component: Request1 },


        // AntvG2 页面导入
        {
            path: '/AntvG2Index',
            component: AntvG2Index,
            redirect: '/AntvG2Welcome',
            children: [{
                    path: '/AntvG2Welcome',
                    name: 'AntvG2Welcome',
                    component: AntvG2Welcome
                },
                {
                    path: '/AntvG2Zhuhe',
                    name: 'AntvG2Zhuhe',
                    component: AntvG2Zhuhe
                },
            ]
        },
        // 404 页面 路由的 书写
        {
            path: '*',
            component: () =>
                import ('@/views/404/404')
        }


    ]
})
export default router
vue 子路由的添加
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'


// 导入相关的页面 路径
import Antdv from '../views/request/antdv'
import Userlist from '../views/user/userlist'
import Workorder from '../views/work/workorder'
import Message from '../views/message/message'


Vue.use(VueRouter)


//路由的书写
const router = new VueRouter({
  routes:[
    {
      path:'/Antdv', //如果 /Antdv 是主页面 ,这其子路由 需要是 它的 children
      component:Antdv,
      redirect:'/Userlist',
      children:[  //子页面
        {
          path:'/Userlist',
          name: 'Userlist',
          component:Userlist
        },
        {
          path:'/Workorder',
          name: 'Workorder',
          component:Workorder
        },
        {
          path:'/Message',
          name: 'Message',
          component:Message
        },
      ]
    },
  ]
})


export default router
App.vue 使用路由占位
<template>
  <div id="app">
    <!-- 路由占位符 -->
     <router-view/>  
  </div>
</template>
index.vue 主页面1

<template>
  <a-layout class="layout">
    <!-- collapsed控制左侧的 展开收起的 -->
    <a-layout-sider v-model="collapsed" class="left_menu" :trigger="null" collapsible>


      <!-- 标题 logo 部分 -->
      <div class="logo" v-if="!collapsed" ><img src="https://image.haier.com/cn/images/haier2020_logo.png" alt=""></div>
      <div class="logo title" v-if="collapsed" >海尔</div>


      <!-- 菜单部分 -->
      <a-menu theme="dark" mode="inline" :default-selected-keys="['1']">
        <a-menu-item key="1">
            <!-- 配置子路由 其余放到 router-link 里面-->
            <router-link to="/Welcome">
                <a-icon type="user" />
                <span>欢迎页</span>
            </router-link>
        </a-menu-item>
        <a-menu-item key="2">
          <!-- 配置子路由 -->
            <router-link to="/Pages1">
                <a-icon type="video-camera" />
                <span>测试页1</span>
            </router-link>
        </a-menu-item>
        <a-menu-item key="3">
          <!-- 配置子路由 -->
            <router-link to="/Pages2">
                <a-icon type="upload" />
                <span>测试页2</span>
            </router-link>
        </a-menu-item>
      </a-menu>
    </a-layout-sider>
    <a-layout>


      <!-- 顶部区域 -->
      <a-layout-header style="background: #fff; padding: 0;display: flex;justify-content: space-between;padding-right: 20px;">
        <a-icon
          class="trigger"
          :type="collapsed ? 'menu-unfold' : 'menu-fold'"
          @click="() => (collapsed = !collapsed)"
        />
        <a-dropdown>
            <a class="ant-dropdown-link" @click="e => e.preventDefault()">更多<a-icon type="down" />
            </a>
            <a-menu slot="overlay">
            <a-menu-item>
                <a href="javascript:;"><a-icon type="lock" /> 修改密码</a>
            </a-menu-item>
            <a-menu-item>
                <a href="javascript:;"><a-icon type="delete" /> 注销账户</a>
            </a-menu-item>
            <a-menu-item>
                <a href="javascript:;"><a-icon type="logout" /> 退出登录</a>
            </a-menu-item>
            </a-menu>
        </a-dropdown>
      </a-layout-header>
       
      <!-- 主体区域 -->
      <a-layout-content
        :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }"
      >
        <!-- 页面 面包屑配置 -->
        <a-breadcrumb>
          <a-breadcrumb-item>首页</a-breadcrumb-item>
          <a-breadcrumb-item v-if="$route.meta.module">
              <a href="">{{$route.meta.module}}</a>
          </a-breadcrumb-item>
          <a-breadcrumb-item>{{$route.meta.title}}</a-breadcrumb-item>
        </a-breadcrumb>
        <!-- 路由占位符 -->
        <router-view></router-view>
      </a-layout-content>
    </a-layout>
  </a-layout>
</template>


<script>
export default {
  data() {
    return {
      collapsed: false,
    };
  },
  methods:{
     
  }
};
</script>


<style lang="less">
  ::-webkit-scrollbar {
      width: 6px;
      height: 6px;
  }
  /*滚动区域背景*/     
  ::-webkit-scrollbar-track-piece {
      background-color: silver;
      -webkit-border-radius: 6px;
  }  
  /*竖向滚动条*/      
  ::-webkit-scrollbar-thumb:vertical {
      height: 5px;
      background-color: #709b2c;
      -webkit-border-radius: 6px;
  }
  /*横向滚动条*/          
  ::-webkit-scrollbar-thumb:horizontal {
      width: 5px;
      background-color: red;
      -webkit-border-radius: 6px;
  }


.layout{
    height: 100vh;
    .logo{
        display: flex;
        justify-content: center;
        align-items: center;
        img{
            width: 100px;
        }
    }
    .title{
        color: #fff;
        padding: 10px 0;
        letter-spacing: 2px;
        font-family: 楷体;
        font-size: 20px;
        font-weight: bold;
    }
    .trigger {
        font-size: 18px;
        line-height: 64px;
        padding: 0 24px;
        cursor: pointer;
        transition: color 0.3s;
        &:hover{
            color: #1890ff;
        }
    }
// 控制左侧菜单 太多的时候的 上下滑动
    .left_menu{
      height: 100vh;
      overflow-y:scroll ;
    }
    .content{
        font-size: 50px;
        font-weight: bold;
        color: blue;
        letter-spacing: 2px;
        // font-family: 楷体;
        font-family: 宋体;
    }
}
</style>
index.vue 主页面2

<template>
  <a-layout class="layout">
    <!-- collapsed控制左侧的 展开收起的 -->
    <a-layout-sider v-model="collapsed" class="left_menu" :trigger="null" collapsible>
        <div class="logo" v-if="!collapsed" ><img src="http://u-park.com/static/logo-light.78fd386c.svg" alt=""></div>
        <div class="logo title flex" v-if="collapsed" >
            <img style="width: 25px;" src="http://u-park.com/static/logo-icon.a3f73e6e.svg" alt="">
        </div>
      <a-menu theme="dark" mode="inline" :default-selected-keys="['1']"
      :default-open-keys="['sub1']">
        <a-sub-menu key="sub1">
            <span slot="title"><a-icon type="user" /><span>用户管理</span></span>
                <a-menu-item key="1">用户信息</a-menu-item>
                <a-menu-item key="2">角色管理</a-menu-item>
        </a-sub-menu>
        <a-sub-menu key="sub2">
            <span slot="title"><a-icon type="form" /><span>自定义管理</span></span>
                <a-menu-item key="3">标签管理</a-menu-item>
                <a-menu-item key="4">自定义字段管理</a-menu-item>
                <a-menu-item key="5">表单模板管理</a-menu-item>
        </a-sub-menu>
      </a-menu>
      <a-icon
          class="trigger"
          :type="collapsed ? 'menu-unfold' : 'menu-fold'"
          @click="() => (collapsed = !collapsed)"
       />
    </a-layout-sider>
    <a-layout>
        <a-layout-header class="layout_header">
            <div></div>
            <div class="header_right">
                <a-dropdown placement="bottomRight">
                    <div class="layout-header_center">
                    <img src="http://u-park.com/static/default-user-avatar-male.259212fe.svg" alt="">
                    <span class="name">黑手</span>
                    </div>
                    <a-menu slot="overlay">
                    <a-menu-item @click="handleClickRouterSwitch('/zone/account')">
                        <a href="javascript:;"><a-icon type="user"/> 个人中心</a>
                    </a-menu-item>
                    <a-menu-item @click="handleLogout">
                        <a href="javascript:;"><a-icon type="logout"/> 退出登录</a>
                    </a-menu-item>
                    </a-menu>
                </a-dropdown>
                <div @click="goback" class="back">
                    <a-icon type="rollback" />
                </div>
            </div>
        </a-layout-header>
       
      <a-layout-content
        :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }"
      >
       <span class="content">主体部分</span>
      </a-layout-content>
    </a-layout>
  </a-layout>
</template>


<script>
  import { mapActions, mapGetters,mapState } from 'vuex'
  import { mixinDevice } from '@/utils/mixin.js'
  import { getFileAccessHttpUrl,getAction } from "@/api/manage"
  import Vue from 'vue'
  export default {
    props: {
      backStatus:{
          type:Boolean,  
          default:false
      },   
    },
    data() {
      return {
        collapsed: false,
      }
    },
    watch: {
     
    },
    created(){
      // 获取对应的 id 值
      const id = this.$route.query.id;
      console.log('id111',id);
    },
    methods: {
      ...mapActions(["Logout"]),
      // 路由跳转
      handleClickRouterSwitch(path) {
        this.$router.push({
          path
        })
      },
      //退出登录
      handleLogout() {
            const that = this
            this.$confirm({
            title: '提示',
            content: '真的要注销登录吗 ?',
            onOk() {
                return that.Logout({}).then(() => {
                // update-begin author:wangshuai date:20200601 for: 退出登录跳转登录页面
                that.$router.push({ path: '/user/login' });
                window.location.reload()
                // update-end author:wangshuai date:20200601 for: 退出登录跳转登录页面
                }).catch(err => {
                that.$message.error({
                    title: '错误',
                    description: err.message
                })
                })
            },
            onCancel() {
            },
            });
      },
      // 返回上一页
      goback(){
        this.$router.back();
      },
      //关闭右侧菜单
      toggleCollapsed() {
        this.collapsed = !this.collapsed;
      },
    }
  }
</script>


<style lang="less">


.layout{
    height: 100vh;
    .logo{
        display: flex;
        justify-content: flex-start;    
        align-items: center;
        padding: 15px 10px;
        img{
            width: 100px;
        }
    }
    .flex{
        display: flex;
        justify-content: center;
    }
    .title{
        color: #fff;
        padding: 10px 0;
        letter-spacing: 2px;
        font-family: 楷体;
        font-size: 20px;
        font-weight: bold;
    }
    .trigger {
        font-size: 18px;
        line-height: 64px;
        padding: 0 24px;
        cursor: pointer;
        color:#fff;
        position: fixed;
        left: 0;
        bottom: 0;
        transition: color 0.3s;
        &:hover{
            color: #1890ff;
            background: rgba(0, 0, 0, 0);
        }
    }
    .content{
        font-size: 50px;
        font-weight: bold;
        color: blue;
        letter-spacing: 2px;
        // font-family: 楷体;
        font-family: 宋体;
    }
}
.left_menu{
    height: 100vh;
    overflow-y:scroll ;
}
.layout-header_center{
  display: flex;
  align-items: center;
  width: 80px;
}
.layout-header_center img{
  display: block;
  width: 25px;
  height: 25px;
  object-fit: cover;
}
.layout-header_center .name{
  margin-left: 10px;
  cursor: pointer;
  color: rgb(0, 0, 0);
  line-height: 48px;
  font-size: 14px;
}
.option{
  cursor: pointer;
}
.option:hover{
  background: #f5f5f5;
}
.layout_header{
    background: #fff; 
    padding: 0;
    display: flex;
    justify-content: space-between;
    height: 48px;
    padding-right: 0px;
}
.header_right{
    display: flex;
}


/* 右侧返回按钮 */
.back{
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    padding: 0 12px;
    color: #fff;
    background: #1890ff;
    cursor: pointer;
    transition: all .3s;
    &:hover{
        background: #40a9ff;
    }
}
</style>
index.vue 主页面3

 

<template>
  <a-layout class="layout">
    <!-- collapsed控制左侧的 展开收起的 -->
    <a-layout-sider v-model="collapsed" class="left_menu" theme="light" :trigger="null" collapsible>
        <div class="logo title flex">
            <img style="width: 25px;" src="http://u-park.com/static/logo-icon.a3f73e6e.svg" alt="">
        </div>
      <a-menu style="margin-top:20px;" theme="light" mode="inline" :default-selected-keys="['1']"
      :default-open-keys="['sub1']">


      <a-menu-item key="1" style="display: flex; flex-direction: column; align-items: center; height: 70px;">
        <a-icon type="bank" style="font-size: 24px; padding: 13px 0px 0px 0px; line-height: 1;" />
        <span> </span>
        <span style="margin-top: -8px;">园区</span>
      </a-menu-item>


      <a-menu-item key="2" style="display: flex; flex-direction: column; align-items: center; height: 70px;">
        <a-icon type="idcard" style="font-size: 24px; padding: 13px 0px 0px 0px; line-height: 1;" />
        <span> </span>
        <span style="margin-top: -8px;">租客</span>
      </a-menu-item>
      <a-menu-item key="3" style="display: flex; flex-direction: column; align-items: center; height: 70px;">
        <a-icon type="file-done" style="font-size: 24px; padding: 13px 0px 0px 0px; line-height: 1;" />
        <span> </span>
        <span style="margin-top: -8px;">合同</span>
      </a-menu-item>
      </a-menu>
    </a-layout-sider>
    <a-layout>
        <a-layout-header class="layout_header">
            <div></div>
            <div class="header_right">
                <a-dropdown placement="bottomRight">
                    <div class="layout-header_center">
                    <img src="http://u-park.com/static/default-user-avatar-male.259212fe.svg" alt="">
                    <span class="name">黑手</span>
                    </div>
                    <a-menu slot="overlay">
                    <a-menu-item @click="handleClickRouterSwitch('/zone/account')">
                        <a href="javascript:;"><a-icon type="user"/> 个人中心</a>
                    </a-menu-item>
                    <a-menu-item @click="handleLogout">
                        <a href="javascript:;"><a-icon type="logout"/> 退出登录</a>
                    </a-menu-item>
                    </a-menu>
                </a-dropdown>
                <div @click="goback" class="back">
                    <a-icon type="rollback" />
                </div>
            </div>
        </a-layout-header>
       
      <a-layout-content
        :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }"
      >
       <span class="content">主体部分</span>
       <Fonts style="color:orange;font-size:30px;" type='icon-qiyeyuanquwuye-xianxing'/>
      </a-layout-content>
    </a-layout>
  </a-layout>
</template>


<script>
  import { mapActions, mapGetters,mapState } from 'vuex'
  import { mixinDevice } from '@/utils/mixin.js'
  import { getFileAccessHttpUrl,getAction } from "@/api/manage"
  import Vue from 'vue';


  // 引入 阿里 图标
  import { Icon } from 'ant-design-vue';
  const Fonts = Icon.createFromIconfontCN({
    scriptUrl: '//at.alicdn.com/t/font_2875819_dl629sjtmb.js'
  });
  export default {
    components:{
      Fonts
    },
    props: {
      backStatus:{
          type:Boolean,  
          default:false
      },   
    },
    data() {
      return {
        collapsed: true,
      }
    },
    watch: {
     
    },
    created(){
      // 获取对应的 id 值
      const id = this.$route.query.id;
      console.log('id111',id);
    },
    methods: {
      ...mapActions(["Logout"]),
      // 路由跳转
      handleClickRouterSwitch(path) {
        this.$router.push({
          path
        })
      },
      //退出登录
      handleLogout() {
            const that = this
            this.$confirm({
            title: '提示',
            content: '真的要注销登录吗 ?',
            onOk() {
                return that.Logout({}).then(() => {
                // update-begin author:wangshuai date:20200601 for: 退出登录跳转登录页面
                that.$router.push({ path: '/user/login' });
                window.location.reload()
                // update-end author:wangshuai date:20200601 for: 退出登录跳转登录页面
                }).catch(err => {
                that.$message.error({
                    title: '错误',
                    description: err.message
                })
                })
            },
            onCancel() {
            },
            });
      },
      // 返回上一页
      goback(){
        this.$router.back();
      },
      //关闭右侧菜单
      toggleCollapsed() {
        this.collapsed = !this.collapsed;
      },
    }
  }
</script>


<style lang="less">


.layout{
    height: 100vh;
    .logo{
        display: flex;
        justify-content: flex-start;    
        align-items: center;
        padding: 15px 10px;
        img{
            width: 100px;
        }
    }
    .flex{
        display: flex;
        justify-content: center;
    }
    .title{
        color: #fff;
        padding: 10px 0;
        letter-spacing: 2px;
        font-family: 楷体;
        font-size: 20px;
        font-weight: bold;
    }
    .trigger {
        font-size: 18px;
        line-height: 64px;
        padding: 0 24px;
        cursor: pointer;
        color:#fff;
        position: fixed;
        left: 0;
        bottom: 0;
        transition: color 0.3s;
        &:hover{
            color: #1890ff;
            background: rgba(0, 0, 0, 0);
        }
    }
    .content{
        font-size: 50px;
        font-weight: bold;
        color: blue;
        letter-spacing: 2px;
        // font-family: 楷体;
        font-family: 宋体;
    }
}
.left_menu{
    height: 100vh;
    overflow-y:scroll ;
}
.layout-header_center{
  display: flex;
  align-items: center;
  width: 80px;
}
.layout-header_center img{
  display: block;
  width: 25px;
  height: 25px;
  object-fit: cover;
}
.layout-header_center .name{
  margin-left: 10px;
  cursor: pointer;
  color: rgb(0, 0, 0);
  line-height: 48px;
  font-size: 14px;
}
.option{
  cursor: pointer;
}
.option:hover{
  background: #f5f5f5;
}
.layout_header{
    background: #fff; 
    padding: 0;
    display: flex;
    justify-content: space-between;
    height: 48px;
    padding-right: 0px;
}
.header_right{
    display: flex;
}


/* 右侧返回按钮 */
.back{
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    padding: 0 12px;
    color: #fff;
    background: #1890ff;
    cursor: pointer;
    transition: all .3s;
    &:hover{
        background: #40a9ff;
    }
}


</style>
上方面包屑的 路由配置
{
path: '/Antdvindex', //如果 /Antdvindex 是主页面 ,这其子路由 需要是 它的 children
component: Antdvindex,
redirect: '/Antdvindex',
children: [{
        path: '/Workorder',
        name: 'Workorder',
        component: Workorder,
        meta: {
            title: '工作平台'  //没有 展开页
        }
    },
    {
        path: '/Userlist',
        name: 'Userlist',
        component: Userlist,
        meta: {
            module: '员工管理', //主展开页
            title: '员工列表'   //子展开页
        }
    },
    {
        path: '/Message',
        name: 'Message',
        component: Message,
        meta: {
            module: '员工管理',
            title: '信息管理'
        }
    },
]
},
面包屑组件的 封装

 <div>
    <!-- 页面 面包屑配置 -->
    <a-breadcrumb>
        <a-breadcrumb-item>首页</a-breadcrumb-item>
        <a-breadcrumb-item v-if="$route.meta.module">
            <a href="">{{$route.meta.module}}</a>
        </a-breadcrumb-item>
        <a-breadcrumb-item>{{$route.meta.title}}</a-breadcrumb-item>
    </a-breadcrumb>
  </div>

使用

<!-- 面包屑组件 -->
<Bread />


<script>
import Bread from '../../components/Bread.vue'
export default {
  name:'Antdv',
  components:{
    Bread
  },
</script>

 

 

一种是直接在main.js中引入(也可以在其他的.vue文件中的<script></script>标签中),即下面这种写法:

<script>
import "@/assets/css/login.css";
export default {}


<script>
import swiper from './swiper.js'
import common from '../common.vue'
export default {}
命名 插槽的组件slot的使用

父组件 slot="right"

<freeListItem :showLeftICon="false" @click="click" borderBottom title="消息免打扰" showRight size="50">
	<switch checked="true" slot="right" @change="" />
</freeListItem>

子组件 name="right"

<view class="flex align-center" v-if="showRight">
	<slot name="right" ></slot>
	<!-- 右箭头 -->
	<text class="iconfont icon-youjiantou font-md pr-3"></text>
</view>
vue中引入 图片
<img src="@/assets/images/6bf09f9948c3044dbb2c7ed8b85098dc.png" alt="/>
Message 全局提示
// message.success(content, [duration], onClose)
// content 消息提示的内容,2 duration秒时间,onClose 关闭时触发的回调函数 
this.$message.success('恭喜您登录成功!!!',2,()=>{
    this.$router.push({path})
});

1、标签跳转

<router-link to='two.html'><button>点我到第二个页面</button></router-link>


<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>

2、点击事件跳转

<button @click="hreftwo" class="test-one">点我到第二个页面</button>

 

<p @click="handleClickRouterSwitch('/zone/account')" class="option"><a-icon type="user" style="margin-right: 10px;" />个人中心</p>


methods:{ //跳转页面
  // 路由跳转 
  handleClickRouterSwitch(path) {
    this.$router.push({
      path
    })
  },
}
vue路由传参的三种基本方式

https://www.jianshu.com/p/d276dcde6656

先有如下场景 点击当前页的某个按钮跳转到另外一个页面去,并将某个值带过去

<div class="examine" @click="insurance(2)">查看详情</div>
第一种方法 页面刷新数据不会丢失
methods:{
  insurance(id) {
       //直接调用$router.push 实现携带参数的跳转
        this.$router.push({
          path: `/particulars/${id}`,
        })
}

需要对应路由配置如下:

{
 path: '/particulars/:id',
 name: 'particulars',
 component: particulars
}

可以看出需要在path中添加/:id来对应 $router.push 中path携带的参数。在子组件中可以使用来获取传递的参数值

另外页面获取参数如下

this.$route.params.id
第二种方法 页面刷新数据会丢失

通过路由属性中的name来确定匹配的路由,通过params来传递参数。

methods:{
  insurance(id) {
       this.$router.push({
          name: 'particulars',
          params: {
            id: id
          }
        })
  }

对应路由配置: 注意这里不能使用:/id来传递参数了,因为组件中,已经使用params来携带参数了。

 {
     path: '/particulars',
     name: 'particulars',
     component: particulars
   }

子组件中: 这样来获取参数

this.$route.params.id
第三种方法
<a-card :bodyStyle="cardStyle" @mouseenter="enter(index)" 


@click="handleClickRouterSwitch('/profile',item.id)"  


class="left_card" hoverable v-for="(item,index) in summaryInfoList" :key="index">

使用path来匹配路由,然后通过query来传递参数

这种情况下 query传递的参数会显示在url后面?id=?

// 跳转详情
handleClickRouterSwitch(path,val) {
  console.log('776776678678678',path,val);
  this.$router.push({
    path,
    query: {
      id: val
    }
  })
},

对应路由配置:

{
 path: '/particulars',
 name: 'particulars',
 component: particulars
}

对应子组件: 这样来获取参数

this.$route.query.id

特别注意哦,

组件中 获取参数的时候是router 这很重要~~~

 

vue返回上一页

https://www.cnblogs.com/lgnblog/p/9957661.html

https://blog.csdn.net/weixin_43970743/article/details/88578609

 1.在当前页面添加返回按钮

<div style="text-align: center">
  <el-button v-on:click="backHistory">取消</el-button>
</div>

2.在方法体内写back方法实现点击返回上一页操作

methods:{
  backHistory(){
    this.$router.go(-1);//返回上一层
  },
},  

总结:

this.$router.go(val) => 在history记录中前进或者后退val步,当val为0时刷新当前页面、-1即为返回上一页;

https://blog.csdn.net/weixin_46419373/article/details/106106166?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

this.$router.back();

强制刷新当前页面
this.$router.go(0);
location.reload()
页面 顶部 LoadingBar 加载进度的 实现

//App.vue 页面 样式

<style scope>
#global_loading {
    background: linear-gradient(to right, #1890ff, rgb(164, 143, 223), rgb(0, 238, 255));
    height: 3px;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 99999;
    width: 0;
    animation: grow 1s infinite forwards;
}
@keyframes grow {
    from {
        width: 0;
    }
    to {
        width: 100%;
    }
}
</style>

//router/index.js 页面

// 导航首位   路由跳转前  效果
router.beforeEach((to, from, next) => {
        // 判断 是否存在LoadingBar 加载进度条  不存在就创建
        let loadingBar = document.getElementById('global_loading')
        if (!loadingBar) {
            loadingBar = document.createElement('div')
            loadingBar.id = 'global_loading'
            document.body.append(loadingBar)
        } else {
            loadingBar.style.display = 'block'
        }
        document.title = '海尔管理后台 - ' + to.meta.title;
        setTimeout(() => {
            next()
        }, 300);
    })
    // 导航首位   路由跳转后  效果
router.afterEach((to, from) => {
    // 隐藏 LoadingBar 加载进度条
    let loadingBar = document.getElementById('global_loading')
    if (loadingBar) {
        loadingBar.style.display = 'none'
    }
})


export default router
ant-design-vue自定义使用阿里iconfont图标

https://www.cnblogs.com/huoshengmiao/p/15118512.html

第一步:从iconfont获取项目js链接

第二步 在需要引用iconfont的页面处加入
<Fonts style="color:blue;font-size:30px;" type='icon-qiyeyuanquwuye-xianxing'/>

 

// 引入 阿里 图标
import { Icon } from 'ant-design-vue';
const Fonts = Icon.createFromIconfontCN({
  scriptUrl: '//at.alicdn.com/t/font_2875819_dl629sjtmb.js'
});
export default {
  components:{
    Fonts
  },

效果:

基于Ant Design Vue的省市区级联选择组件应用

https://www.jianshu.com/p/731d1b27f51d

对于省市区级联选择,很多做法都是通过一级一级的调用服务端接口来实现的,今天介绍一个完全采用前端、基于Ant Design Vue来构建的省市区级联选择组件。

一、准备省市区数据

1、下载省市区数据

省市区JSON数据 可直接使用的直接替换即可

2、将省市区数据保存到areadata.js文件中,并导出

//地区json数据
export default [
    {
        code: "11",
        name: "北京市",
        children: [
            {
                code: "1101",
                name: "市辖区",
                children: [
                    {
                        code: "110101",
                        name: "东城区"
                    },
                    {
                        code: "110102",
                        name: "西城区"
...
二、基于Cascader包装成省市区组件 组件 的封装
<template>
  <a-cascader
    :fieldNames="{ label: 'name', value: 'code', children: 'children' }"
    :options="areaData"
    :placeholder="placeholder"
    v-model="selectedValues"
    @change="onChange"
  />
</template>
<script>
import areaData from "./areadata";
export default {
  name: "areaSelect",
  props: {
    placeholder: {
      type: String,
      default: "请选择省市区",
    },
    defaultValue: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  data() {
    return {
      //地区数据
      areaData,
      //选择的数据
      selectedValues: [],
    };
  },
  created() {
    if (this.defaultValue.length) {
      this.selectedValues = [...this.defaultValue];
    }
  },
  watch: {
    defaultValue(newValue) {
      if (newValue.length) {
        this.selectedValues = newValue;
      } else {
        this.selectedValues = [];
      }
    },
  },
  methods: {
    //选择好之后的回调
    onChange(value) {
      this.$emit("change", value);
    },
  },
};
</script>
<style lang="scss" scoped>
</style>
三、使用该组件
<template>
  <div>
    <!-- 省市区选择器 -->
    <area-select
      @change="selectArea"
      :default-value="defaultArea"
    />
  </div>
</template>
<script>
//导入构建好的组件
import areaSelect from "./areaselect";
export default {
  components: {
    areaSelect,
  },
  data() {
    return {
      //配置默认选中的省市区(依次是省市区的区域代码)
      defaultArea:['32','3205','320571'],
    };
  },
  methods: {
    //选择地区之后的回调
    selectArea(selectedArea) {
      console.log(selectedArea);
    },
  },
};
</script>
<style lang="scss" scoped>
</style>
四、效果

Vue 拖拽组件 vuedraggable

http://www.ptbird.cn/vue-draggable-dragging.html

https://www.jianshu.com/p/e8ff1e1cafb1

https://www.itxst.com/vue-draggable/tutorial.html

1.在项目中总会遇见一些需要排序的数据 , 我们可以通过vue.draggable 进行拖动排序 。

2.Draggable为基于Sortable.js的vue组件,用以实现拖拽功能。

3.拖顶的数据和data里的数据为双向绑定 ,在界面变的时候data中的数据也在跟着变化。

安装
npm i -S vuedraggable
页面引入
import draggable from "vuedraggable"
定义组件
components: {
   draggable
},

效果展示

页面使用

<draggable
  class="syllable_ul"
  element="ul"
  :list="syllable"
  :options="{group:'title', animation:150}"
  :no-transition-on-drag="true"
  @change="change"
  @start="start"
  @end="end"
  :move="move"
>
  <transition-group type="transition"  :name="!drag? 'syll_li' : null" :css="true">
    <li v-for="(item , idx) in syllable" :key="idx">{{item.title}}</li>
  </transition-group>
</draggable>

事件

//evt里面有两个值,一个evt.added 和evt.removed  可以分别知道移动元素的ID和删除元素的ID
  change(evt) {
    console.log(evt , 'change...')
  },
  //start ,end ,add,update, sort, remove 得到的都差不多
  start(evt) {
    this.drag = true
    console.log(evt , 'start...')
  },
  end(evt) {
    console.log(evt , 'end....')
    this.drag = true
    evt.item //可以知道拖动的本身
    evt.to    // 可以知道拖动的目标列表
    evt.from  // 可以知道之前的列表
    evt.oldIndex  // 可以知道拖动前的位置
    evt.newIndex  // 可以知道拖动后的位置
  },
  move(evt, originalEvent) {
    console.log(evt , 'move')
    console.log(originalEvent) //鼠标位置
  }
属性和方法说明

属性( Attributes)

draggable的属性:

参数

说明

可选值

默认值

value

用于实现拖拽的list,通常和内部v-for循环的数组为同一数组

Array,非必须

null

list

就是value的替代品。从表现上没有看出不同

Array,非必须

null

element

<draggable>标签在渲染后展现出来的标签类型 ,可以用来兼容UI组件

String,

div

options

配置项对象 下面有详细解释

Object

 


 

动态计算 绑定 宽度 width

<a-col @click.stop="showDrawer" :class="[(disStatus&&disIndex!=index)||(items.area<minArea&&minArea)||(items.area>maxArea&&maxArea)?'bg_none':'']" :style="{ width: 1210 / 1000 * items.area + '%'}" v-for="(items,indexs) in item.data" :key="indexs">

 

//原始数组
{
  name:'周鹏程',
  id:'1104',
  area:'110',
  check:false,
  business:false,
  dqdate:'2021/12/30',
},


// 搜索 事件
onSearch(value) {
    console.log(value);
    var newArr2 = [];
    newArr.forEach((v,i) => {
      //搜索的关键字与 数据中的name  id  匹配
      if(v.name.search(value) != -1 ||v.id.search(value) != -1){
          newArr2.push(v);
      }
    });
    console.log('newArr2',newArr2);  //输出符合条件的数组元素
},
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read properties of null (reading 'search')"

一般时这个.对象没有值,需要进行判空处理

//搜索
search(val1,val2,that){
    if(val1){
         if(val1.search(that.searchVal) != -1 ||val2.search(that.searchVal) != -1 ){
        return true
        }else{
            return false
        }
    }
}

 

数组元素求和

arr1 (2) [440, 295]

// 统计选中面积求和
var arr1 =  [];
this.checkedArr.forEach(v=>{
    arr1.push(v.area)
})
this.allArea =eval(arr1.join("+"));

 

 

Jeecj Boot

http://doc.jeec g.com/2044015

JDate 日期组件的使用
<template>
    <div>
        <j-date v-model="dateStr" placeholder="请输入日期" showTime dateFormat="YYYY-MM-DD HH:mm:ss"></j-date>
    </div>
</template>


<script>
import JDate from '@/components/jeecg/JDate'
import { component } from 'vuedraggable'
export default {
    data() {
        name:'Changelog'
        component:{
            JDate
        }
        return{
            dateStr:''
        }
    },
}
</script>

 

 
 

 

posted @ 2021-11-02 22:33  行者_Panda  阅读(949)  评论(0)    收藏  举报