perf(layer): 初步集成 layer 弹层, 新增 useMove 拖拽 hooks

This commit is contained in:
就眠仪式 2021-11-01 01:02:21 +08:00
parent 5aa3544914
commit 32a2500d67
53 changed files with 925 additions and 210 deletions

View File

@ -74,7 +74,7 @@ export default {
::: title 动画类名
:::
| Name | Description | Accepted Values |
| 类名 | 描述 | 使用 |
| --------------------------------- | ------------ | ---------------------------------------------- |
| layui-anim-down | 顶部往下滑入 | `layui-anim layui-anim-down` |
| layui-anim-downbit | 微微往下滑入 | `layui-anim layui-anim-downbit` |

View File

@ -83,7 +83,7 @@ export default {
::: title 头像属性
:::
| | | |
| 属性 | 描述 | 可选值 |
| ------ | ---- | -------------- |
| src | 图源 | -- |
| size | 尺寸 | `xs` `sm` `lg` |

View File

@ -82,13 +82,13 @@ export default {
::: title 面包屑属性
:::
| Name | Description | Accepted Values |
| --------- | ----------- | --------------- |
| 属性 | 描述 | 默认值 |
| --------- | ------ | ------ |
| separator | 分割符 | `/` |
::: title 面包屑插槽
:::
| Name | Description | Accepted Values |
| ------- | ----------- | --------------- |
| 插槽 | 描述 | 默认值 |
| ------- | -------- | ------ |
| default | 默认插槽 | `--` |

View File

@ -252,13 +252,48 @@ export default {
:::
::: title 事件处理
:::
::: demo 使用 @click 设置单击回调
<template>
<lay-button type="default" @click="clickHandle">单击事件</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const clickHandle = function() {
console.log('点击事件')
}
return {
clickHandle
}
}
}
</script>
:::
::: title 按钮属性
:::
| Name | Description | Accepted Values |
| ------ | ----------- | --------------------------------------------- |
| 属性 | 描述 | 可选值 |
| ------ | ------ | --------------------------------------------- |
| type | 主题 | `primary` `normal` `warm` `danger` `disabled` |
| size | 尺寸 | `lg` `sm` `xs` |
| fluid | 最大化 | `true` `false` |
| radius | 圆角 | `true` `false` |
| border | 边框 | `green` `blue` `orange` `red` `black` |
::: title 按钮事件
:::
| 事件 | 描述 | 参数 |
| ----- | -------- | ---- |
| click | 单击事件 | `--` |

View File

@ -108,14 +108,14 @@ export default {
::: title 卡片属性
:::
| | | |
| ----- | ---- | --- |
| 属性 | 描述 | 可选值 |
| ----- | ---- | ------ |
| title | 标题 | -- |
::: title 卡片插槽
:::
| | | |
| ------ | -------- | --- |
| 插槽 | 描述 | 可选值 |
| ------ | -------- | ------ |
| header | 头部插槽 | -- |
| body | 内容插槽 | -- |

View File

@ -119,7 +119,7 @@ export default {
::: title 轮播属性
:::
| Name | Description | Accepted Values |
| 属性 | 描述 | 可选值 |
| --------- | ------------ | ------------------------- |
| v-model | 当前激活项 | `--` |
| anim | 切换方向 | `default` `updown` |
@ -129,6 +129,6 @@ export default {
::: title 轮播事件
:::
| Name | Description | Accepted Values |
| ------ | ----------- | --------------- |
| 事件 | 描述 | 可选值 |
| ------ | -------- | ------ |
| change | 切换回调 | id |

View File

@ -149,13 +149,20 @@ export default {
:::
::: title checkbox 属性
::: title 复选框属性
:::
| Name | Description | Accepted Values |
| 属性 | 描述 | 可选值 |
| ------------------- | ------------- | -------------------- |
| name | 原始属性 name | -- |
| skin | 主题 | -- |
| label | 选中值 | -- |
| checked ( v-model ) | 是否选中 | `true` `false` |
| change | 切换事件 | isChecked : 当前状态 |
::: title 复选框事件
:::
| 事件 | 描述 | 可选值 |
| ------ | -------- | -------------------- |
| change | 切换事件 | isChecked : 当前状态 |

View File

@ -143,3 +143,16 @@ export default {
</script>
:::
::: title 颜色说明
:::
| Class | 描述 | 使用 |
| --------------- | ---- | ----------------------- |
| layui-bg-red | 赤色 | class="layui-bg-red" |
| layui-bg-orange | 橙色 | class="layui-bg-orange" |
| layui-bg-green | 墨绿 | class="layui-bg-green" |
| layui-bg-cyan | 藏青 | class="layui-bg-cyan" |
| layui-bg-blue | 蓝色 | class="layui-bg-blue" |
| layui-bg-black | 雅黑 | class="layui-bg-black" |

View File

@ -68,6 +68,6 @@ export default {
::: title 容器属性
:::
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| 属性 | 描述 | 可选值 |
| ----- | ------ | -------------- |
| fluid | 流模式 | `true` `false` |

View File

@ -67,16 +67,16 @@ export default {
:::
::: title Dropdown 属性
::: title 下拉属性
:::
| Name | Description | Accepted Values |
| ------- | ----------- | --------------- |
| 属性 | 描述 | 可选值 |
| ------- | -------- | --------------- |
| trigger | 触发方式 | `click` `hover` |
::: title Dropdown 插槽
::: title 下拉插槽
:::
| Name | Description | Accepted Values |
| ------- | ----------- | --------------- |
| 插槽 | 描述 | 可选值 |
| ------- | -------- | ------ |
| content | 下拉内容 | -- |

View File

@ -45,9 +45,8 @@ export default {
:::
::: title empty 属性
:::
| Name | Description | Accepted Values |
| ----------- | ----------- | --------------- |
| 属性 | 描述 | 可选值 |
| ----------- | -------- | ------ |
| description | 描述信息 | -- |

View File

@ -137,24 +137,22 @@ export default {
:::
::: title 行属性
:::
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| space | 间隔 | -- |
| 属性 | 描述 | 可选值 |
| ----- | ---- | ------ |
| space | 间隔 | 0 - 30 |
::: title 列属性
:::
| Name | Description | Description Info | Accepted Values |
| -------- | ----------- | ----------------------- | --------------- |
| xs | 尺寸 | 超小屏幕 (手机<768px) | 12 |
| sm | 尺寸 | 小屏幕 (平板 ≥768px) | 12 |
| md | 尺寸 | 中等屏幕 (桌面 ≥992px) | 12 |
| lg | 尺寸 | 大型屏幕 (桌面 ≥1200px) | 12 |
| xsOffset | 偏移 | 超小屏幕 (手机<768px) | 12 |
| smOffset | 偏移 | 小屏幕 (平板 ≥768px) | 12 |
| mdOffset | 偏移 | 中等屏幕 (桌面 ≥992px) | 12 |
| lgOffset | 偏移 | 大型屏幕 (桌面 ≥1200px) | 12 |
| 属性 | 描述 | 可选值 |
| --------- | ------------------------------ | ------ |
| xs | 尺寸 - 超小屏幕 (手机<768px) | 0 - 12 |
| sm | 尺寸 - 小屏幕 (平板 ≥768px) | 0 - 12 |
| md | 尺寸 - 中等屏幕 (桌面 ≥992px) | 0 - 12 |
| lg | 尺寸 - 大型屏幕 (桌面 ≥1200px) | 0 - 12 |
| xs-offset | 偏移 - 超小屏幕 (手机<768px) | 0 - 12 |
| sm-offset | 偏移 - 小屏幕 (平板 ≥768px) | 0 - 12 |
| md-offset | 偏移 - 中等屏幕 (桌面 ≥992px) | 0 - 12 |
| lg-offset | 偏移 - 大型屏幕 (桌面 ≥1200px) | 0 - 12 |

View File

@ -1107,8 +1107,8 @@ export default {
::: title 图标属性
:::
| Name | Description | Default Value |
| ------ | ----------- | ----------------- |
| 属性 | 描述 | 默认值 |
| ------ | ---- | ----------------- |
| type | 图标 | `layui-icon-home` |
| prefix | 前缀 | `layui-icon` |
| color | 颜色 | -- |

View File

@ -103,15 +103,21 @@ export default {
:::
::: title input 属性
::: title 输入框属性
:::
| Name | Description | Accepted Values |
| ----------- | --------------- | ---------------- |
| 属性 | 描述 | 可选值 |
| ----------- | ------------- | -------------- |
| name | 原始属性 name | -- |
| placeholder | 提示信息 | -- |
| disabled | 禁用 | `true` `false` |
| v-model | 值 | -- |
::: title 输入框属性
:::
| 事件 | 描述 | 参数 |
| ----- | --------------- | ---------------- |
| input | 原生 input 事件 | event : 事件对象 |
| foucs | 原生 foucs 事件 | event : 事件对象 |
| blur | 原生 blur 事件 | -- |

View File

@ -0,0 +1,226 @@
::: title 基本使用
:::
::: demo
<template>
<lay-button @click="changeVisible1" type="primary">简单使用</lay-button>
<lay-layer title="身如不系之舟" v-model:visible="visible1">
<div style="padding: 20px;">
忘了是怎么开始, 也许就是对你
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible1 = ref(false)
const changeVisible1 = function() {
visible1.value = !visible1.value
}
return {
visible1
};
},
};
</script>
:::
::: title 允许拖动
:::
::: demo
<template>
<lay-button @click="changeVisible2" type="primary">允许拖动</lay-button>
<lay-layer title="身如不系之舟" v-model:visible="visible2" move="true">
<div style="padding: 20px;">
忘了是怎么开始, 也许就是对你
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible2 = ref(false)
const changeVisible2 = function() {
visible2.value = !visible2.value
}
return {
visible2
};
},
};
</script>
:::
::: title 放大缩小
:::
::: demo
<template>
<lay-button @click="changeVisible3" type="primary">放大缩小</lay-button>
<lay-layer title="平胸女子" v-model:visible="visible3" move="true" maxmin="true">
<div style="padding: 20px;">
她是照相只照半边的女子
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible3 = ref(false)
const changeVisible3 = function() {
visible3.value = !visible3.value
}
return {
visible3
};
},
};
</script>
:::
::: title 指定位置
:::
::: demo
<template>
<lay-button @click="changeVisible4" type="primary">指定位置</lay-button>
<lay-layer title="亦是此间少年" v-model:visible="visible4" move="true" :offset="['100px','100px']">
<div style="padding: 20px;">
暗恋是一个人的事
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible4 = ref(false)
const changeVisible4 = function() {
visible4.value = !visible4.value
}
return {
visible4
};
},
};
</script>
:::
::: title 远程窗体
:::
::: demo
<template>
<lay-button @click="changeVisible5" type="primary">远程窗体</lay-button>
<lay-layer title="亦是此间少年" width="500px" height="400px" v-model:visible="visible5" move="true" :type="type5" content="http://www.pearadmin.com"></lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const type5 = ref(2)
const visible5 = ref(false)
const changeVisible5 = function() {
visible5.value = !visible5.value
}
return {
type5,
visible5
};
},
};
</script>
:::
::: title 定义操作
:::
::: demo
<template>
<lay-button @click="changeVisible6" type="primary">定义操作</lay-button>
<lay-layer title="亦是此间少年" v-model:visible="visible6" move="true" :btn="btn6">
<div style="padding: 20px;">
你喜欢我吗?
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible6 = ref(false)
const btn6 = [
{text:'确认', callback: ()=>{ alert("确认事件") }},
{text:'取消', callback: ()=>{ alert("取消事件") }}
]
const changeVisible6 = function() {
visible6.value = !visible6.value
}
return {
btn6,
visible6
};
},
};
</script>
:::
::: title 弹层属性
:::
| 备注 | 描述 | 默认值 |
| --------------- | ------------- | ------- |
| title | 标题 | -- |
| move | 允许拖拽 | `false` |
| maxmin | 最小化 最大化 | `false` |
| offset | 位置 | -- |
| width | 宽 | -- |
| height | 高 | -- |
| v-model:visible | 展示 隐藏 | false |
| content | 内容 | -- |

View File

@ -172,7 +172,7 @@ export default {
::: title 布局组件
:::
| | | |
| 组件 | 描述 | |
| ---------- | ---- | --- |
| lay-layout | 容器 | -- |
| lay-header | 顶部 | -- |

View File

@ -80,14 +80,14 @@ export default {
::: title 菜单属性
:::
| Name | Description | Accepted Values |
| --------------------- | ----------- | --------------- |
| 属性 | 描述 | 备注 |
| --------------------- | ------ | ---- |
| selectedKey (v-model) | 选中项 | -- |
| openKeys (v-model) | 打开项 | -- |
::: title 菜单插槽
:::
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| 插槽 | 描述 | 备注 |
| ----- | -------- | ---- |
| title | 菜单标题 | -- |

View File

@ -196,7 +196,7 @@ export default {
::: title 分页属性
:::
| | | |
| 属性 | 描述 | 默认值 |
| ----------- | ------------ | ------- |
| limit | 每页数量 | -- |
| total | 总条数 | -- |
@ -209,14 +209,14 @@ export default {
::: title 分页事件
:::
| | | |
| 事件 | 描述 | 参数 |
| ---- | -------- | --------------------- |
| jump | 切换回调 | { current: 当前页面 } |
::: title 分页插槽
:::
| | | |
| 插槽 | 描述 | 默认值 |
| ---- | ------ | ------ |
| prev | 上一页 | 上一页 |
| next | 下一页 | 下一页 |

View File

@ -24,6 +24,6 @@ export default {
::: title 面板插槽
:::
| Name | Description | Accepted Values |
| ------- | ----------- | --------------- |
| 插槽 | 描述 | 可选值 |
| ------- | -------- | ------ |
| default | 默认插槽 | -- |

View File

@ -110,10 +110,10 @@ export default {
:::
::: title Progress 属性
::: title 进度属性
:::
| | | |
| 属性 | 描述 | 可选值 |
| -------- | -------- | --------------------------------------------- |
| percent | 进度 | -- |
| theme | 主题 | `orange` `green` `cyan` `blue` `black` `gray` |

View File

@ -94,12 +94,18 @@ export default {
:::
::: title radio 属性
::: title 单选框属性
:::
| Name | Description | Accepted Values |
| ------- | ------------- | ---------------- |
| 属性 | 描述 | 默认值 |
| ------- | ------------- | ------ |
| name | 原始属性 name | -- |
| label | 当前值 | -- |
| v-model | 选中值 | -- |
::: title 单选框事件
:::
| 事件 | 描述 | 参数 |
| ------ | -------- | ---------------- |
| change | 切换事件 | current : 当前值 |

View File

@ -134,8 +134,8 @@ export default {
::: title 评分属性
:::
| | | |
| -------- | -------- | --- |
| 属性 | 描述 | 默认值 |
| -------- | -------- | ------ |
| v-model | 评分值 | -- |
| length | 评分长度 | -- |
| readonly | 只读模式 | -- |

View File

@ -108,14 +108,20 @@ export default {
:::
::: title switch 属性
::: title 开关属性
:::
| Name | Description | Accepted Values |
| ------------- | -------------- | ---------------- |
| 属性 | 描述 | 可选值 |
| ------------- | -------------- | -------------- |
| name | 原生 name 属性 | -- |
| v-model | 是否启用 | `true` `false` |
| disabled | 禁用 | `true` `false` |
| change | 切换事件 | current : 当前值 |
| active-text | 启用描述 | `启动` |
| inactive-text | 禁用描述 | `禁用` |
::: title 开关事件
:::
| 属性 | 描述 | 可选值 |
| ------ | -------- | ---------------- |
| change | 切换事件 | current : 当前值 |

View File

@ -166,21 +166,20 @@ export default {
:::
::: title tab 属性
::: title 选项卡属性
:::
| Name | Description | Accepted Values |
| ----------- | ----------- | --------------- |
| 属性 | 描述 | 可选值 |
| ----------- | -------- | -------------- |
| v-model | 当前激活 | -- |
| type | 主题样式 | -- |
| allow-close | 允许关闭 | `true` `false` |
::: title tab 事件
::: title 选项卡事件
:::
| Name | Description | Accepted Params |
| ------ | ----------- | --------------- |
| 事件 | 描述 | 参数 |
| ------ | -------- | ---- |
| change | 选中切换 | -- |
| close | 关闭事件 | -- |

View File

@ -260,11 +260,11 @@ export default {
:::
::: title table attributes
::: title 表格属性
:::
| | | |
| 属性 | 描述 | 可选值 |
| ------------------------ | ---------- | -------------- |
| columns | 列配置 | -- |
| dataSource | 数据源 | -- |

View File

@ -82,13 +82,21 @@ export default {
:::
::: title textarea 属性
::: title 文本域属性
:::
| Name | Description | Accepted Values |
| ----------- | --------------- | --------------- |
| 属性 | 描述 | 可选值 |
| ----------- | ------------- | -------------- |
| name | 原始属性 name | -- |
| placeholder | 提示信息 | -- |
| disabled | 禁用 | `true` `false` |
| v-model | 值 | -- |
| input | 原生 input 事件 | val : 当前值 |
::: title 文本域事件
:::
| 事件 | 描述 | 可选值 |
| ----- | --------------- | ---------------- |
| input | 原生 input 事件 | event : 事件对象 |
| foucs | 原生 foucs 事件 | event : 事件对象 |
| blur | 原生 blur 事件 | -- |

View File

@ -10,6 +10,11 @@
::: demo
<template>
<lay-timeline>
<lay-timeline-item title="0.2.2">
[新增] useFullScreen 全屏 hooks。<br>
[新增] useMove 拖拽 hooks。<br>
[新增] textarea 文本域 blur foucs 获取焦点 失去焦点 事件。<br>
</lay-timeline-item>
<lay-timeline-item title="0.2.1">
[新增] hooks 文档
[新增] useClickOutside 外部 click 事件 hooks。<br>

View File

@ -7,8 +7,6 @@
:::
<img src="https://portrait.gitee.com/uploads/avatars/namespace/2849/8547475_layui-vue_1633242524.png" style="margin-left:24px;border-radius: 10px;" width="140px" />
<span style="font-size: 30px;color: #aaa;margin: 0 20px;">+</span>
<img src="https://qn.antdv.com/vue.png" width="160px" />
<br>
<br>

View File

@ -1,30 +1,11 @@
::: title 测试
::: title 沙盒环境
:::
::: demo
<template>
<lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys" :tree="isTree">
<lay-menu-item title="工作空间" id="0">
<lay-menu-child-item id="1" title="控制台">
</lay-menu-child-item>
<lay-menu-child-item id="2" title="分析页">
</lay-menu-child-item>
</lay-menu-item>
<lay-menu-item title="错误页面" id="3">
<lay-menu-child-item id="4" title="403">
</lay-menu-child-item>
<lay-menu-child-item id="5" title="404">
</lay-menu-child-item>
<lay-menu-child-item id="6" title="500">
</lay-menu-child-item>
</lay-menu-item>
</lay-menu>
<lay-tab type="brief" v-model="selectedKey">
<lay-tab-item v-for="tab in tabs" :key="tab" :title="tab.title" :id="tab.id">
{{ tab }}
</lay-tab-item>
</lay-tab>
<lay-layer title="一任流行坎止"></lay-layer>
<lay-layer title="身如不系之舟" :offset="['260px','220px']"></lay-layer>
</template>
<script>
@ -32,31 +13,8 @@ import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const router = useRouter();
const route = useRoute();
const tabs = ref([{
id:'1',title:'选项一'
},{
id:'2',title:'选项二'
}])
const isTree = ref(true);
const selectedKey = ref("1");
const openKeys = ref(["0"]);
const change = function (id) {
selectedKey.value = id
}
return {
isTree,
selectedKey,
openKeys,
change,
tabs
};
},
};

View File

@ -1,10 +1,12 @@
::: title 基础使用
:::
::: demo 使用 useClickOutside 监听元素外的监听事件
::: block 使 用 useClickOutside 监 听 元 素 外 click 事 件
:::
```vue
<template>
<lay-button ref='buttonRef' type='primary'>当前元素</lay-button>
<lay-button type="primary" ref="buttonRef">当前元素</lay-button>
</template>
<script>
@ -13,19 +15,24 @@ import useClickOutside from '/@src/hooks/useClickOutside'
export default {
setup() {
const buttonRef = (ref < null) | (HTMLElement > null)
const isClickOutside = useClickOutside(buttonRef)
watch(isClickOutside, () => {
console.log("元素外 click 事件")
console.log('元素外 click 事件')
})
return {
buttonRef
}
buttonRef,
}
},
}
</script>
```
::: title 使用备注
:::
| 备注 | 描述 | 类型 |
| -------------- | --------------- | ---- |
| isClickOutside | 使用 watch 监听 | Ref |

View File

@ -0,0 +1,38 @@
::: title 基础使用
:::
::: block 使 用 useMove 为 元 素 提 供 拖 拽 支 持
:::
```vue
<template>
<lay-button @click="fullScreen">全屏切换</lay-button>
</template>
<script>
import useFullScreen from '/@src/hooks/useFullScreen'
export default {
setup() {
const { fullScreen, isFullScreen } = useFullScreen()
watch(isFullScreen, () => {
console.log('全屏切换')
})
return {
fullScreen,
isFullScreen,
}
},
}
</script>
```
::: title 使用备注
:::
| 事件 | 描述 | 类型 |
| ------------ | -------- | -------- |
| fullScreen | 全屏切换 | Function |
| isFullScreen | 当前状态 | Ref |

View File

@ -0,0 +1,33 @@
::: title 基础使用
:::
::: block 使 用 useFullScreen 快 速 完 成 fullScreen 操 作
:::
```vue
<template>
<button id="button">拖动</button>
</template>
<script>
import { ref, watch, onMounted } from 'vue'
import useMove from '/@src/hooks/useMove'
export default {
setup() {
onMounted(() => {
const el = document.getElementById('button')
useMove(el)
})
return {}
},
}
</script>
```
::: title 使用备注
:::
| 备注 | 描述 | 类型 |
| ---- | -------------- | ----------- |
| el | 需要拖拽的元素 | HtmlElement |

View File

@ -43,7 +43,7 @@
</a>
</li>
<li class="layui-nav-item">
<a href="javascript:void(0)"> 0.2.1 </a>
<a href="javascript:void(0)"> 0.2.2 </a>
</li>
</ul>
</lay-header>

View File

@ -52,6 +52,11 @@ const zhCN = [
component: () => import('../../docs/zh-CN/guide/norms.md'),
meta: { title: '规范' },
},
{
path: '/zh-CN/guide/sandbox',
component: () => import('../../docs/zh-CN/guide/sandbox.md'),
meta: { title: '沙盒' },
},
],
},
{
@ -253,6 +258,11 @@ const zhCN = [
import('../../docs/zh-CN/components/colorPicker.md'),
meta: { title: '颜色选择器' },
},
{
path: '/zh-CN/components/layer',
component: () => import('../../docs/zh-CN/components/layer.md'),
meta: { title: '弹层' },
},
],
},
{
@ -267,6 +277,16 @@ const zhCN = [
import('../../docs/zh-CN/hooks/useClickOutside.md'),
meta: { title: 'useClickOutside' },
},
{
path: '/zh-CN/hooks/useFullScreen',
component: () => import('../../docs/zh-CN/hooks/useFullScreen.md'),
meta: { title: 'useFullScreen' },
},
{
path: '/zh-CN/hooks/useMove',
component: () => import('../../docs/zh-CN/hooks/useMove.md'),
meta: { title: 'useMove' },
},
],
},
],

View File

@ -118,19 +118,27 @@ table {
width: 100%; /*表格宽度*/
border-collapse: collapse; /*使用单一线条的边框*/
empty-cells: show; /*单元格无内容依旧绘制边框*/
border-right: 1px solid whitesmoke;
border-left: 1px solid whitesmoke;
border-radius: 4px;
}
table th,
table td {
font-size: 14px;
color: #606266;
width: 160px;
max-width: 160px;
height: 50px; /*统一每一行的默认高度*/
border-top: 1px solid whitesmoke; /*内部边框样式*/
padding: 0 10px; /*内边距*/
padding-left: 28px;
}
table th {
color: #666;
font-weight: 500;
white-space: nowrap; /*表头内容强制在一行显示*/
background-color: #fafafa;
}
table td {
white-space: nowrap;

View File

@ -328,6 +328,18 @@ export default {
},
],
},
{
id: 1,
title: '反馈',
children: [
{
id: 90,
title: '弹层',
subTitle: 'layer',
path: '/zh-CN/components/layer',
},
],
},
]
const selected = ref(1)

View File

@ -86,6 +86,12 @@ export default {
subTitle: 'change log',
path: '/zh-CN/guide/changelog',
},
{
id: 4,
title: '沙盒',
subTitle: 'sandbox',
path: '/zh-CN/guide/sandbox',
},
],
},
]

View File

@ -70,10 +70,22 @@ export default {
children: [
{
id: 1,
title: 'useClickOutside',
subTitle: '',
title: '事件',
subTitle: 'useClickOutside',
path: '/zh-CN/hooks/useClickOutside',
},
{
id: 3,
title: '拖拽',
subTitle: 'useMove',
path: '/zh-CN/hooks/useMove',
},
{
id: 2,
title: '全屏',
subTitle: 'useFullScreen',
path: '/zh-CN/hooks/useFullScreen',
},
],
},
]

View File

@ -28,7 +28,7 @@
>
</div>
<div class="site-version">
<span>当前版本v<cite class="site-showv">0.2.1</cite></span>
<span>当前版本v<cite class="site-showv">0.2.2</cite></span>
<span
><router-link
class="layui-inline site-down"

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -462,16 +462,16 @@ html #layuicss-layer {
.layui-layer-btn {
text-align: right;
padding: 0 15px 12px;
padding: 8px 15px 12px;
pointer-events: auto;
user-select: none;
-webkit-user-select: none;
}
.layui-layer-btn a {
height: 28px;
line-height: 28px;
margin: 5px 5px 0;
height: 33px;
line-height: 33px;
margin: 0px 5px 0;
padding: 0 15px;
border: 1px solid #dedede;
background-color: #fff;

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 701 B

After

Width:  |  Height:  |  Size: 701 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,5 +1,6 @@
import { ref, onMounted, onUnmounted, Ref } from 'vue'
const x = undefined
// 案例详见 dropdown.vue
const useClickOutside = (elementRef: Ref<HTMLElement | null>) => {
// 设置一个导出值

View File

@ -0,0 +1,25 @@
import { ref, onMounted, onUnmounted, Ref } from 'vue'
const useFullScreen = () => {
const isFullScreen = ref(false)
const fullScreen = function () {
var docElm = document.documentElement
switch (!isFullScreen.value) {
case true:
if (docElm.requestFullscreen) {
docElm.requestFullscreen()
}
break
case false:
if (document.exitFullscreen) {
document.exitFullscreen()
}
break
}
isFullScreen.value = !isFullScreen.value
}
return { isFullScreen, fullScreen }
}
export default useFullScreen

103
src/hooks/useMove.ts Normal file
View File

@ -0,0 +1,103 @@
function useMove(el: any) {
el.style.position = 'fixed'
let offsetX: number,
offsetY: number,
oL: number,
oT: number,
oLeft: number,
oTop: number
const browser = {
versions: (function () {
const u = navigator.userAgent
return {
mobile: !!u.match(/AppleWebKit.*Mobile.*/), //判断设备
// ..... 其他设备信息
}
})(),
}
if (!browser.versions.mobile) {
//Pc
if (el != null) {
el.addEventListener('mousedown', function (event: any) {
if (event.button == 0 && el != null) {
const lexObj: any = getComputedStyle(el)
offsetX =
event.pageX - el.offsetLeft + parseInt(lexObj['margin-left'])
offsetY =
event.pageY - el.offsetTop + parseInt(lexObj['margin-right'])
const move = function (event: any) {
if (el != null) {
let x = event.pageX - offsetX
let y = event.pageY - offsetY
if (x < 0) {
x = 0
} else if (
x >
document.documentElement.clientWidth - el.offsetWidth
) {
x = document.documentElement.clientWidth - el.offsetWidth
}
if (y < 0) {
y = 0
} else if (
y >
document.documentElement.clientHeight - el.offsetHeight
) {
y = document.documentElement.clientHeight - el.offsetHeight
}
el.style.left = x + 'px'
el.style.top = y + 'px'
}
return false
}
document.addEventListener('mousemove', move)
const stop = function () {
document.removeEventListener('mousemove', move)
document.removeEventListener('mouseup', stop)
}
document.addEventListener('mouseup', stop)
}
return false
})
}
} else {
//Mobile
if (el != null) {
const maxW = document.body.clientWidth - el.offsetWidth
const maxH = document.body.clientHeight - el.offsetHeight
const defaultEvent = function (e: any) {
e.preventDefault()
}
el.addEventListener('touchstart', function (e: any) {
const ev = e || window.event
const touch = ev.targetTouches[0]
oL = touch.clientX - el.offsetLeft
oT = touch.clientY - el.offsetTop
document.addEventListener('touchmove', defaultEvent, false)
el.addEventListener('touchmove', function (e: any) {
const ev = e || window.event
const touch = ev.targetTouches[0]
oLeft = touch.clientX - oL
oTop = touch.clientY - oT
if (oLeft < 0) {
oLeft = 0
} else if (oLeft >= maxW) {
oLeft = maxW
}
if (oTop < 0) {
oTop = 0
} else if (oTop >= maxH) {
oTop = maxH
}
el.style.left = oLeft + 'px'
el.style.top = oTop + 'px'
})
el.addEventListener('touchend', function () {
document.removeEventListener('touchmove', defaultEvent)
})
})
}
}
}
export default useMove

View File

@ -59,6 +59,7 @@ import LaySlider from './module/slider/index'
import LayCarousel from './module/carousel/index'
import LayCarouselItem from './module/carouselItem/index'
import LayColorPicker from './module/colorPicker/index'
import LayLayer from './module/layer/index'
const components: Record<string, IDefineComponent> = {
LayRadio,
@ -117,6 +118,7 @@ const components: Record<string, IDefineComponent> = {
LayCarousel,
LayCarouselItem,
LayColorPicker,
LayLayer,
}
const install = (app: App, options?: InstallOptions): void => {
@ -186,6 +188,7 @@ export {
LayCarousel,
LayCarouselItem,
LayColorPicker,
LayLayer,
install,
}

View File

@ -25,11 +25,16 @@
</button>
</template>
<script setup name="LayButton" lang="ts">
<script lang="ts">
export default {
name: 'LayButton',
}
</script>
<script setup lang="ts">
import { defineProps } from 'vue'
const props =
defineProps<{
const props = defineProps<{
type?: string
size?: string
fluid?: boolean

View File

@ -0,0 +1,9 @@
import type { App } from 'vue'
import Component from './index.vue'
import type { IDefineComponent } from '../type/index'
Component.install = (app: App) => {
app.component(Component.name || 'LayLayer', Component)
}
export default Component as IDefineComponent

159
src/module/layer/index.vue Normal file
View File

@ -0,0 +1,159 @@
<template>
<div
v-if="visible"
:id="id"
class="layui-layer"
style="z-index: 19891021; position: fixed"
:style="{
top: top,
left: left,
width: width,
height: height,
}"
>
<div class="layui-layer-title" style="cursor: move">
{{ title }}
</div>
<div class="layui-layer-content">
<div :style="{ height: contentHeight }" v-if="type === 1">
<slot v-if="slot.default"></slot>
<template v-else>
{{ content }}
</template>
</div>
<iframe
v-if="type === 2"
scrolling="auto"
allowtransparency="true"
frameborder="0"
:src="content"
style="width: 100%"
:style="{ height: contentHeight }"
></iframe>
</div>
<span class="layui-layer-setwin"
><a
v-if="maxmin"
class="layui-layer-min"
href="javascript:;"
@click="minHandle"
><cite></cite></a
><a
class="layui-layer-ico layui-layer-max"
:class="[max ? 'layui-layer-maxmin' : '']"
href="javascript:;"
v-if="maxmin"
@click="maxHandle"
></a>
<a
class="layui-layer-ico layui-layer-close layui-layer-close1"
href="javascript:;"
@click="closeHandle"
></a
></span>
<div class="layui-layer-btn" v-if="btn && btn.length > 0">
<template v-for="(b, index) in btn" :key="index">
<a :class="['layui-layer-btn' + index]" @click="b.callback">{{
b.text
}}</a>
</template>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'LayLayer',
}
</script>
<script lang="ts" setup>
import { onMounted, onUpdated, ref, useSlots } from 'vue'
import useMove from '../../hooks/useMove'
const slot = useSlots()
onMounted(() => {
if (props.move) {
const el = document.getElementById(props.id)
if (el != null) {
useMove(el)
}
}
})
onUpdated(() => {
if (props.move) {
const el = document.getElementById(props.id)
if (el != null) {
useMove(el)
}
}
})
const props = withDefaults(
defineProps<{
id?: string
title?: string
offset?: string[]
width?: string
height?: string
visible?: boolean
maxmin?: boolean
btn: Record<string, unknown>[]
move?: boolean
type?: number
content?: string
}>(),
{
id: 'layer',
title: '标题',
offset: () => ['50%', '50%'],
width: '390px',
height: '330px',
visible: true,
maxmin: false,
move: false,
type: 1,
btn: () => [],
}
)
const top = ref(props.offset[0])
const left = ref(props.offset[1])
const width = ref(props.width)
const height = ref(props.height)
const max = ref(false)
const contentHeight = ref(
props.btn.length > 0
? 'calc(' + props.height + ' - 100px)'
: 'calc(' + props.height + ' - 50px)'
)
const emit = defineEmits(['close', 'update:visible'])
const closeHandle = function () {
emit('close')
emit('update:visible', false)
}
const minHandle = function () {
emit('close')
emit('update:visible', false)
}
const maxHandle = function () {
if (max.value) {
width.value = props.width
height.value = props.height
top.value = props.offset[0]
left.value = props.offset[1]
} else {
width.value = '100%'
height.value = '100%'
top.value = '0px'
left.value = '0px'
}
max.value = !max.value
}
</script>

View File

@ -6,7 +6,9 @@
:disabled="disabled"
class="layui-textarea"
:class="{ 'layui-disabled': disabled }"
@input="updateValue"
@input="onInput"
@focus="onFocus"
@blur="onBlur"
/>
</template>
@ -20,11 +22,19 @@ const props = defineProps<{
disabled?: boolean
}>()
const emit = defineEmits(['update:modelValue', 'input'])
const emit = defineEmits(['update:modelValue', 'input', 'focus', 'blur'])
const updateValue = function (event: InputEvent) {
const onInput = function (event: InputEvent) {
const inputElement = event.target as HTMLInputElement
emit('update:modelValue', inputElement.value)
emit('input', inputElement.value)
}
const onFocus = function (event: FocusEvent) {
emit('focus', event)
}
const onBlur = function () {
emit('blur')
}
</script>