Merge branch 'develop'

This commit is contained in:
就眠儀式 2021-12-17 00:22:34 +08:00
commit f0c5ebaa4d
88 changed files with 1548 additions and 305 deletions

View File

@ -92,3 +92,6 @@ export default {
| layui-anim-rotate layui-anim-loop | 循环动画 | `layui-anim layui-anim-rotate layui-anim-loop` | | layui-anim-rotate layui-anim-loop | 循环动画 | `layui-anim layui-anim-rotate layui-anim-loop` |
::: :::
::: comment
:::

View File

@ -92,3 +92,6 @@ export default {
| radius | 圆形 | `true` `false` | | radius | 圆形 | `true` `false` |
::: :::
::: comment
:::

View File

@ -58,3 +58,6 @@ export default {
| default | 默认 | 非 `dot` 可用 | | default | 默认 | 非 `dot` 可用 |
::: :::
::: comment
:::

View File

@ -57,3 +57,6 @@ export default {
| nm | 灰色样式 | -- | | nm | 灰色样式 | -- |
::: :::
::: comment
:::

View File

@ -100,3 +100,6 @@ export default {
| default | 默认插槽 | `--` | | default | 默认插槽 | `--` |
::: :::
::: comment
:::

View File

@ -305,3 +305,6 @@ export default {
| click | 单击事件 | `--` | | click | 单击事件 | `--` |
::: :::
::: comment
:::

View File

@ -128,3 +128,6 @@ export default {
| body | 内容插槽 | -- | | body | 内容插槽 | -- |
::: :::
::: comment
:::

View File

@ -139,3 +139,6 @@ export default {
| change | 切换回调 | id | | change | 切换回调 | id |
::: :::
::: comment
:::

View File

@ -210,3 +210,6 @@ export default {
| change | 切换事件 | isChecked : 当前状态 | | change | 切换事件 | isChecked : 当前状态 |
::: :::
::: comment
:::

View File

@ -206,3 +206,6 @@ export default {
| change | 折叠面板变化触发事件 | (`id`, `isShow`, activeValues)<br> <br> `id`: (`number` / `string`)对应当前操作面板的值 <br> <br> `isShow`: (`boolean`)`true` -> 展开, `false` -> 折叠 <br> <br> `activeValues`: (`Array`)当前状态为展开的面板值集合| | change | 折叠面板变化触发事件 | (`id`, `isShow`, activeValues)<br> <br> `id`: (`number` / `string`)对应当前操作面板的值 <br> <br> `isShow`: (`boolean`)`true` -> 展开, `false` -> 折叠 <br> <br> `activeValues`: (`Array`)当前状态为展开的面板值集合|
::: :::
::: comment
:::

View File

@ -160,3 +160,6 @@ export default {
| layui-bg-black | 雅黑 | class="layui-bg-black" | | layui-bg-black | 雅黑 | class="layui-bg-black" |
::: :::
::: comment
:::

View File

@ -28,3 +28,6 @@ export default {
| showSearch | 启用搜索 | -- | | showSearch | 启用搜索 | -- |
::: :::
::: comment
:::

View File

@ -73,3 +73,6 @@ layer.confirm(content, options)
| options | 选配属性 | { time: 加载时长, btn: 按钮组 } | | options | 选配属性 | { time: 加载时长, btn: 按钮组 } |
::: :::
::: comment
:::

View File

@ -75,3 +75,6 @@ export default {
| fluid | 流模式 | `true` `false` | | fluid | 流模式 | `true` `false` |
::: :::
::: comment
:::

View File

@ -88,3 +88,6 @@ export default {
| content | 下拉内容 | -- | | content | 下拉内容 | -- |
::: :::
::: comment
:::

View File

@ -54,3 +54,6 @@ export default {
| description | 描述信息 | -- | | description | 描述信息 | -- |
::: :::
::: comment
:::

View File

@ -68,3 +68,6 @@ export default {
| title | 标题 | -- | | title | 标题 | -- |
::: :::
::: comment
:::

View File

@ -74,3 +74,6 @@ export default {
| label | 标题名称 | -- | | label | 标题名称 | -- |
::: :::
::: comment
:::

View File

@ -164,3 +164,6 @@ export default {
| lg-offset | 偏移 - 大型屏幕 (桌面 ≥1200px) | 0 - 24 | | lg-offset | 偏移 - 大型屏幕 (桌面 ≥1200px) | 0 - 24 |
::: :::
::: comment
:::

View File

@ -1127,3 +1127,6 @@ npm install @layui/icons-vue
| size | 尺寸 | -- | | size | 尺寸 | -- |
::: :::
::: comment
:::

View File

@ -110,3 +110,6 @@ export default {
| showSearch | 启用搜索 | -- | | showSearch | 启用搜索 | -- |
::: :::
::: comment
:::

View File

@ -129,3 +129,6 @@ export default {
| blur | 原生 blur 事件 | -- | | blur | 原生 blur 事件 | -- |
::: :::
::: comment
:::

View File

@ -0,0 +1,142 @@
::: title 基础使用
:::
::: demo
<template>
<lay-input-number v-model="data"></lay-input-number>
<lay-input-number v-model="data2" position="right"></lay-input-number>
</template>
<script>
import { ref } from 'vue';
const data = ref(0);
const data2 = ref(0);
export default {
setup() {
return {
data,
data2,
}
}
}
</script>
:::
::: title 尺寸
:::
::: demo
<template>
<div>
<div>
<lay-input-number></lay-input-number>
<lay-input-number size="md"></lay-input-number>
<lay-input-number size="sm"></lay-input-number>
<lay-input-number size="xs"></lay-input-number>
</div>
<div>
<lay-input-number position="right"></lay-input-number>
<lay-input-number position="right" size="md"></lay-input-number>
<lay-input-number position="right" size="sm"></lay-input-number>
<lay-input-number position="right" size="xs"></lay-input-number>
</div>
</div>
</template>
<script>
</script>
:::
::: title 限制数字大小
:::
::: demo
<template>
<lay-input-number :min="0" :max="10"></lay-input-number>
</template>
<script>
</script>
:::
::: title 数字步数
:::
::: demo
<template>
<lay-input-number :step="10"></lay-input-number>
</template>
<script>
</script>
:::
::: title 禁用
:::
::: demo
<template>
<p>禁用输入</p>
<lay-input-number v-model="data" disabled-input></lay-input-number>
<p>全部禁用</p>
<lay-input-number v-model="data2" disabled></lay-input-number>
</template>
<script>
import { ref } from 'vue';
const data = ref(10);
const data2 = ref(25);
export default {
setup() {
return {
data,
data2
}
}
}
</script>
:::
::: title input-number属性
:::
::: table
| 属性 | 描述 | 类型 | 默认值 |
| -------- | ------------- | ------ | ------ |
| v-model | 值 | `number` | 0 |
| name | 原生属性`name` | `number` | 5 |
| disabledInput | 禁用输入框输入 | `boolean` | false |
| disabled | 禁用操作 | `boolean` | false |
| step | 数字增减的步数 | `number` | 1 |
| position | 控制按钮显示位置, 目前除了默认值,只有`right`可填 | `string` | -- |
| min | 最小可输入的数 | `number` | -- |
| max | 最大可输入的数 | `number` | -- |
| size | 尺寸, 可选值`md` / `sm` / `xs`| `string` | 默认为最大尺寸 |
:::
::: title 事件
:::
::: table
| 属性 | 描述 | 回调参数 |
| -------- | -------- | ------ |
| change | 值更改触发事件 | (value: number) |
:::
::: comment
:::

View File

View File

@ -184,3 +184,6 @@ export default {
| lay-footer | 底部 | -- | | lay-footer | 底部 | -- |
::: :::
::: comment
:::

View File

@ -41,3 +41,6 @@ export default {
| theme | 主题 | `orange` `green` `cyan` `blue` `black` `gray` | | theme | 主题 | `orange` `green` `cyan` `blue` `black` `gray` |
::: :::
::: comment
:::

View File

@ -123,3 +123,6 @@ layer.load(load, options)
| options | 选配属性 | { time: 加载时长 } | | options | 选配属性 | { time: 加载时长 } |
::: :::
::: comment
:::

View File

@ -99,3 +99,6 @@ export default {
| title | 菜单标题 | -- | | title | 菜单标题 | -- |
::: :::
::: comment
:::

View File

@ -6,6 +6,7 @@
<template> <template>
<lay-button @click="changeVisible1" type="primary">基础使用</lay-button> <lay-button @click="changeVisible1" type="primary">基础使用</lay-button>
<lay-modal title="基础使用" v-model="visible1"> <lay-modal title="基础使用" v-model="visible1">
内容
</lay-modal> </lay-modal>
</template> </template>
@ -38,6 +39,7 @@ export default {
<template> <template>
<lay-button @click="changeVisible2" type="primary">允许拖动</lay-button> <lay-button @click="changeVisible2" type="primary">允许拖动</lay-button>
<lay-modal title="允许拖动" v-model="visible2"> <lay-modal title="允许拖动" v-model="visible2">
内容
</lay-modal> </lay-modal>
</template> </template>
@ -70,6 +72,7 @@ export default {
<template> <template>
<lay-button @click="changeVisible3" type="primary">放大缩小</lay-button> <lay-button @click="changeVisible3" type="primary">放大缩小</lay-button>
<lay-modal title="放大缩小" v-model="visible3" move="true" maxmin="true"> <lay-modal title="放大缩小" v-model="visible3" move="true" maxmin="true">
内容
</lay-modal> </lay-modal>
</template> </template>
@ -102,6 +105,7 @@ export default {
<template> <template>
<lay-button @click="changeVisible4" type="primary">指定位置</lay-button> <lay-button @click="changeVisible4" type="primary">指定位置</lay-button>
<lay-modal title="指定位置" v-model="visible4" move="true" :offset="['100px','100px']"> <lay-modal title="指定位置" v-model="visible4" move="true" :offset="['100px','100px']">
内容
</lay-modal> </lay-modal>
</template> </template>
@ -167,6 +171,7 @@ export default {
<template> <template>
<lay-button @click="changeVisible6" type="primary">定义操作</lay-button> <lay-button @click="changeVisible6" type="primary">定义操作</lay-button>
<lay-modal title="定义操作" v-model="visible6" move="true" :btn="btn6"> <lay-modal title="定义操作" v-model="visible6" move="true" :btn="btn6">
内容
</lay-modal> </lay-modal>
</template> </template>
@ -204,6 +209,7 @@ export default {
<template> <template>
<lay-button @click="changeVisible7" type="primary">开启遮盖</lay-button> <lay-button @click="changeVisible7" type="primary">开启遮盖</lay-button>
<lay-modal title="开启遮盖" move="true" shade="false" v-model="visible7"> <lay-modal title="开启遮盖" move="true" shade="false" v-model="visible7">
内容
</lay-modal> </lay-modal>
</template> </template>
@ -296,3 +302,6 @@ export default {
| isOutAnim | 关闭动画 | `true` `false` | | isOutAnim | 关闭动画 | `true` `false` |
::: :::
::: comment
:::

View File

@ -91,3 +91,6 @@ layer.msg(content, options)
| options | 选配属性 | { time: 加载时长, icon: 图标 } | | options | 选配属性 | { time: 加载时长, icon: 图标 } |
::: :::
::: comment
:::

View File

@ -232,3 +232,6 @@ export default {
| next | 下一页 | 下一页 | | next | 下一页 | 下一页 |
::: :::
::: comment
:::

View File

@ -31,3 +31,6 @@ export default {
| default | 默认插槽 | -- | | default | 默认插槽 | -- |
::: :::
::: comment
:::

View File

@ -125,3 +125,6 @@ export default {
| showText | 展示描述 | -- | | showText | 展示描述 | -- |
::: :::
::: comment
:::

View File

@ -117,3 +117,6 @@ export default {
| change | 切换事件 | current : 当前值 | | change | 切换事件 | current : 当前值 |
::: :::
::: comment
:::

View File

@ -305,3 +305,6 @@ export default {
| select | 选中之后触发事件 | (value: number) | | select | 选中之后触发事件 | (value: number) |
::: :::
::: comment
:::

View File

@ -100,3 +100,6 @@ export default {
| change | 切换事件 | value | | change | 切换事件 | value |
::: :::
::: comment
:::

View File

@ -1,7 +1,7 @@
::: demo ::: demo
<template> <template>
<lay-slider></lay-slider> <lay-slider v-model="value"></lay-slider>
</template> </template>
<script> <script>
@ -9,8 +9,9 @@ import { ref } from 'vue'
export default { export default {
setup() { setup() {
const value = ref(50)
return { return {
value
} }
} }
} }
@ -40,3 +41,6 @@ export default {
</script> </script>
::: :::
::: comment
:::

View File

@ -133,3 +133,6 @@ export default {
| change | 切换事件 | current : 当前值 | | change | 切换事件 | current : 当前值 |
::: :::
::: comment
:::

View File

@ -243,3 +243,6 @@ export default {
| close | 关闭事件 | id | | close | 关闭事件 | id |
::: :::
::: comment
:::

View File

@ -223,12 +223,12 @@ export default {
{ {
title:"账户", title:"账户",
width:"200px", width:"200px",
slot:"username", customSlot:"username",
key:"username" key:"username"
},{ },{
title:"密码", title:"密码",
width: "180px", width: "180px",
slot:"password", customSlot:"password",
key:"password" key:"password"
},{ },{
title:"年龄", title:"年龄",
@ -248,11 +248,11 @@ export default {
] ]
const rowClick = function(data) { const rowClick = function(data) {
alert(JSON.stringify(data)) console.log(JSON.stringify(data))
} }
const rowDoubleClick = function(data) { const rowDoubleClick = function(data) {
alert(JSON.stringify(data)) console.log(JSON.stringify(data))
} }
return { return {
@ -309,3 +309,19 @@ export default {
| toolbar | 自定义工具栏 | -- | | toolbar | 自定义工具栏 | -- |
::: :::
::: title 列配置
:::
::: table
| 插槽 | 描述 | 默认 |
| ------- | ------------ | ---- |
| title | 列标题 | -- |
| key | 数据字段 | -- |
| customSlot | 插槽名称 | -- |
| width | 宽度 | -- |
:::
::: comment
:::

View File

@ -108,3 +108,6 @@ export default {
| blur | 原生 blur 事件 | -- | | blur | 原生 blur 事件 | -- |
::: :::
::: comment
:::

View File

@ -83,3 +83,6 @@ export default {
| title | 标题 | -- | | title | 标题 | -- |
::: :::
::: comment
:::

View File

@ -0,0 +1,130 @@
::: title 基础使用
:::
::: demo
<template>
<lay-tooltip content="假装这里有文字提示">
<lay-button>tooltip</lay-button>
</lay-tooltip>
</template>
<style>
</style>
:::
::: title 显示位置
:::
::: demo
<template>
<div style="padding: 100px;max-width:400px;">
<div style="text-align: center;">
<lay-tooltip content="假装这里有文字提示">
<lay-button>上边</lay-button>
</lay-tooltip>
</div>
<div>
<lay-tooltip content="假装这里有文字提示假装这里有文字提示假装这里有文字提示假装这里有文字提示假装这里有文字提示" position="left">
<lay-button style="float:left;">左边</lay-button>
</lay-tooltip>
<lay-tooltip content="假装这里有文字提示假装这里有文字提示假装这里有文字提示假装这里有文字提示假装这里有文字提示" position="right">
<lay-button style="float:right;">右边</lay-button>
</lay-tooltip>
<div style="clear: both;"></div>
</div>
<div style="text-align: center;">
<lay-tooltip content="假装这里有文字提示假装这里有文字提示假装这里有文字提示假装这里有文字提示" position="bottom">
<lay-button>下边</lay-button>
</lay-tooltip>
</div>
</div>
</template>
<style>
</style>
:::
::: title 浅色主题
:::
::: demo
<template>
<lay-tooltip content="不明白是是非非,只知我不会不在。" :is-dark="false">
<lay-button >tooltip</lay-button>
</lay-tooltip>
</template>
<script>
</script>
:::
::: title 是否禁用/动态属性
:::
::: demo
<template>
<lay-tooltip :content="content" :is-dark="isDark" :disabled="!disabled">
<lay-button>tooltip</lay-button>
</lay-tooltip>
<lay-switch v-model="disabled" active-text="启用tooltip" inactive-text="禁用tooltip" style="margin-left: 5px;"></lay-switch>
<lay-switch v-model="isDark" active-text="深色" inactive-text="浅色" style="margin-left: 5px;"></lay-switch>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const contentArr = [
"不明白是是非非,只知我不会不在。",
"千山万水,去程是你,归程也是你。",
"一约既定,万山无阻。",
"时光都淡了,我还伴着你。",
"只问深情,不问西东。",
"感谢曾经在我身边的,一直在我身边。",
"经年再相逢,魂梦与子同。"
];
const rendonCotent = function(){
return contentArr[Math.floor(Math.random() * contentArr.length)];
};
const content = ref(rendonCotent())
const isDark = ref(false)
const disabled = ref(true)
setInterval(()=> content.value = rendonCotent(), 1000)
return {
content,
isDark,
disabled
}
}
}
</script>
<style>
</style>
:::
::: title tooltip属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----------- | -------- | -------------- |
| content | 显示内容 | -- |
| position | 显示位置 | `top`(默认值)、`bottom``left``right` |
| isDark | 是否为黑色主题 | `true`(默认值)、`false`(浅色) |
| disabled | 是否禁用 | `false`(默认值)、`true`(禁用) ||
| visible | 控制是否显示 | `true`(默认值)、`false` ||
| isCanHide | 控制是否可以隐藏,可参考`lay-slider`组件 | `true`(默认值)、`false` ||
:::
::: comment
:::

View File

@ -106,3 +106,6 @@ export default {
| item | 列表项 | { data } | | item | 列表项 | { data } |
::: :::
::: comment
:::

View File

@ -253,3 +253,6 @@ function handleClick(node) {
| node-click | 节点 click 事件 | -- | | node-click | 节点 click 事件 | -- |
::: :::
::: comment
:::

View File

@ -10,174 +10,38 @@
::: demo ::: demo
<template> <template>
<lay-timeline> <lay-timeline>
<lay-timeline-item title="0.2.7"> <lay-timeline-item title="0.2.x">
[完善] rate 评分组件。<br> <ul>
[完善] collapse 手风琴组件。<br> <a name="0-2-7"> </a>
[新增] useState 变量状态管理。<br> <li>
[新增] useBoolean 布尔变量状态管理。<br> <h3>0.2.8 <span class="layui-badge-rim">2021-12-15</span></h3>
[新增] tab 选项卡 before-close, before-leave 钩子。<br> <ul>
[新增] rate 评分组件 half 属性, 支持半选状态。<br> <li>[新增] tooltip 警告提示,展现需要关注的信息。</li>
[新增] rate 评分组件 select 事件, 评分回调事件。<br> <li>[新增] input-number 数字输入框, 通过鼠标或键盘,输入范围内的数值。</li>
[新增] layer 对象 confirm 方法, 函数式调用信息框。<br> <li>[新增] layer 组件 isHtmlFangement 属性,函数调用时,用于解析 html 片段。</li>
[新增] layer 对象 load 方法, 通过 type 配置调用不同类型加载层。<br> <li>[新增] layer 组件 resize 属性, 开启弹层尺寸拉伸, 常用于 页面层 与 Iframe 层。</li>
[修复] tab 选项卡 close 无法删除选项卡问题。<br> <li>[加强] layer 组件 area 属性, 支持 字符串 与 数组 类型, 默认 auto 宽高根据内容自适应。</li>
[修复] layer 对象的函数调用, 导致弹层过渡动画失效的问题。<br> <li>[修复] layer 组件 body 禁用拖动, 仅支持标题拖动窗体。</li>
[文档] icons-vue 组件化使用方式。<br> <li>[修复] icon-picker 组件 select 图标时, 自动隐藏选择内容。</li>
[文档] hooks-vue 使用文档。<br> <li>[修复] dropdown 组件触发方式为 hover 时,移动不到菜单子项的问题</li>
[升级] hooks-vue 0.1.6。<br> <li>[集成] utteranc.es 插件, 基于 issues 提供为文档提供留言能力。</li>
[升级] layer-vue 1.1.2。<br> <li>[升级] layer-vue 1.2.0, 更稳定的 layer 版本。</li>
[升级] vue 3.2.24。 <li>[升级] vue 3.2.26 版本。</li>
</lay-timeline-item> </ul>
<lay-timeline-item title="0.2.6"> </li>
[依赖] hooks-vue 0.1.2。<br> </ul>
[升级] layer-vue 1.0.3。<br> </lay-timeline-item>
</lay-timeline-item> <lay-timeline-item title="0.1.x">
<lay-timeline-item title="0.2.5"> <ul>
[新增] layer 提供 open, close, closeAll 函数式调用。<br> <a name="0-2-7"> </a>
[新增] icons 组件化调用方式, 使用 class 作为组件名使用组件。<br> <li>
[修复] layer 的 id 属性不唯一, 调整 Guid 为 Uuid 策略。<br> <h3>0.1.0 <span class="layui-badge-rim">2021-12-10</span></h3>
[修改] layer 组件 move 默认为 true, 默认提供拖拽支持。<br> <ul>
[修改] layer.css 为 @layui/layui-vue/lib/index.css。<br> <li>孵化。</li>
[修改] layer 组件为 lay-modal, 使用方式保持不变。<br> </ul>
[独立] layui-vue 项目, 亦支持单独引用。<br> </li>
[独立] icons-vue 项目, 亦支持单独引用。<br> </ul>
</lay-timeline-item> </lay-timeline-item>
<lay-timeline-item title="0.2.4">
[增强] checkbox 组件, v-model 支持 array 数据类型。<br>
[重构] row col 栅格组件, 支持 24 粒度布局。<br>
[重构] layui.css 样式, 集成 less 编译器。<br>
[重构] button, button-group, button-container 非破坏性改进代码。<br>
[修复] themeline 时间线,因 mackdown 造成的样式污染。<br>
[新增] layer 弹层出场动画, 允许使用 isOutAmin 关闭。<br>
[新增] checkbox-group 复选框组, 更方便的复选方式。<br>
[优化] table 和 tranfer 组件复选实现。<br>
[删除] rate 评分 theme 属性默认值。<br>
</lay-timeline-item>
<lay-timeline-item title="0.2.3">
[新增] table 表格 列筛选功能。<br>
[新增] table 表格 row 行单击, row-double 行双击事件。<br>
[新增] layer 弹层 closeBtn 属性, 允许隐藏关闭操作。<br>
[新增] layer 弹层 btnAlign 属性, 允许自定义按钮布局。<br>
[新增] layer 弹层 anim 属性, 支持 7 种入场动画。<br>
[修复] layer 弹层 btn 属性为非必填。<br>
[修复] layer 弹层 boolean 类型推断造成的警告。<br>
[修复] mackdown 文档 table 样式对 table 组件的污染。<br>
[修复] breadcrumb-item 面包屑 title 属性, 未填写造成的警告。<br>
[修复] select-option 下拉选择 disabled 属性的类型推断造成的警告。<br>
[修复] page 分页 showSkip 属性的类型推断造成的警告。<br>
[修复] rate 评分 readonly 属性的类型推断造成的警告。<br>
[修复] carousel 轮播 anim arrow indicator 属性为非必传。<br>
[优化] carousel 轮播逻辑, 允许循环切换。<br>
[优化] layer 弹层 border 样式。<br>
[优化] layer 弹层 id 默认生成方式, 使用 Guid 作为编号。<br>
[升级] vue-router 4.0.12 版本。<br>
[升级] vue 3.2.21 版本。<br>
</lay-timeline-item>
<lay-timeline-item title="0.2.2">
[新增] useFullScreen 全屏 hooks。<br>
[新增] useMove 拖拽 hooks。<br>
[新增] textarea 文本域 blur foucs 获取焦点 失去焦点 事件。<br>
[新增] layer 弹层。<br>
</lay-timeline-item>
<lay-timeline-item title="0.2.1">
[新增] hooks 文档
[新增] useClickOutside 外部 click 事件 hooks。<br>
[新增] rate 评分 readonly 属性, 支持只读模式。<br>
[新增] rate 评分 theme 属性, 支持自定义主题。<br>
[新增] progress 文档, 区分 theme 与 size 使用案例。<br>
[新增] dropdown 下拉组件 dropdown-item 点击监听, 隐藏 content 内容。<br>
[新增] input 输入框 foucs blur 原生事件绑定。<br>
[修复] rate 评分 modelValue 属性, 支持双向数据绑定。<br>
</lay-timeline-item>
<lay-timeline-item title="0.2.0">
[新增] carousel 轮播 anim 属性, 支持 default updown 不同方向轮播。<br>
[新增] carousel 轮播 arrow 属性, 支持 always hover none 不同状态切换按钮。<br>
[新增] carousel 轮播 indicator 属性, 支持 none inside outside 不同位置轮播控制器。<br>
[新增] carousel 轮播 change 事件, 用于自定义切换回调事件。<br>
[重构] layout 系列组件, 支持 纵向布局, 横向布局, 嵌套布局等。<br>
</lay-timeline-item>
<lay-timeline-item title="0.1.9">
[新增] carousel 轮播组件, 初步完成切换逻辑。<br>
[新增] colorPicker 颜色选择器, 初步完成组件渲染。<br>
[文档] 新增首页模块。<br>
[文档] 拆分菜单为指南与组件模块。<br>
[文档] 新增全局内容检索。<br>
</lay-timeline-item>
<lay-timeline-item title="0.1.8">
[新增] table 表格 size 属性, 提供不同尺寸。<br>
[新增] transfer 穿梭框 item 插槽, 允许自定义列表项。<br>
[新增] select 下拉选择 change 事件, 值变动触发回调。<br>
[新增] select-option 下拉选择项 disabled 属性, 允许可选项禁用。<br>
[修复] transfer 穿梭框 切换 逻辑。<br>
[删除] dropdown 下拉菜单 padding 样式。<br>
</lay-timeline-item>
<lay-timeline-item title="0.1.7">
[新增] page 分页 prev 插槽。<br>
[新增] page 分页 next 插槽。<br>
[新增] button 按钮 naiveType 属性, 原生 type 属性, 支持 button, submit 可选值。<br>
[新增] form 表单 model 属性, 共 submit 等事件作为入参。<br>
[新增] form 表单 submit 事件, 内部 submit 提交回调。<br>
[修复] menu 菜单 selectedKey 选中项 openKeys 打开项 props 双绑。<br>
[修复] tab 选项卡 v-model 激活项 双绑。<br>
[修复] tab 选项卡 tab-item 组件套用 for 循环无法获取 props 属性。<br>
[重构] tree 树内部逻辑, 优化性能。<br>
</lay-timeline-item>
<lay-timeline-item title="0.1.4">
[新增] button 按钮 loading 属性, 提供 加载 状态。<br>
[新增] tab 选项卡 allow-close 属性,支持 关闭。<br>
[新增] tab 选项卡 close change 事件,扩展 tab 动态逻辑。<br>
[新增] ClickOutside 工具。<br>
[新增] menu 菜单 selectedKey, openKeys 属性。<br>
[修复] menu 菜单 layui-this 样式,多 a 标签样式重叠。<br>
</lay-timeline-item>
<lay-timeline-item title="0.1.1">
[新增] menu 菜单 title 插槽,允许自定义菜单项。<br>
[新增] table 表格 toolbar 插槽, 用于自定义工具栏。<br>
[新增] icon 图标 color 属性, 用于自定义颜色。<br>
[新增] icon 图标 size 属性, 用于自定义尺寸。<br>
[新增] breadcrumb-item 面包屑 default 插槽, 用于自定义标题。<br>
[调整] menu 菜单 child-item 行高, 由 40 调整为 46。<br>
[调整] breadcrumb 面包屑样式, 让 Api 更合理。<br>
</lay-timeline-item>
<lay-timeline-item title="0.1.0">
[新增] tree 树,支持 node-clickselectKeys 等<br>
[新增] table 表格,提供 columns datasource page 分页<br>
[新增] transfer 穿梭框,提供 双列表数据切换<br>
[新增] textarea 文本域 input 事件 与 disabled 禁用属性<br>
[新增] button 按钮 disabled 禁用属性<br>
[新增] input 输入框 disabled 禁用属性<br>
[新增] checkbox 复选框 disabled 禁用属性<br>
[新增] icon 图标 prefix 属性,支持自定义 iconfont 引入使用<br>
[修改] card 卡片 slot 判断逻辑body 不存在时,使用 default slot<br>
[修改] field 字段逻辑,当 slot 为空时,展现为线状,否则为面板<br>
[修复] collapse 手风琴,展开 收起 状态时的不同图标展示<br>
[重构] checkbox 复选框逻辑,让 api 更合理<br>
[依赖] 升级 vue 3.2.20 依赖<br>
</lay-timeline-item>
<lay-timeline-item title="0.0.17">
[新增] table 表格组件<br>
[新增] tab 选项卡组件<br>
[新增] rate 评分组件<br>
[新增] button 组件 border 属性,设置边框颜色<br>
[新增] iconPicker 组件 showSearch 配置, 是否启用搜索<br>
[新增] page 分页组件<br>
[修复] menu 组件,菜单项 与 目录 重复渲染<br>
[支持] 完善 layui-vue-sample 案例<br>
[支持] 文档支持模糊查询, 用于快速检索组件文档<br>
[支持] 文档移动端预览<br>
</lay-timeline-item>
<lay-timeline-item title="0.0.14">
[新增] menu 菜单组件<br>
[新增] iconPicker 图标选择组件<br>
[新增] anim 动画文档<br>
[新增] dropdown 下拉菜单组件<br>
[新增] color 颜色文档<br>
[新增] collapse 手风琴组件<br>
[新增] select 下拉选择组件<br>
[新增] empty 空数据组件<br>
[新增] scroll 滚动容器组件<br>
[新增] avatar 头像组件<br>
</lay-timeline-item>
</lay-timeline> </lay-timeline>
</template> </template>

View File

@ -1,2 +0,0 @@
::: title 贡献代码
:::

View File

@ -1,7 +1,11 @@
::: title 基本介绍 ::: title 基本介绍
::: :::
<img src="http://layui-doc.pearadmin.com/static/images/layui/logo-2.png" /> <p>
<a href="http://layui-vue.pearadmin.com">
<img src="https://sentsin.gitee.io/res/images/layui/layui.png" alt="layui" width="500">
</a>
</p>
<br> <br>

View File

@ -0,0 +1,10 @@
::: title 贡献代码
:::
::: describe
[![Giteye chart](https://chart.giteye.net/gitee/layui-vue/layui-vue/DBC9Z6HQ.png)](https://giteye.net/chart/DBC9Z6HQ)
:::

View File

@ -1,3 +1,8 @@
.utterances {
margin-top: 30px;
max-width: 100%;
}
html { html {
line-height: 1.4; line-height: 1.4;
font-size: 16px; font-size: 16px;

View File

@ -19,6 +19,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { layer } from '@layui/layer-vue'
import { onMounted, onUnmounted, ref, watch } from 'vue' import { onMounted, onUnmounted, ref, watch } from 'vue'
const meta = ref<HTMLElement>({} as HTMLElement) const meta = ref<HTMLElement>({} as HTMLElement)
@ -32,9 +33,14 @@ const toggle = function () {
} }
const copy = function () { const copy = function () {
var Url2 = document.getElementById('source') as any const foundCodes = meta.value.getElementsByClassName('language-html')
Url2.select() if (document.hasFocus()) {
document.execCommand('Copy') const text = foundCodes[0].textContent || "";
navigator.clipboard.writeText(text);
layer.msg("复制成功", { icon : 1, time: 1000}, ()=>{})
} else {
layer.msg("复制失败", { icon : 2, time: 1000}, ()=>{})
}
} }
onMounted(() => { onMounted(() => {

View File

@ -0,0 +1,24 @@
<template>
<div id="comment"></div>
</template>
<script>
export default {
name: 'Utterances',
methods: {
initValine () {
const utterances = document.createElement('script');
utterances.type = 'text/javascript';
utterances.async = true;
utterances.setAttribute('issue-term', 'pathname')
utterances.setAttribute('theme','github-light')
utterances.setAttribute('repo',`layui-vue/layui-doc`)
utterances.crossorigin = 'anonymous';
utterances.src = 'https://utteranc.es/client.js';
window.document.getElementById('comment').appendChild(utterances);
}
},
mounted: function(){
this.initValine()
}
}
</script>

View File

@ -41,7 +41,7 @@
<script setup name="LaySelect" lang="ts"> <script setup name="LaySelect" lang="ts">
import { defineProps, ref } from 'vue' import { defineProps, ref } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { Recordable } from '/@src/module/type' import { Recordable } from '../../../src/module/type'
const props = defineProps<{ const props = defineProps<{
datas?: Recordable[] datas?: Recordable[]

View File

@ -12,11 +12,9 @@
border-left: 1px solid whitesmoke; border-left: 1px solid whitesmoke;
border-radius: 4px; border-radius: 4px;
} }
.lay-table-box table tbody { .lay-table-box table tbody {
border-bottom: 1px solid whitesmoke; border-bottom: 1px solid whitesmoke;
} }
.lay-table-box table th, .lay-table-box table th,
.lay-table-box table td { .lay-table-box table td {
font-size: 14px; font-size: 14px;
@ -27,14 +25,12 @@
padding: 0 10px; /*内边距*/ padding: 0 10px; /*内边距*/
padding-left: 28px; padding-left: 28px;
} }
.lay-table-box table th { .lay-table-box table th {
color: #666; color: #666;
font-weight: 500; font-weight: 500;
white-space: nowrap; /*表头内容强制在一行显示*/ white-space: nowrap; /*表头内容强制在一行显示*/
background-color: #fafafa; background-color: #fafafa;
} }
.lay-table-box table td { .lay-table-box table td {
white-space: nowrap; white-space: nowrap;
} }

View File

@ -18,7 +18,7 @@
<router-link to="/zh-CN/components"> 组件 </router-link> <router-link to="/zh-CN/components"> 组件 </router-link>
</li> </li>
<li class="layui-nav-item"> <li class="layui-nav-item">
<router-link to="/zh-CN/hooks"> hooks </router-link> <router-link to="/zh-CN/ecology"> 生态 </router-link>
</li> </li>
<li class="layui-nav-item"> <li class="layui-nav-item">
<lay-form> <lay-form>
@ -32,18 +32,18 @@
> >
<li class="layui-nav-item"> <li class="layui-nav-item">
<a href="https://gitee.com/layui-vue"> <a href="https://gitee.com/layui-vue">
<lay-icon type="layui-icon-fonts-code" size="14px"></lay-icon> <lay-icon type="layui-icon-fonts-code" size="15px"></lay-icon>
</a> </a>
</li> </li>
<li class="layui-nav-item"> <li class="layui-nav-item">
<a <a
href="https://gitee.com/layui-vue/layui-vue/issues?assignee_id=&author_id=&branch=&collaborator_ids=&issue_search=&label_ids=&label_text=&milestone_id=&priority=&private_issue=&program_id=&project_id=Jmysy%2Flayui-vue&project_type=&scope=&sort=&state=all&target_project=" href="https://gitee.com/layui-vue/layui-vue/issues"
> >
<lay-icon type="layui-icon-chat" size="14px"></lay-icon> <lay-icon type="layui-icon-chat" size="15px"></lay-icon>
</a> </a>
</li> </li>
<li class="layui-nav-item"> <li class="layui-nav-item">
<a href="javascript:void(0)"> 0.2.7 </a> <a href="javascript:void(0)"> 0.2.8 </a>
</li> </li>
</ul> </ul>
</lay-header> </lay-header>
@ -281,6 +281,12 @@ export default {
subTitle: 'input', subTitle: 'input',
path: '/zh-CN/components/input', path: '/zh-CN/components/input',
}, },
{
id: 341,
title: '数字输入框',
subTitle: 'inputNumber',
path: '/zh-CN/components/inputNumber',
},
{ {
id: 35, id: 35,
title: '文本域', title: '文本域',
@ -316,6 +322,11 @@ export default {
title: '颜色选择器', title: '颜色选择器',
subTitle: 'colorPicker', subTitle: 'colorPicker',
path: '/zh-CN/components/colorPicker', path: '/zh-CN/components/colorPicker',
}, {
id: 41,
title: '文字提示',
subTitle: 'tooltip',
path: '/zh-CN/components/tooltip',
}, },
] ]

View File

@ -6,6 +6,7 @@ import Layui from '../../src/index'
import LayCode from './components/LayCode.vue' import LayCode from './components/LayCode.vue'
import LaySearch from './components/LaySearch.vue' import LaySearch from './components/LaySearch.vue'
import LayTableBox from './components/LayTableBox.vue' import LayTableBox from './components/LayTableBox.vue'
import LayComment from './components/LayComment.vue'
import './assets/css/index.css' import './assets/css/index.css'
export function createApp(): { export function createApp(): {
@ -13,9 +14,7 @@ export function createApp(): {
router: Router router: Router
} { } {
const app = const app =
import.meta.env.MODE === 'production' import.meta.env.MODE === 'production' ? createSSRApp(Layout) : _createApp(Layout)
? createSSRApp(Layout)
: _createApp(Layout)
const router = createRouter() const router = createRouter()
app app
@ -23,6 +22,7 @@ export function createApp(): {
.component('LayCode', LayCode) .component('LayCode', LayCode)
.component('LaySearch', LaySearch) .component('LaySearch', LaySearch)
.component('LayTableBox', LayTableBox) .component('LayTableBox', LayTableBox)
.component('LayComment', LayComment)
.use(Layui) .use(Layui)
return { app, router } return { app, router }

View File

@ -8,6 +8,7 @@ import createTitle from './create-title'
import createBlock from './create-block' import createBlock from './create-block'
import createDescribe from './create-describe' import createDescribe from './create-describe'
import createTable from './create-table' import createTable from './create-table'
import createComment from './create-comment'
import preWrapper from './pre-wrapper' import preWrapper from './pre-wrapper'
const plugins = [ const plugins = [
@ -29,6 +30,7 @@ const plugins = [
.use(...createBlock('block', '')) .use(...createBlock('block', ''))
.use(...createTitle('title', '')) .use(...createTitle('title', ''))
.use(...createDescribe('describe', '')) .use(...createDescribe('describe', ''))
.use(...createComment('comment', ''))
}, },
}), }),
] as any ] as any

View File

@ -0,0 +1,30 @@
import container from 'markdown-it-container'
import type Token from 'markdown-it/lib/token'
type ContainerArgs = [
typeof container,
string,
{
render(tokens: Token[], idx: number): string
}
]
export default function createContainer(
klass: string,
defaultTitle: string
): ContainerArgs {
return [
container,
klass,
{
render(tokens, idx) {
const token = tokens[idx]
if (token.nesting === 1) {
return `<lay-comment>`
} else {
return '</lay-comment>\n'
}
},
},
]
}

View File

@ -1,6 +1,7 @@
import { import {
createRouter as _createRouter, createRouter as _createRouter,
createWebHashHistory, createWebHashHistory,
createWebHistory,
Router, Router,
} from 'vue-router' } from 'vue-router'
import zhCN from './zh-CN' import zhCN from './zh-CN'
@ -10,7 +11,7 @@ const routes = [...zhCN]
export function createRouter(): Router { export function createRouter(): Router {
const baseUrl = import.meta.env.BASE_URL const baseUrl = import.meta.env.BASE_URL
return _createRouter({ return _createRouter({
history: createWebHashHistory(baseUrl), history: createWebHistory(baseUrl),
routes: routes, routes: routes,
}) })
} }

View File

@ -3,6 +3,7 @@ import Component from '../view/component.vue'
import Hooks from '../view/hooks.vue' import Hooks from '../view/hooks.vue'
import Guide from '../view/guide.vue' import Guide from '../view/guide.vue'
import Index from '../view/index.vue' import Index from '../view/index.vue'
import Ecology from '../view/ecology.vue'
const zhCN = [ const zhCN = [
{ {
@ -16,6 +17,11 @@ const zhCN = [
component: Index, component: Index,
meta: { title: '指南' }, meta: { title: '指南' },
}, },
{
path: '/zh-CN/ecology',
component: Ecology,
meta: { title: '生态' },
},
{ {
path: '/zh-CN/guide', path: '/zh-CN/guide',
redirect: '/zh-CN/guide/introduce', redirect: '/zh-CN/guide/introduce',
@ -43,9 +49,9 @@ const zhCN = [
meta: { title: '问题' }, meta: { title: '问题' },
}, },
{ {
path: '/zh-CN/guide/contribution', path: '/zh-CN/guide/member',
component: () => import('../../docs/zh-CN/guide/contribution.md'), component: () => import('../../docs/zh-CN/guide/member.md'),
meta: { title: '贡献' }, meta: { title: '团队' },
}, },
{ {
path: '/zh-CN/guide/norms', path: '/zh-CN/guide/norms',
@ -232,6 +238,11 @@ const zhCN = [
component: () => import('../../docs/zh-CN/components/input.md'), component: () => import('../../docs/zh-CN/components/input.md'),
meta: { title: '输入框' }, meta: { title: '输入框' },
}, },
{
path: '/zh-CN/components/inputNumber',
component: () => import('../../docs/zh-CN/components/inputNumber.md'),
meta: { title: '数字输入框' },
},
{ {
path: '/zh-CN/components/textarea', path: '/zh-CN/components/textarea',
component: () => import('../../docs/zh-CN/components/textarea.md'), component: () => import('../../docs/zh-CN/components/textarea.md'),
@ -262,6 +273,15 @@ const zhCN = [
component: () => component: () =>
import('../../docs/zh-CN/components/colorPicker.md'), import('../../docs/zh-CN/components/colorPicker.md'),
meta: { title: '颜色选择器' }, meta: { title: '颜色选择器' },
},{
path: '/zh-CN/components/layer',
component: () => import('../../docs/zh-CN/components/layer.md'),
meta: { title: '简介' },
},
{
path: '/zh-CN/components/tooltip',
component: () => import('../../docs/zh-CN/components/tooltip.md'),
meta: { title: '文字提示' },
}, },
{ {
path: '/zh-CN/components/modal', path: '/zh-CN/components/modal',

View File

@ -188,6 +188,12 @@ export default {
subTitle: 'input', subTitle: 'input',
path: '/zh-CN/components/input', path: '/zh-CN/components/input',
}, },
{
id: 341,
title: '数字输入框',
subTitle: 'inputNumber',
path: '/zh-CN/components/inputNumber',
},
{ {
id: 35, id: 35,
title: '文本域', title: '文本域',
@ -326,6 +332,12 @@ export default {
subTitle: 'field', subTitle: 'field',
path: '/zh-CN/components/field', path: '/zh-CN/components/field',
}, },
{
id: 25,
title: '文字提示',
subTitle: 'tooltip',
path: '/zh-CN/components/tooltip',
},
], ],
}, },
{ {

View File

@ -0,0 +1,59 @@
<template>
<div
style="margin-top: 60px; height: 100%; width: 80%"
class="layui-container"
>
<blockquote class="layui-elem-quote layui-text" style="margin: 30px 0">
尽管 layui 中包含了这些组件但因为它们受众群体广泛或应用广泛特从 layui
中抽取出来个副本可独立引用我们也会对它们进行同步维护
</blockquote>
<fieldset class="layui-elem-field layui-field-title">
<legend style="margin-bottom: 20px; text-align: center">独立组件</legend>
<div class="layui-field-box">
<ul class="layui-row layui-col-space6">
<li class="layui-col-sm12">
<div class="alone">
<a href="https://gitee.com/layui-vue/layer-vue" target="_blank"
>layer - vue<cite>通用型弹出层组件</cite></a
>
</div>
</li>
<li class="layui-col-sm12">
<div class="alone">
<a href="https://gitee.com/layui-vue/icons-vue" target="_blank"
>icons - vue<cite>图标组件化解决方案</cite></a
>
</div>
</li>
</ul>
</div>
</fieldset>
</div>
</template>
<style>
.alone {
text-align: center;
background-color: #009688;
color: #fff;
font-weight: 300;
transition: all 0.3s;
-webkit-transition: all 0.3s;
}
.alone:hover a {
color: white !important;
background-color: #5fb878;
}
.alone a {
display: block;
padding: 50px 20px;
color: #fff;
font-size: 30px;
}
.alone a cite {
display: block;
padding-top: 10px;
font-size: 14px;
letter-spacing:2px;
}
</style>

View File

@ -92,17 +92,11 @@ export default {
subTitle: 'problem', subTitle: 'problem',
path: '/zh-CN/guide/problem', path: '/zh-CN/guide/problem',
}, },
{
id: 5,
title: '主题',
subTitle: 'theme',
path: '/zh-CN/guide/theme',
},
{ {
id: 6, id: 6,
title: '贡献', title: '团队',
subTitle: 'contribution', subTitle: 'member',
path: '/zh-CN/guide/contribution', path: '/zh-CN/guide/member',
} }
], ],
}, },

View File

@ -21,14 +21,12 @@
<cite>layui vue, A component library for Vue 3 base on layui</cite> <cite>layui vue, A component library for Vue 3 base on layui</cite>
</div> </div>
<div class="site-download"> <div class="site-download">
<router-link <router-link class="layui-inline site-down" to="/zh-CN/guide"
class="layui-inline site-down"
to="/zh-CN/guide/getStarted"
>Get Started</router-link >Get Started</router-link
> >
</div> </div>
<div class="site-version"> <div class="site-version">
<span>当前版本v<cite class="site-showv">0.2.7</cite></span> <span>当前版本v<cite class="site-showv">0.2.8</cite></span>
<span <span
><router-link ><router-link
class="layui-inline site-down" class="layui-inline site-down"
@ -56,6 +54,14 @@
> >
Gitee Gitee
</a> </a>
<a
href="https://github.com/layui-vue"
target="_blank"
rel="nofollow"
class="site-fork"
>
Github
</a>
</div> </div>
</div> </div>
<div style="margin-left: 10%; margin-right: 10%"> <div style="margin-left: 10%; margin-right: 10%">

View File

@ -1,6 +1,6 @@
{ {
"name": "@layui/layui-vue", "name": "@layui/layui-vue",
"version": "0.2.7", "version": "0.2.8",
"description": "a component library for Vue 3 base on layui-vue", "description": "a component library for Vue 3 base on layui-vue",
"homepage": "https://gitee.com/layui-vue/layui-vue/blob/master/README.md", "homepage": "https://gitee.com/layui-vue/layui-vue/blob/master/README.md",
"module": "lib/layui-vue.es.js", "module": "lib/layui-vue.es.js",
@ -28,30 +28,31 @@
"author": "就眠儀式", "author": "就眠儀式",
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"vue": "^3.2.24", "@layui/hooks-vue": "^0.1.6",
"vue-router": "^4.0.12",
"@layui/layer-vue": "^1.1.2",
"@layui/icons-vue": "^1.0.1", "@layui/icons-vue": "^1.0.1",
"@layui/hooks-vue": "^0.1.6" "@layui/layer-vue": "^1.1.9",
"vue": "^3.2.26",
"vue-router": "^4.0.12"
}, },
"dependencies": { "dependencies": {
"vue": "^3.2.24", "@layui/hooks-vue": "^0.1.6",
"vue-router": "^4.0.12",
"@layui/layer-vue": "^1.1.2",
"@layui/icons-vue": "^1.0.1", "@layui/icons-vue": "^1.0.1",
"@layui/hooks-vue": "^0.1.6" "@layui/layer-vue": "^1.1.9",
"evtd": "^0.2.3",
"vue": "^3.2.26",
"vue-router": "^4.0.12"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.15.8", "@babel/core": "^7.15.8",
"@babel/preset-env": "^7.15.8", "@babel/preset-env": "^7.15.8",
"@babel/preset-typescript": "^7.15.0", "@babel/preset-typescript": "^7.15.0",
"@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-babel": "^5.3.0",
"@types/node": "^16.11.9",
"@types/markdown-it": "^12.2.3", "@types/markdown-it": "^12.2.3",
"@types/markdown-it-container": "^2.0.4", "@types/markdown-it-container": "^2.0.4",
"@types/node": "^16.11.9",
"@vitejs/plugin-vue": "^1.9.3", "@vitejs/plugin-vue": "^1.9.3",
"@vue/compiler-sfc": "^3.2.24", "@vue/compiler-sfc": "^3.2.26",
"@vue/server-renderer": "^3.2.24", "@vue/server-renderer": "^3.2.26",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"less": "^4.1.2", "less": "^4.1.2",
"markdown-it-container": "^3.0.0", "markdown-it-container": "^3.0.0",

View File

@ -2610,16 +2610,24 @@ body .layui-table-tips .layui-layer-content {
display: none; display: none;
position: absolute; position: absolute;
left: 0; left: 0;
top: 42px; top: 38px;
z-index: 899; z-index: 899;
min-width: 100%; min-width: 100%;
border: 1px solid #eee;
max-height: 360px; max-height: 360px;
overflow-y: auto; overflow-y: auto;
background-color: #fff; background-color: #fff;
border-radius: 4px;
box-sizing: border-box; box-sizing: border-box;
} }
.layui-dropdown dl::before{
content: ' ';
display: block;
height: 4px;
width: 100%;
}
.layui-dropdown dl>.layui-dropdown-menu{
border: 1px solid #eee;
border-radius: 4px;
}
.layui-dropdown-up dl { .layui-dropdown-up dl {
display: block; display: block;

View File

@ -8,6 +8,7 @@ import '@layui/icons-vue/lib/index.css';
import { layer } from '@layui/layer-vue' import { layer } from '@layui/layer-vue'
import LayModal from './module/layer/modal/index' import LayModal from './module/layer/modal/index'
import LayBacktop from './module/backTop/index'
import LayAvatar from './module/avatar/index' import LayAvatar from './module/avatar/index'
import LayRadio from './module/radio/index' import LayRadio from './module/radio/index'
import LayButton from './module/button/index' import LayButton from './module/button/index'
@ -64,11 +65,14 @@ import LaySlider from './module/slider/index'
import LayCarousel from './module/carousel/index' import LayCarousel from './module/carousel/index'
import LayCarouselItem from './module/carouselItem/index' import LayCarouselItem from './module/carouselItem/index'
import LayColorPicker from './module/colorPicker/index' import LayColorPicker from './module/colorPicker/index'
import LayTooltip from './module/tooltip/index'
import LayInputNumber from './module/inputNumber/index'
const components: Record<string, IDefineComponent> = { const components: Record<string, IDefineComponent> = {
LayRadio, LayRadio,
LayButton, LayButton,
LayIcon, LayIcon,
LayBacktop,
LayLayout, LayLayout,
LaySide, LaySide,
LayHeader, LayHeader,
@ -123,6 +127,8 @@ const components: Record<string, IDefineComponent> = {
LayCarouselItem, LayCarouselItem,
LayColorPicker, LayColorPicker,
LayModal, LayModal,
LayTooltip,
LayInputNumber,
} }
const install = (app: App, options?: InstallOptions): void => { const install = (app: App, options?: InstallOptions): void => {
@ -139,6 +145,7 @@ export {
LayRadio, LayRadio,
LayIcon, LayIcon,
LayButton, LayButton,
LayBacktop,
LayLayout, LayLayout,
LaySide, LaySide,
LayHeader, LayHeader,

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 || 'LayBacktop', Component)
}
export default Component as IDefineComponent

View File

@ -0,0 +1,14 @@
<template>
<ul class="layui-fixbar">
<li class="layui-icon layui-fixbar-top" style="display: list-item"></li>
</ul>
</template>
<script lang="ts">
export default {
name: "LayBacktop"
}
</script>
<script lang="ts" setup>
</script>

View File

@ -1,6 +1,6 @@
.layui-btn { .layui-btn {
height: 38px; height: 38px;
line-height: 38px; line-height: 36px;
border: 1px solid transparent; border: 1px solid transparent;
padding: 0 18px; padding: 0 18px;
background-color: #009688; background-color: #009688;

View File

@ -1,3 +1,49 @@
<script lang="ts">
export default {
name: "LayDropdown"
}
</script>
<script setup lang="ts">
import { defineProps, provide, ref, watch } from 'vue'
import { useClickOutside } from '@layui/hooks-vue'
const dropdownRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(dropdownRef)
export interface LayDropdownProps {
trigger?: string
}
const props = withDefaults(defineProps<LayDropdownProps>(),{
trigger: 'click',
})
const openState = ref(false)
const open = function () {
openState.value = true
}
const hide = function () {
openState.value = false
}
const toggle = function () {
openState.value = !openState.value
}
watch(isClickOutside, () => {
if (isClickOutside.value) {
openState.value = false
}
})
provide('openState', openState)
defineExpose({ open, hide, toggle });
</script>
<template> <template>
<div <div
v-if="trigger === 'click'" v-if="trigger === 'click'"
@ -31,42 +77,3 @@
</dl> </dl>
</div> </div>
</template> </template>
<script setup name="LaySelect" lang="ts">
import { defineProps, provide, ref, watch } from 'vue'
import { useClickOutside } from '@layui/hooks-vue'
const dropdownRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(dropdownRef)
const props = withDefaults(
defineProps<{
trigger?: string
}>(),
{
trigger: 'click',
}
)
const openState = ref(false)
const open = function () {
openState.value = true
}
const hide = function () {
openState.value = false
}
const toggle = function () {
openState.value = !openState.value
}
watch(isClickOutside, () => {
if (isClickOutside.value) {
openState.value = false
}
})
provide('openState', openState)
</script>

View File

@ -1,5 +1,5 @@
<template> <template>
<lay-dropdown> <lay-dropdown ref="dropdownRef">
<div <div
class=" class="
layui-inline layui-border-box layui-iconpicker layui-iconpicker-split layui-inline layui-border-box layui-iconpicker layui-iconpicker-split
@ -85,17 +85,18 @@
import { defineProps, Ref, ref } from 'vue' import { defineProps, Ref, ref } from 'vue'
import { LayIconList as icons } from "@layui/icons-vue" import { LayIconList as icons } from "@layui/icons-vue"
const props = withDefaults( export interface LayIconPickerProps {
defineProps<{ page?: boolean,
modelValue?: string modelValue?: string,
page?: boolean
showSearch?: boolean showSearch?: boolean
}>(), }
{
const props = withDefaults(defineProps<LayIconPickerProps>(),{
modelValue: 'layui-icon-face-smile', modelValue: 'layui-icon-face-smile',
page: false, page: false,
} })
)
const dropdownRef = ref<null | HTMLElement>(null);
const emit = defineEmits(['update:modelValue']) const emit = defineEmits(['update:modelValue'])
@ -104,6 +105,8 @@ const selectedIcon: Ref<string> = ref(props.modelValue as string)
const selectIcon = function (icon: string) { const selectIcon = function (icon: string) {
emit('update:modelValue', icon) emit('update:modelValue', icon)
selectedIcon.value = icon selectedIcon.value = icon
// @ts-ignore
dropdownRef.value.hide()
} }
const icones: Ref = ref([]) const icones: Ref = ref([])

View File

@ -20,7 +20,7 @@ export interface LayInputProps {
name?: string; name?: string;
type?: string; type?: string;
disabled?: boolean; disabled?: boolean;
modelValue?: string; modelValue?: string | number;
placeholder?: string; placeholder?: string;
} }
@ -41,4 +41,5 @@ const onFocus = function (event: FocusEvent) {
const onBlur = function () { const onBlur = function () {
emit("blur"); emit("blur");
}; };
</script> </script>

View File

@ -0,0 +1,117 @@
@border-color: #eee;
@hover-border-color: #5fb878;
@lg: 40px;
@lg-wdith: 200px;
@lg-right: 20px;
@md: 32px;
@md-wdith: 160px;
@md-right: 16px;
@sm: 28px;
@sm-wdith: 140px;
@sm-right: 14px;
@xs: 24px;
@xs-wdith: 120px;
@xs-right: 12px;
.set-size(@width, @size, @right-size){
&{
height: @size;
width: @width;
.layui-input{
height: @size;
line-height: @size;
padding: 0 @size;
}
.layui-control-btn {
width: @size;
height: @size;
line-height: @size;
}
&[position=right]{
.layui-input{
padding: 0 @size 0 0;
}
.layui-control-btn {
height: @right-size;
line-height: @right-size;
}
.layui-subtraction-btn{
top: @right-size - 1;
}
}
}
}
.layui-input-number{
position: relative;
display: inline-block;
box-sizing: border-box;
border: 1px solid @border-color;
border-color: @border-color;
border-radius: 2px;
overflow: hidden;
.set-size(@lg-wdith, @lg, @lg-right);
margin-left: 5px;
.layui-input{
text-align: center;
border: 0;
}
.layui-control-btn {
position: absolute;
box-sizing: border-box;
border: 0;
border-color: @border-color;
border-style: solid;
border-radius: 0;
padding: 0;
text-align: center;
top: 0;
&:hover{
color: @hover-border-color;
}
&.layui-subtraction-btn{
border-right-width: 1px;
}
&.layui-addition-btn{
border-left-width: 1px;
right: 0;
}
.layui-icon{
padding: 0px;
}
}
/* 谷歌--去掉自带的控制按钮 */
input.layui-input::-webkit-outer-spin-button,
input.layui-input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
/* 火狐--去掉自带的控制按钮 */
input.layui-input[type="number"]{
-moz-appearance: textfield;
}
&[position=right]{
.layui-subtraction-btn{
right: 0;
border-right-width: 0px;
border-left-width: 1px;
}
.layui-addition-btn{
border-bottom-width: 1px;
}
}
&[size=md] {
.set-size(@md-wdith,@md, @md-right)
}
&[size=sm] {
.set-size(@sm-wdith, @sm, @sm-right)
}
&[size=xs] {
.set-size(@xs-wdith, @xs, @xs-right)
}
}

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 || 'LayInputNumber', Component)
}
export default Component as IDefineComponent

View File

@ -0,0 +1,144 @@
<template>
<div class="layui-input-number" :position="position" :size="size">
<lay-button
type="primary"
size="gl"
@mousedown="longDown(subtraction)"
@mouseup="cancelLongDown"
@blur="cancelLongDown"
:disabled="minControl"
class="layui-control-btn layui-subtraction-btn"
>
<lay-icon :type="position==='right' ? 'layui-icon-down' : 'layui-icon-subtraction'"></lay-icon>
</lay-button>
<div class="layui-input-number-input">
<lay-input
v-model="num"
:readonly="disabledInput || disabled"
type="number"
:name="name"
@change="inputChange"
></lay-input>
</div>
<lay-button
type="primary"
size="gl"
@mousedown="longDown(addition)"
@mouseup="cancelLongDown"
@blur="cancelLongDown"
:disabled="maxControl"
class="layui-control-btn layui-addition-btn"
>
<lay-icon :type="position==='right' ? 'layui-icon-up' : 'layui-icon-addition'"></lay-icon>
</lay-button>
</div>
</template>
<script lang="ts">
export default {
name: "LayInputNumber",
};
</script>
<script setup lang="ts">
import layButton from "../button/index";
import layIcon from "../icon/index";
import layInput from "../input/index";
import "./index.less";
import {
defineProps,
defineEmits,
ref,
watch,
withDefaults,
computed,
} from "vue";
export interface LayInputNumberProps {
modelValue?: number;
name?: string;
disabled?: boolean;
disabledInput?: boolean;
step?: number;
position?: "right";
min?: number;
max?: number;
size?: "md" | "sm" | "xs";
}
const props = withDefaults(defineProps<LayInputNumberProps>(), {
disabled: false,
disabledInput: false,
modelValue: 0,
step: 1,
min: -Infinity,
max: Infinity,
});
const emit = defineEmits(["update:modelValue", "change"]);
let num = ref(props.modelValue);
watch(num, (val) => {
if (props.max !== Infinity && val > props.max) {
num.value = props.max;
return;
}
if (props.min !== -Infinity && val < props.min) {
num.value = props.min;
return;
}
if (isNumber(num.value)) {
tempValue.value = Number(num.value);
emit("update:modelValue", tempValue.value);
emit("change", tempValue.value);
}
});
watch(()=>props.modelValue, (val) => {
if (val !== num.value) {
num.value = props.modelValue;
}
});
const tempValue = ref(0);
let timer: any = 0;
const minControl = computed(
() => props.min !== -Infinity && Number(props.min) >= num.value
);
const maxControl = computed(
() => props.max !== Infinity && Number(props.max) <= num.value
);
const addition = function () {
num.value += Number(props.step);
};
const subtraction = function () {
num.value -= Number(props.step);
};
const longDown = function (fn: Function) {
cancelLongDown();
if (props.disabled) {
return;
}
timer = setInterval(() => fn.call(timer), 150);
fn.call(timer);
};
const cancelLongDown = function () {
clearInterval(timer);
};
const inputChange = function () {
if (isNumber(num.value)) {
tempValue.value = Number(num.value);
return;
}
num.value = tempValue.value;
};
const isNumber = function (num: any) {
return /^\d+(\.\d+)?$/.test(num);
};
</script>

View File

@ -0,0 +1,50 @@
import { Ref } from "vue";
// 计算各个方向位置
const postionFns: any = {
top(el: HTMLElement, popper: HTMLElement, innnerPosition: Ref, called: boolean) {
let {top, left, bottom} = el.getBoundingClientRect()
if ((top = top - popper.offsetHeight - 6) < 0 && bottom > popper.offsetHeight) {
innnerPosition.value = 'bottom';
top = bottom;
}
return {
top: `${top}px`,
left: `${left - (popper.offsetWidth - el.offsetWidth) / 2}px`
}
},
bottom(el: HTMLElement, popper: HTMLElement, innnerPosition: Ref, called: boolean) {
let { top, left, bottom } = el.getBoundingClientRect()
if (window.innerHeight - bottom < popper.offsetHeight + 6) {
innnerPosition.value = 'top';
bottom = top - popper.offsetHeight - 6;
}
return {
top: `${bottom}px`,
left: `${left - (popper.offsetWidth - el.offsetWidth) / 2}px`
}
},
left(el: HTMLElement, popper: HTMLElement, innnerPosition: Ref, called : boolean) {
let {top, left, right} = el.getBoundingClientRect()
left = left - popper.offsetWidth - 6;
if (left < 0) {
innnerPosition.value = 'right';
left = right;
}
return {
top: `${top - (popper.offsetHeight - el.offsetHeight) / 2}px`,
left: `${left}px`
}
},
right(el: HTMLElement, popper: HTMLElement, innnerPosition: Ref, called: boolean) {
let { top, left, right } = el.getBoundingClientRect()
if (window.innerWidth < right + popper.offsetWidth + 6) {
innnerPosition.value = 'left';
right = left - popper.offsetWidth - 6;
}
return {
top: `${top - (popper.offsetHeight - el.offsetHeight) / 2}px`,
left: `${right}px`
}
}
}
export default postionFns;

View File

@ -0,0 +1,101 @@
// 主题颜色
// 浅色 --> 默认使用
@ligh-background: #FFF;
@ligh-color: #3a3a3a;
// 深色
@dark-background: #353535;
@dark-color: #FFF;
@border-clor: #cecece;
// 单一设置主题
.single-theme(@position, @contrary_position, @margin_postion, @color, @m-border-color) {
@attr : ~'[position=@{position}]';
&{
border: 1px solid @m-border-color;
&.layui-popper@{attr}{
margin-@{contrary_position}: 6px;
.layui-popper-arrow {
@{contrary_position}: -6px;
border-@{contrary_position}-width: 0;
border-@{position}-color: @m-border-color;
&::after{
@{contrary_position}: 1px;
border-@{contrary_position}-width: 0;
margin-@{margin_postion}: -6px;
border-@{position}-color: @color;
}
}
}
}
}
// 统一设置四个方向的主题
.theme(@background-color, @color, @border-color) {
background-color: @background-color;
color: @color;
.single-theme(top, bottom, left, @background-color, @border-color);
.single-theme(bottom, top, left, @background-color, @border-color);
.single-theme(right, left, top, @background-color, @border-color);
.single-theme(left, right, top, @background-color, @border-color);
}
// 箭头默认居中
.arrow-default-center(@position, @prop) {
@attr : ~'[position=@{position}]';
&.layui-popper@{attr} {
.layui-popper-arrow{
@{prop}: -moz-calc(50% - 6px);
@{prop}: -webkit-calc(50% - 6px);
@{prop}: calc(50% - 6px);
}
}
}
.all-arrow-default-center() {
.arrow-default-center(top, left);
.arrow-default-center(bottom, left);
.arrow-default-center(left, top);
.arrow-default-center(right, top);
}
// 样式开始
.layui-popper {
position: fixed;
padding: 10px;
border-radius: 3px;
word-wrap: break-word;
min-width: 12px;
min-height: 12px;
font-size: 14px;
box-sizing: border-box;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.15);
.theme(@ligh-background, @ligh-color, @border-clor);
max-width: 300px;
z-index: 9999;
// 箭头默认居中
.all-arrow-default-center();
.layui-popper-arrow {
&,&::after{
position: absolute;
display: block;
width: 0;
height: 0;
border-width: 6px;
border-style: solid;
border-color: transparent;
}
&::after{
content: ' ';
}
}
/* 深色主题 */
&.layui-dark {
.theme(@dark-background, @dark-color, @dark-background);
}
}

105
src/module/popper/index.vue Normal file
View File

@ -0,0 +1,105 @@
<template>
<transition v-show="innerVisible">
<div ref="popper" :class="['layui-popper', {'layui-dark' : innnerIsDark}]" :style="style" :position="innnerPosition">
<slot>{{content.value}}</slot>
<div class="layui-popper-arrow"></div>
</div>
</transition>
</template>
<script lang="ts">
const NAME = "LayPopper";
export default {
name: NAME
}
</script>
<script setup lang="ts">
import "./index.less";
import postionFns from "./calcPosition";
import { CSSProperties, ref, watch, onUpdated, defineEmits, onMounted, Ref} from "vue";
import {on} from "../../tools/domUtil";
const props = withDefaults(
defineProps<{
el : any,
content ?: Ref<string|Number>,
position ?: Ref<string>,
trigger ?: string,
enterable ?: boolean,
isDark ?: Ref<boolean>,
disabled ?: Ref<boolean>,
visible ?: Ref<boolean>,
isCanHide ?: Ref<boolean>,
updateVisible ?: Function
}>(),
{
enterable : true,
trigger : 'hover'
}
);
const EVENT_MAP : any = {
'hover' : ['mouseenter', null, 'mouseleave', false],
'click' : ['click', document, 'click', true]
}
const triggerArr = EVENT_MAP[props.trigger];
if (!triggerArr) {
console.error(`${NAME} render error!cause: 'Trigger' must be 'hover/click' `)
}
const style = ref<CSSProperties>({top: (-window.innerHeight) + 'px',left:0});
const checkTarget = ref(false);
const popper = ref<HTMLDivElement>({} as HTMLDivElement);
const tempPosition = props.position??ref('top');
const innnerPosition = ref(tempPosition.value);
const innnerIsDark = ref(props.isDark??true);
const innnerDisabled = ref(props.disabled??false);
const innerVisible = ref(props.visible??true);
watch(innerVisible, (val)=>{
invokeShowPosistion();
props.updateVisible && props.updateVisible(val);
})
watch(innnerDisabled, (val)=>{
innerVisible.value = false;
})
watch(()=>props.content?.value, (val)=>{
innerVisible.value && invokeShowPosistion();
})
const doShow = function(){
if (!innnerDisabled.value) {
innerVisible.value = true;
}
}
const doHidden = function(e : MouseEvent){
if ((checkTarget.value && props.el.contains(e.target)) || (props.enterable && popper.value.contains(e.target as Node))) return;
// style.value = {top: (-window.innerHeight) + 'px',left:0};
// popper.value.remove();
if (props.isCanHide?.value !== false) {
innerVisible.value = false;
}
innnerPosition.value = tempPosition.value;
}
//
on(props.el, triggerArr[0], doShow);
on(triggerArr[1]??props.el, triggerArr[2], doHidden);
checkTarget.value = triggerArr[3];
//
const showPosistion = function(){
postionFns[tempPosition.value] && (style.value = postionFns[tempPosition.value](props.el, popper.value, innnerPosition));
}
const invokeShowPosistion = function(){
if (innerVisible.value) {
popper.value.offsetWidth === 0 ? setTimeout(showPosistion, 0) : showPosistion();
//
setTimeout(()=>innerVisible.value && showPosistion(), 2);
};
}
onMounted(()=>{
invokeShowPosistion();
})
</script>

View File

@ -0,0 +1,43 @@
import { h, ref, render, watchEffect, watch} from "vue";
import popper from "./index.vue";
import { once } from "../../tools/domUtil";
const EVENT_MAP : any = {
'hover': 'mouseenter',
'click': 'click'
}
const usePopper = {
createPopper(el: HTMLElement, props: any, trigger : string) {
const _this = this;
once(el, EVENT_MAP[trigger], () => {
// TODO 临时解决方案
const _props:any = {el};
for (const key in props) {
_props[key] = ref(props[key]);
}
_props.updateVisible = function(val:boolean) {
_props.visible && (_props.visible.value = val);
}
_this.renderPopper(_props);
watchEffect(() => {
for (const key in _props) {
if (key === 'visible') {
continue;
}
_props[key].value = props[key];
}
});
watch(() => props.visible, (val: boolean)=> {
_props.updateVisible(val);
})
})
},
renderPopper(props: any) {
const container: HTMLDivElement = document.createElement("div");
// container.setAttribute("class", "lay-div");
const node = h(popper, props);
render(node, container);
container.firstElementChild && document.body.appendChild(container.firstElementChild);
return node;
}
}
export default usePopper;

View File

@ -0,0 +1,34 @@
.layui-slider-v {
width: 100%;
height: 50px;
/* background-color: palevioletred; */
}
.layui-slider-track-v {
width: 100%;
height: 16px;
position: relative;
cursor: pointer;
z-index: 30;
}
.layui-slider-btn-v {
width: 12px;
height: 12px;
background-color: white;
position: absolute;
// top: -7px;
border: 2px solid rgb(0, 150, 136);
border-radius: 50%;
cursor: pointer;
left: 0%;
}
.layui-slider-rate-v {
width: 0%;
height: 4px;
position: absolute;
top: 6px;
left: 0;
background-color: rgb(0, 150, 136);
}

View File

@ -1,38 +1,89 @@
<template> <template>
<div class="layui-slider layui-slider-vertical" style="height: 200px" v-if="vertical"> <div class="layui-slider layui-slider-vertical" style="height: 200px" v-if="vertical">
<div class="layui-slider-tips"></div> <div class="layui-slider-tips"></div>
<div <div class="layui-slider-bar" style="background: #009688; height: 0%; bottom: 0"></div>
class="layui-slider-bar"
style="background: #009688; height: 0%; bottom: 0"
></div>
<div class="layui-slider-wrap" style="bottom: 0%"> <div class="layui-slider-wrap" style="bottom: 0%">
<div <div class="layui-slider-wrap-btn" style="border: 2px solid #009688"></div>
class="layui-slider-wrap-btn"
style="border: 2px solid #009688"
></div>
</div> </div>
</div> </div>
<div class="layui-slider" v-else> <div class="layui-slider-v" v-else>
<div class="layui-slider-tips"></div> <div ref="tracker" @mousedown.stop="handle_mousedown" class="layui-slider-track-v">
<div <lay-tooltip :content="modelValue + ''">
class="layui-slider-bar" <div :style="{ left: modelValue + '%' }" class="layui-slider-btn-v"></div>
style="background: #009688; width: 0%; left: 0" </lay-tooltip>
></div>
<div class="layui-slider-wrap" style="left: 0%"> <div :style="{ width: modelValue + '%' }" class="layui-slider-rate-v"></div>
<div
class="layui-slider-wrap-btn"
style="border: 2px solid #009688"
></div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts">
import { defineProps, reactive, ref } from 'vue'
import { on, off } from 'evtd'
import './index.less'
<script setup name="LaySlider" lang="ts"> const emit = defineEmits(["update:modelValue"]);
import { defineProps } from 'vue'
interface LaySliderProps {
vertical?: boolean,
modelValue?: number,
min?: number,
max?: number,
}
const props = withDefaults(defineProps<LaySliderProps>(), {
vertical: false,
modelValue: 0,
})
const tracker = ref<HTMLElement | null>(null)
const style = reactive({
left: props.modelValue,
width: props.modelValue
})
function handle_mousedown() {
on('selectstart', window, handle_select, { once: true })
on('mouseup', window, handle_mouseup)
on('mousemove', window, handle_mousemove)
}
function handle_mousemove(e: MouseEvent) {
if (!tracker.value) {
return
}
let tracker_rect = tracker.value.getBoundingClientRect()
let origin_left = tracker_rect.left
let point_left = e.clientX
let distance = point_left - origin_left
if (distance < 0) {
style.left = 0
style.width = 0
props.modelValue = 0
} else {
let rate = (distance / tracker_rect.width) * 100
style.left = Math.floor(rate)
style.width = Math.floor(rate)
props.modelValue = Math.floor(rate)
if (style.left > 100) {
style.left = 100
style.width = 100
props.modelValue = 100
}
}
emit('update:modelValue', style.left)
}
function handle_mouseup() {
// off('selectstart', document, handle_select)
off('mouseup', window, handle_mouseup)
off('mousemove', window, handle_mousemove)
}
function handle_select(e: Event): void {
e.preventDefault()
}
const props =
defineProps<{
vertical?: boolean
}>()
</script> </script>

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 || 'LayTooltip', Component)
}
export default Component as IDefineComponent

View File

@ -0,0 +1,42 @@
<script lang="ts">
import usePopper from "../popper/usePopper";
import { defineComponent} from "vue";
export default defineComponent({
name: "LayTooltip",
props: {
content: {
type: [Number, String],
required: true,
},
position: {
type: String,
default: "top",
},
isDark: {
type: Boolean,
default: true,
},
disabled: {
type: Boolean,
default: false,
},
visible: {
type: Boolean,
default: true
},
isCanHide: {
type: Boolean,
default: true
}
},
render() {
return this.$slots.default && this.$slots.default()[0];
},
mounted() {
const _this = this;
this.$nextTick(() => {
usePopper.createPopper(_this.$el, _this.$props, 'hover')
});
}
});
</script>

View File

@ -44,7 +44,7 @@ const allLeftChange = function (checked: any) {
watch( watch(
leftSelectedKeys, leftSelectedKeys,
function () { () => {
if ( if (
leftDataSource.value.length === leftSelectedKeys.value.length && leftDataSource.value.length === leftSelectedKeys.value.length &&
leftDataSource.value.length != 0 leftDataSource.value.length != 0
@ -70,7 +70,7 @@ const allRightChange = function (checked: any) {
watch( watch(
rightSelectedKeys, rightSelectedKeys,
function () { () => {
if ( if (
rightDataSource.value.length === rightSelectedKeys.value.length && rightDataSource.value.length === rightSelectedKeys.value.length &&
rightDataSource.value.length != 0 rightDataSource.value.length != 0

View File

@ -1,4 +1,5 @@
import type { App, DefineComponent, Ref } from 'vue' import type { App, DefineComponent, Ref } from 'vue'
export type StringObject = Record<string, unknown> export type StringObject = Record<string, unknown>
export type UnknownObject = Record<string | number, unknown> export type UnknownObject = Record<string | number, unknown>

27
src/tools/domUtil.js Normal file
View File

@ -0,0 +1,27 @@
// 获取标签与窗口顶边距离
export function getTop(elem) {
return elem.offsetTop + (elem.offsetParent && getTop(elem.offsetParent) || 0);
}
// 获取标签与窗口左边距离
export function getLeft(elem) {
return elem.offsetLeft + (elem.offsetParent && getLeft(elem.offsetParent) || 0);
}
// 事件绑定
export function on(elem, events, handler) {
[].concat(events).forEach(event => elem.addEventListener(event, handler, false));
}
export function once (elem, events, handler) {
const listener = function (_this, args) {
handler.apply(_this, args)
off(elem, events, listener);
}
on(elem, events, listener)
}
// 事件解除
export function off(elem, events, handler) {
[].concat(events).forEach(event => elem.removeEventListener(event, handler, false));
}