Merge branch 'develop' of https://gitee.com/dingyongya/layui-vue into split-panel

 Conflicts:
	src/index.ts
This commit is contained in:
dingyongya 2022-01-20 13:34:18 +08:00
commit 3d0daef5be
60 changed files with 859 additions and 532 deletions

View File

@ -38,9 +38,7 @@ export default {
<script> <script>
import { ref } from 'vue' import { ref } from 'vue'
export default { export default {
setup() { setup() {
const src = "https://portrait.gitee.com/uploads/avatars/user/2813/8441097_shaynas_1610801433.png" const src = "https://portrait.gitee.com/uploads/avatars/user/2813/8441097_shaynas_1610801433.png"
@ -61,8 +59,11 @@ export default {
<template> <template>
<lay-avatar :src="src" size="xs"></lay-avatar> <lay-avatar :src="src" size="xs"></lay-avatar>
&nbsp;&nbsp;
<lay-avatar :src="src" size="sm"></lay-avatar> <lay-avatar :src="src" size="sm"></lay-avatar>
&nbsp;&nbsp;
<lay-avatar :src="src"></lay-avatar> <lay-avatar :src="src"></lay-avatar>
&nbsp;&nbsp;
<lay-avatar :src="src" size="lg"></lay-avatar> <lay-avatar :src="src" size="lg"></lay-avatar>
</template> </template>
@ -83,7 +84,39 @@ export default {
::: :::
::: title 头像属性 ::: title 头像列表
:::
::: demo
<template>
<lay-avatar-list>
<lay-avatar :src="src" radius></lay-avatar>
<lay-avatar :src="src" radius></lay-avatar>
<lay-avatar :src="src" radius></lay-avatar>
<lay-avatar :src="src" radius></lay-avatar>
<lay-avatar :src="src" radius></lay-avatar>
</lay-avatar-list>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const src = "https://portrait.gitee.com/uploads/avatars/user/2813/8441097_shaynas_1610801433.png"
return {
src
}
}
}
</script>
:::
::: title Avatar 属性
::: :::
::: table ::: table
@ -100,4 +133,4 @@ export default {
::: :::
::: previousNext avatar ::: previousNext avatar
::: :::

View File

@ -99,7 +99,7 @@ export default {
::: :::
::: title 事件 ::: title Backtop 事件
::: :::
::: table ::: table
@ -110,7 +110,7 @@ export default {
::: :::
::: title 插槽 ::: title Backtop 插槽
::: :::
::: table ::: table

View File

@ -39,7 +39,7 @@ export default {
::: :::
::: title 徽章属性 ::: title Badge 属性
::: :::
::: table ::: table
@ -51,7 +51,7 @@ export default {
::: :::
::: title 徽章插槽 ::: title Badge 插槽
::: :::
::: table ::: table

View File

@ -82,7 +82,7 @@ export default {
::: :::
::: title 面包屑属性 ::: title Breadcrumb 属性
::: :::
::: table ::: table
@ -93,7 +93,7 @@ export default {
::: :::
::: title 面包屑插槽 ::: title Breadcrumb 插槽
::: :::
::: table ::: table

View File

@ -122,7 +122,7 @@ export default {
<lay-button type="normal" radius>百搭按钮</lay-button> <lay-button type="normal" radius>百搭按钮</lay-button>
<lay-button type="warm" radius>暖色按钮</lay-button> <lay-button type="warm" radius>暖色按钮</lay-button>
<lay-button type="danger" radius>警告按钮</lay-button> <lay-button type="danger" radius>警告按钮</lay-button>
<lay-button type="disabled" radius>禁用按钮</lay-button> <lay-button @click="onClick" disabled radius>禁用按钮</lay-button>
</template> </template>
<script> <script>
@ -131,7 +131,12 @@ import { ref } from 'vue'
export default { export default {
setup() { setup() {
const onClick = () => {
console.log("click event");
}
return { return {
onClick
} }
} }
} }

View File

@ -108,7 +108,7 @@ export default {
::: :::
::: title 卡片属性 ::: title Card 属性
::: :::
::: table ::: table
@ -119,7 +119,7 @@ export default {
::: :::
::: title 卡片插槽 ::: title Card 插槽
::: :::
::: table ::: table

View File

@ -118,7 +118,7 @@ export default {
::: :::
::: title 轮播属性 ::: title Carousel 属性
::: :::
::: table ::: table
@ -132,7 +132,7 @@ export default {
::: :::
::: title 轮播事件 ::: title Carousel 事件
::: :::
::: table ::: table

View File

@ -188,7 +188,7 @@ export default {
::: :::
::: title 复选框属性 ::: title Checkbox 属性
::: :::
::: table ::: table
@ -203,7 +203,7 @@ export default {
::: :::
::: title 复选框事件 ::: title Checkbox 事件
::: :::
::: table ::: table

View File

@ -174,7 +174,18 @@ export default {
::: :::
::: title Collapse-item 属性 ::: title Collapse 事件
:::
::: table
| Name | Description | Callback Params |
| -------- | -------------------- | ---------------- |
| change | 折叠面板变化触发事件 | (`id`, `isShow`, activeValues)<br> <br> `id`: (`number` / `string`)对应当前操作面板的值 <br> <br> `isShow`: (`boolean`)`true` -> 展开, `false` -> 折叠 <br> <br> `activeValues`: (`Array`)当前状态为展开的面板值集合|
:::
::: title Collapse Item 属性
::: :::
::: table ::: table
@ -187,7 +198,7 @@ export default {
::: :::
::: title Collapse-item 插槽 ::: title Collapse Item 插槽
::: :::
::: table ::: table
@ -199,17 +210,6 @@ export default {
::: :::
::: title 事件
:::
::: table
| Name | Description | Callback Params |
| -------- | -------------------- | ---------------- |
| change | 折叠面板变化触发事件 | (`id`, `isShow`, activeValues)<br> <br> `id`: (`number` / `string`)对应当前操作面板的值 <br> <br> `isShow`: (`boolean`)`true` -> 展开, `false` -> 折叠 <br> <br> `activeValues`: (`Array`)当前状态为展开的面板值集合|
:::
::: comment ::: comment
::: :::

View File

@ -19,7 +19,7 @@ export default {
} }
</script> </script>
::: title icon-picker 属性 ::: title Icon Picker 属性
::: :::
::: table ::: table

View File

@ -33,14 +33,17 @@ export default {
::: demo ::: demo
<template> <template>
<lay-button @click="handlerClick" type="primary" size="sm">更新</lay-button>
<br/>
<br/>
<!-- 属性 --> <!-- 属性 -->
<lay-card style="width:200px;height:120px;display:inline-block; border:1px solid #eeeeee;box-shadow: 3px 3px 5px #888888"> <lay-card style="width:200px;height:120px;display:inline-block;">
<h1 style="padding:20px 15px"> <h1 style="padding:20px 15px">
<lay-count-up :end-val="countVal2" prefix="¥" suffix="↑"></lay-count-up> <lay-count-up :end-val="countVal2" prefix="¥" suffix="↑"></lay-count-up>
</h1> </h1>
</lay-card> </lay-card>
<!-- 插槽 --> <!-- 插槽 -->
<lay-card style="width:200px;height:120px;display:inline-block; margin-left:50px; border:1px solid #eeeeee;box-shadow: 3px 3px 5px #888888"> <lay-card style="width:200px;height:120px;display:inline-block;">
<h1 style="padding:20px 15px"> <h1 style="padding:20px 15px">
<lay-count-up :end-val="18" :duration="1"> <lay-count-up :end-val="18" :duration="1">
<template #prefix> <template #prefix>
@ -54,7 +57,6 @@ export default {
</lay-count-up> </lay-count-up>
</h1> </h1>
</lay-card> </lay-card>
<lay-button @click="handlerClick" type="primary" border="blue" size="sm" style="margin:0px 30px;">更新</lay-button>
</template> </template>
<script> <script>
@ -75,7 +77,7 @@ export default {
::: :::
::: title countUp 属性 ::: title Count Up 属性
::: :::
::: table ::: table
@ -94,8 +96,19 @@ export default {
::: :::
::: title Count Up 插槽
:::
::: title CountUpOptions 属性 ::: table
| 名称 | 描述 | 参数 |
| ----- | -------- | ---- |
| prefix | 前缀 | -- |
| suffix | 后缀 | -- |
:::
::: title Count Up Options 属性
::: :::
::: table ::: table
@ -113,17 +126,5 @@ export default {
::: :::
::: title countUp 插槽
:::
::: table
| 名称 | 描述 | 参数 |
| ----- | -------- | ---- |
| prefix | 前缀 | -- |
| suffix | 后缀 | -- |
:::
::: previousNext countUp ::: previousNext countUp
::: :::

View File

@ -70,7 +70,7 @@ export default {
::: :::
::: title 下拉属性 ::: title Dropdown 属性
::: :::
::: table ::: table
@ -81,7 +81,7 @@ export default {
::: :::
::: title 下拉插槽 ::: title Dropdown 插槽
::: :::
::: table ::: table

View File

@ -47,7 +47,7 @@ export default {
::: :::
::: title empty 属性 ::: title Empty 属性
::: :::
::: table ::: table

View File

@ -64,7 +64,7 @@ export default {
::: :::
::: title 字段属性 ::: title Field 属性
::: :::
::: table ::: table

View File

@ -139,7 +139,7 @@ export default {
::: :::
::: title 属性 ::: title Row 属性
::: :::
::: table ::: table
@ -150,7 +150,7 @@ export default {
::: :::
::: title 属性 ::: title Col 属性
::: :::
::: table ::: table

View File

@ -106,7 +106,7 @@ export default {
::: :::
::: title 输入框属性 ::: title Input 属性
::: :::
::: table ::: table
@ -120,7 +120,7 @@ export default {
::: :::
::: title 输入框属性 ::: title Input 属性
::: :::
::: table ::: table

View File

@ -111,7 +111,7 @@
::: :::
::: title input-number属性 ::: title Input Number 属性
::: :::
::: table ::: table
@ -130,7 +130,7 @@
::: :::
::: title 事件 ::: title Input Number 事件
::: :::
::: table ::: table

View File

@ -37,7 +37,7 @@ export default {
::: :::
::: title 分割属性 ::: title Line 属性
::: :::
::: table ::: table

View File

@ -47,7 +47,7 @@ export default {
::: demo ::: demo
<template> <template>
<lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys" v-model:tree="isTree"> <lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys" :tree="true">
<lay-menu-item title="首页" id="1"></lay-menu-item> <lay-menu-item title="首页" id="1"></lay-menu-item>
<lay-menu-item title="用户" id="2"></lay-menu-item> <lay-menu-item title="用户" id="2"></lay-menu-item>
<lay-menu-item title="角色" id="3"></lay-menu-item> <lay-menu-item title="角色" id="3"></lay-menu-item>
@ -66,6 +66,49 @@ export default {
<script> <script>
import { ref } from 'vue' import { ref } from 'vue'
export default {
setup() {
const openKeys = ref(["7"])
const selectedKey = ref("5")
return {
openKeys,
selectedKey
}
}
}
</script>
:::
::: title 菜单插槽
:::
::: demo
<template>
<lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys" v-model:tree="isTree">
<lay-menu-item id="1">
<router-link to="">首页</router-link>
</lay-menu-item>
<lay-sub-menu id="7">
<template v-slot:title>
<router-link to="">目录</router-link>
</template>
<lay-menu-item id="8">
<router-link to="">菜单一</router-link>
</lay-menu-item>
<lay-menu-item id="9">
<router-link to="">菜单二</router-link>
</lay-menu-item>
</lay-sub-menu>
</lay-menu>
</template>
<script>
import { ref } from 'vue'
export default { export default {
setup() { setup() {
@ -84,59 +127,7 @@ export default {
::: :::
::: title Menu 属性
::: title 菜单插槽
:::
::: demo
<template>
<lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys" v-model:tree="isTree">
<lay-menu-item id="1">
<template v-slot:title>
<router-link to="">首页</router-link>
</template>
</lay-menu-item>
<lay-menu-item id="7">
<template v-slot:title>
<router-link to="">目录</router-link>
</template>
<lay-menu-item id="8">
<template v-slot:title>
<router-link to="">菜单一</router-link>
</template>
</lay-menu-item>
<lay-menu-item id="9">
<template v-slot:title>
<router-link to="">菜单二</router-link>
</template>
</lay-menu-item>
</lay-menu-item>
</lay-menu>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const isTree = ref(true)
const selectedKey = ref("5")
const openKeys = ref(["7"])
return {
isTree,
openKeys,
selectedKey
}
}
}
</script>
:::
::: title 菜单属性
::: :::
::: table ::: table
@ -148,7 +139,40 @@ export default {
::: :::
::: title 菜单插槽 ::: title Menu Item 属性
:::
::: table
| 插槽 | 描述 | 备注 |
| ----- | -------- | ---- |
| title | 菜单标题 | -- |
:::
::: title Menu Item 插槽
:::
::: table
| 插槽 | 描述 | 备注 |
| ----- | -------- | ---- |
| title | 菜单标题 | -- |
:::
::: title Sub Menu 属性
:::
::: table
| 插槽 | 描述 | 备注 |
| ----- | -------- | ---- |
| title | 菜单标题 | -- |
:::
::: title Sub Menu 插槽
::: :::
::: table ::: table

View File

@ -7,7 +7,7 @@
::: demo ::: demo
<template> <template>
<lay-page :limit="limit" :total="total" :show-page="showPage"></lay-page> <lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage"></lay-page>
</template> </template>
<script> <script>
@ -37,7 +37,7 @@ export default {
::: demo ::: demo
<template> <template>
<lay-page :limit="limit" :total="total"></lay-page> <lay-page :limit="limit" @limit="limit = $event" :total="total"></lay-page>
</template> </template>
<script> <script>
@ -65,7 +65,7 @@ export default {
::: demo ::: demo
<template> <template>
<lay-page :limit="limit" :total="total"> <lay-page :limit="limit" @limit="limit = $event" :total="total">
<template v-slot:prev></template> <template v-slot:prev></template>
<template v-slot:next></template> <template v-slot:next></template>
</lay-page> </lay-page>
@ -96,11 +96,11 @@ export default {
::: demo ::: demo
<template> <template>
<lay-page :limit="limit" :total="total" :show-page="showPage" theme="red"></lay-page> <lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage" theme="red"></lay-page>
<br> <br>
<lay-page :limit="limit" :total="total" :show-page="showPage" theme="blue"></lay-page> <lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage" theme="blue"></lay-page>
<br> <br>
<lay-page :limit="limit" :total="total" :show-page="showPage" theme="orange"></lay-page> <lay-page :limit="limit" @limit="limit = $event" :total="total" :show-page="showPage" theme="orange"></lay-page>
</template> </template>
<script> <script>
@ -124,13 +124,13 @@ export default {
::: :::
::: title 完整分页 ::: title 指定分页容量
::: :::
::: demo ::: demo
<template> <template>
<lay-page :limit="limit" :total="total" :show-count="showCount" :show-page="showPage" :show-limit="showLimit" :show-refresh="showRefresh" showSkip="showSkip"></lay-page> <lay-page :limit="limit" :total="total" showCount showPage :limits="[10,50,100,200]" @limit="limit=$event"></lay-page>
</template> </template>
<script> <script>
@ -141,6 +141,66 @@ export default {
const limit = ref(20) const limit = ref(20)
const total = ref(100) const total = ref(100)
return {
limit,
total
}
}
}
</script>
:::
::: title 每页数量切换事件(limit)
:::
::: demo
<template>
<lay-page :limit="limit" showPage showCount :total="total" @limit="limit=$event" :show-limit="showLimit" ></lay-page>
<div>每页数量:{{limit}}</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(5)
const total = ref(9999)
const showLimit = ref(true)
return {
limit,
total,
showLimit,
}
}
}
</script>
:::
::: title 完整分页
:::
::: demo
<template>
<lay-page :limit="limit" :total="9999" :show-count="showCount" @limit="limit=$event" :show-page="showPage" :show-limit="showLimit" :show-refresh="showRefresh" showSkip="showSkip"></lay-page>
每页数量:{{limit}}
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(5)
const total = ref(9999)
const showCount = ref(true) const showCount = ref(true)
const showPage = ref(true) const showPage = ref(true)
const showLimit = ref(true) const showLimit = ref(true)
@ -162,13 +222,13 @@ export default {
::: :::
::: title 切换事件 ::: title 页码切换事件(jump)
::: :::
::: demo ::: demo
<template> <template>
<lay-page :limit="limit" :total="total" @jump="jump" :show-page="showSkip"></lay-page> <lay-page :limit="limit" :total="total" @jump="jump" @limit="limit = $event" :show-page="showSkip"></lay-page>
</template> </template>
<script> <script>
@ -196,7 +256,7 @@ export default {
::: :::
::: title 分页属性 ::: title Page 属性
::: :::
::: table ::: table
@ -210,10 +270,12 @@ export default {
| showLimit | 显示每页数量 | `false` | | showLimit | 显示每页数量 | `false` |
| showRefresh | 显示刷新按钮 | `false` | | showRefresh | 显示刷新按钮 | `false` |
| showSkip | 显示跳转 | `false` | | showSkip | 显示跳转 | `false` |
| pages | 显示切页按钮数量 | `10` |
| limits | 切换每页数量的选择项 | `[10,20,30,40,50]` |
::: :::
::: title 分页事件 ::: title Page 事件
::: :::
::: table ::: table
@ -221,10 +283,11 @@ export default {
| 事件 | 描述 | 参数 | | 事件 | 描述 | 参数 |
| ---- | -------- | --------------------- | | ---- | -------- | --------------------- |
| jump | 切换回调 | { current: 当前页面 } | | jump | 切换回调 | { current: 当前页面 } |
| limit | 每页数量变化 | 变化后的值 |
::: :::
::: title 分页插槽 ::: title Page 插槽
::: :::
::: table ::: table

View File

@ -24,7 +24,7 @@ export default {
::: :::
::: title 面板插槽 ::: title Panel 插槽
::: :::
::: table ::: table

View File

@ -113,7 +113,7 @@ export default {
::: :::
::: title 进度属性 ::: title Progress 属性
::: :::
::: table ::: table

View File

@ -97,7 +97,7 @@ export default {
::: :::
::: title 单选框属性 ::: title Radio 属性
::: :::
::: table ::: table
@ -110,7 +110,7 @@ export default {
::: :::
::: title 单选框事件 ::: title Radio 事件
::: :::
::: table ::: table

View File

@ -269,7 +269,7 @@ export default {
::: :::
::: title 评分属性 ::: title Rate 属性
::: :::
::: table ::: table
@ -287,7 +287,7 @@ export default {
::: :::
::: title 插槽 ::: title Rate 插槽
::: :::
::: table ::: table
@ -298,7 +298,7 @@ export default {
::: :::
::: title 事件 ::: title Rate 事件
::: :::
::: table ::: table

View File

@ -27,6 +27,40 @@ export default {
} }
</script> </script>
::: title 数据联动
:::
::: demo
<template>
<lay-select v-model="value">
<lay-select-option value="1" label="学习"></lay-select-option>
<lay-select-option value="2" label="编码"></lay-select-option>
<lay-select-option value="3" label="运动"></lay-select-option>
</lay-select>
<lay-button @click="change1">点击切换(当前值:{{value}})</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
name:'selectChange',
setup() {
const value = ref(null);
var i = 1;
function change1(){
value.value=i++%3+1
}
return {
value,
change1
}
}
}
</script>
::: :::
::: title 选择禁用 ::: title 选择禁用
@ -74,6 +108,7 @@ export default {
<lay-select-option value="6" label="打篮球"></lay-select-option> <lay-select-option value="6" label="打篮球"></lay-select-option>
<lay-select-option value="7" label="rap"></lay-select-option> <lay-select-option value="7" label="rap"></lay-select-option>
</lay-select> </lay-select>
<lay-button @click="mvalue=[1,5,7]">点击切换(当前值:{{mvalue.join()}})</lay-button>
</template> </template>
<script> <script>
@ -95,7 +130,7 @@ export default {
::: :::
::: title select 属性 ::: title Select 属性
::: :::
::: table ::: table
@ -112,7 +147,18 @@ export default {
::: :::
::: title select-option 属性 ::: title Select 事件
:::
::: table
| 属性 | 描述 | 接收值 |
| ------ | ---------- | --------------- |
| change | 切换事件 | value |
:::
::: title Select Option 属性
::: :::
::: table ::: table
@ -128,7 +174,7 @@ export default {
::: :::
::: title select-option 插槽 ::: title Select Option 插槽
::: :::
::: table ::: table
@ -139,17 +185,6 @@ export default {
::: :::
::: title select 事件
:::
::: table
| 属性 | 描述 | 接收值 |
| ------ | ---------- | --------------- |
| change | 切换事件 | value |
:::
::: comment ::: comment
::: :::

View File

@ -82,7 +82,7 @@ export default {
::: :::
::: title 骨架屏属性 ::: title Skeleton 属性
::: :::
::: table ::: table
@ -96,7 +96,7 @@ export default {
::: :::
::: title 骨架屏插槽 ::: title Skeleton 插槽
::: :::
::: table ::: table

View File

@ -1,3 +1,6 @@
::: anchor
:::
::: title 横向 ::: title 横向
::: :::
@ -91,7 +94,7 @@ export default {
</script> </script>
::: :::
::: title slider 属性 ::: title Slider 属性
::: :::
::: table ::: table

View File

@ -423,7 +423,7 @@ export default {
::: :::
::: title step步骤条属性 ::: title Step 属性
::: :::
::: table ::: table
@ -442,7 +442,7 @@ export default {
::: :::
::: title stepItem步骤条属性 ::: title Step Item 属性
::: :::
::: table ::: table
@ -457,7 +457,7 @@ export default {
::: :::
::: title stepItem步骤条slot ::: title Step Item 插槽
::: :::
::: table ::: table

View File

@ -111,7 +111,7 @@ export default {
::: :::
::: title 开关属性 ::: title Switch 属性
::: :::
::: table ::: table
@ -126,7 +126,7 @@ export default {
::: :::
::: title 开关事件 ::: title Switch 事件
::: :::
::: table ::: table

View File

@ -130,15 +130,15 @@ export default {
::: :::
::: title 控制是否关闭 ::: title 关闭前置
::: :::
::: demo ::: demo
<template> <template>
<lay-tab type="card" v-model="current5" allow-close @change="change5" @close="close5" :beforeClose="beforeClose"> <lay-tab type="card" v-model="current5" allow-close @change="change5" @close="close5" :beforeClose="beforeClose">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item> <lay-tab-item title="选项一" id="1" closable="true"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item> <lay-tab-item title="选项二" id="2" closable="false"><div style="padding:20px">选项二</div></lay-tab-item>
<lay-tab-item title="选项三" id="3"><div style="padding:20px">选项三</div></lay-tab-item> <lay-tab-item title="选项三" id="3"><div style="padding:20px">选项三</div></lay-tab-item>
<lay-tab-item title="选项四" id="4"><div style="padding:20px">选项四</div></lay-tab-item> <lay-tab-item title="选项四" id="4"><div style="padding:20px">选项四</div></lay-tab-item>
<lay-tab-item title="选项五" id="5"><div style="padding:20px">选项五</div></lay-tab-item> <lay-tab-item title="选项五" id="5"><div style="padding:20px">选项五</div></lay-tab-item>
@ -169,7 +169,7 @@ export default {
return { return {
current5, current5,
change5, change5,
beforeClose beforeClose,
close5 close5
} }
} }
@ -178,15 +178,14 @@ export default {
::: :::
::: title 嵌套循环 ::: title 嵌套循环
::: :::
::: demo ::: demo
<template> <template>
<lay-tab type="card" v-model="current6" @change="change6"> <lay-tab type="card" allow-close v-model="current6" @change="change6">
<lay-tab-item v-for="a in arr" :key="a" :title="a.title" :id="a.id"> <lay-tab-item v-for="a in arr" :key="a" :title="a.title" :id="a.id" :closable="a.closable">
内容{{a.id}} 内容{{a.id}}
</lay-tab-item> </lay-tab-item>
</lay-tab> </lay-tab>
@ -204,12 +203,11 @@ export default {
} }
const arr = ref([ const arr = ref([
{id:'1', title:'选项一'}, {id:'1', title:'选项一', closable: false},
{id:'2', title:'选项二'} {id:'2', title:'选项二'},
{id:'3', title:'选项三'}
]) ])
arr.value.push({id:'3', title:'选项三'})
return { return {
current6, current6,
arr arr
@ -220,22 +218,22 @@ export default {
::: :::
::: title 选项卡属性 ::: title Tab 属性
::: :::
::: table ::: table
| 属性 | 描述 | 可选值 | | 属性 | 描述 | 可选值 |
| ----------- | -------- | -------------- | | ------------ | ------------------------------------ | ----------------------------------------- |
| v-model | 当前激活 | -- | | v-model | 当前激活 | -- |
| type | 主题样式 | -- | | type | 主题样式 | -- |
| allow-close | 允许关闭 | `true` `false` | | allow-close | 允许关闭 | `true` `false` |
| before-close | `Function`关闭之前的回调钩子函数 | 参数(`id`), `return false` 表示不进行关闭 | | before-close | `Function`关闭之前的回调钩子函数 | 参数(`id`), `return false` 表示不进行关闭 |
| before-leave | `Function`切换标签之前的回调钩子函数 | 参数(`id`), `return false` 表示不进行切换 | | before-leave | `Function`切换标签之前的回调钩子函数 | 参数(`id`), `return false` 表示不进行切换 |
::: :::
::: title 选项卡事件 ::: title Tab 事件
::: :::
::: table ::: table
@ -247,8 +245,21 @@ export default {
::: :::
::: title Tab Item 属性
:::
::: table
| 属性 | 描述 | 可选值 |
| -------- | -------- | ------ |
| id | 唯一标识 | -- |
| title | 头部标题 | -- |
| closable | 允许关闭 | -- |
:::
::: comment ::: comment
::: :::
::: previousNext tab ::: previousNext tab
::: :::

View File

@ -315,7 +315,7 @@ export default {
### <div id="tableColumn"></div> ### <div id="tableColumn"></div>
::: title Table Column 属性 ::: title Table 数据
::: :::
::: table ::: table

View File

@ -85,7 +85,7 @@ export default {
::: :::
::: title 文本域属性 ::: title Textarea 属性
::: :::
::: table ::: table
@ -99,7 +99,7 @@ export default {
::: :::
::: title 文本域事件 ::: title Textarea 事件
::: :::
::: table ::: table

View File

@ -120,7 +120,7 @@ export default {
::: :::
::: title Timeline Item 属性 ::: title Timeline Item 插槽
::: :::
::: table ::: table

View File

@ -113,7 +113,7 @@
</style> </style>
::: :::
::: title tooltip属性 ::: title Tooltip 属性
::: :::
::: table ::: table

View File

@ -86,7 +86,7 @@ export default {
::: :::
::: title transfer 属性 ::: title Transfer 属性
::: :::
::: table ::: table
@ -99,7 +99,7 @@ export default {
::: :::
::: title transfer 插槽 ::: title Transfer 插槽
::: :::
::: table ::: table

View File

@ -216,7 +216,7 @@ function handleClick(node) {
::: :::
::: title tree attributes ::: title Tree 属性
::: :::
::: table ::: table
@ -231,7 +231,7 @@ function handleClick(node) {
::: :::
::: title TreeData ::: title Tree 数据
::: :::
::: table ::: table
@ -246,7 +246,7 @@ function handleClick(node) {
::: :::
::: title tree events ::: title Tree 事件
::: :::
::: table ::: table

View File

@ -11,16 +11,45 @@
<template> <template>
<lay-timeline> <lay-timeline>
<lay-timeline-item title="0.3.x"> <lay-timeline-item title="0.3.x">
<ul>
<a name="0-3-5"> </a>
<li>
<h3>0.3.5 <span class="layui-badge-rim">2022-01-19</span></h3>
<ul>
<li>[修复] dropdown 下拉菜单 content 显示位置问题。</li>
<li>[升级] icons-vue 1.0.3 版本。</li>
</ul>
</li>
</ul>
<ul>
<a name="0-3-4"> </a>
<li>
<h3>0.3.4 <span class="layui-badge-rim">2022-01-19</span></h3>
<ul>
<li>[新增] avatar-list 头像列表组件。</li>
<li>[新增] tab-item 选项卡组件 closable 属性, 控制当前选项卡 close 支持。</li>
<li>[修复] button 按钮 disabled 为 true 时, 触发 click 事件。</li>
<li>[修复] menu-item 与 sub-menu 组件的 title 属性必填警告。</li>
<li>[修复] layout 组件 side 因 flex 布局宽度不固定。</li>
<li>[优化] layer 的 children slot 渲染机制。</li>
<li>[升级] layer-vue 1.2.5 版本。</li>
<li>[升级] vue 3.2.27 版本。</li>
</ul>
</li>
</ul>
<ul> <ul>
<a name="0-3-3"> </a> <a name="0-3-3"> </a>
<li> <li>
<h3>0.3.3 <span class="layui-badge-rim">2022-01-05</span></h3> <h3>0.3.3 <span class="layui-badge-rim">2022-01-09</span></h3>
<ul> <ul>
<li>[新增] setup 步骤条组件。</li> <li>[新增] setup 步骤条组件。</li>
<li>[新增] slider 滑块组件 vertical 属性, 支持垂直布局。</li> <li>[新增] slider 滑块组件 vertical 属性, 支持垂直布局。</li>
<li>[新增] timeline-item 时间线组件 dot 插槽, 支持自定义节点内容。</li> <li>[新增] timeline-item 时间线组件 dot 插槽, 支持自定义节点内容。</li>
<li>[新增] sub-menu 目录组件, 与 menu-item 组合使用。</li> <li>[新增] sub-menu 目录组件, 与 menu-item 组合使用。</li>
<li>[修复] menu 组件 layui-nav-more 切换动画。</li> <li>[修复] menu 菜单组件 layui-nav-more 切换动画。</li>
<li>[修复] select 下拉选择组件外部参数变更组件内的数值不生效的问题</li>
<li>[修复] page 分页组件 limit 数量过多时, 展示部分页数。</li>
<li>[推出] layui-vue-admin 后台模板 </li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -35,7 +64,7 @@
<li>[增强] menu 菜单组件, 初步支持无限级嵌套。</li> <li>[增强] menu 菜单组件, 初步支持无限级嵌套。</li>
<li>[修复] layer.close layer.closeAll 函数无法触发 OutAnim 过度动画问题。</li> <li>[修复] layer.close layer.closeAll 函数无法触发 OutAnim 过度动画问题。</li>
<li>[废弃] menu-child-item 组件, 使用 menu-item 替代。</li> <li>[废弃] menu-child-item 组件, 使用 menu-item 替代。</li>
<li>[升级] layer-vue 1.2.4。</li> <li>[升级] layer-vue 1.2.4 版本</li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -53,7 +82,7 @@
<li>[修复] rate 评分 mouseleave 事件绑定警告。</li> <li>[修复] rate 评分 mouseleave 事件绑定警告。</li>
<li>[修复] npm 安装 layui-vue 不必要的依赖警告。</li> <li>[修复] npm 安装 layui-vue 不必要的依赖警告。</li>
<li>[集成] eslint, prettier 规范插件 。</li> <li>[集成] eslint, prettier 规范插件 。</li>
<li>[升级] icons-vue 1.0.2。</li> <li>[升级] icons-vue 1.0.2 版本</li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -72,7 +101,7 @@
<li>[修复] layer 弹层 v-model 切换状态后, 让其保持 area 与 offset 状态。</li> <li>[修复] layer 弹层 v-model 切换状态后, 让其保持 area 与 offset 状态。</li>
<li>[修复] transfer 穿梭框组件按钮样式, 使其增加减少操作按钮对齐。</li> <li>[修复] transfer 穿梭框组件按钮样式, 使其增加减少操作按钮对齐。</li>
<li>[修复] tree 树开启 checkbox 时, 无法选中的问题。</li> <li>[修复] tree 树开启 checkbox 时, 无法选中的问题。</li>
<li>[升级] layer-vue 1.2.2。</li> <li>[升级] layer-vue 1.2.2 版本</li>
</ul> </ul>
</li> </li>
</ul> </ul>

View File

@ -110,10 +110,6 @@ form {
margin: 0; margin: 0;
} }
.source .layui-avatar {
margin-right: 30px;
}
.site-doc-icon { .site-doc-icon {
margin-bottom: 50px; margin-bottom: 50px;
font-size: 0; font-size: 0;

View File

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

View File

@ -28,6 +28,20 @@
</ul> </ul>
</div> </div>
</fieldset> </fieldset>
<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-sm24">
<div class="alone">
<a href="https://gitee.com/layui-vue/layui-vue-admin" target="_blank"
>layui - admin<cite>通用型 vue 3.0 后台模板</cite></a
>
</div>
</li>
</ul>
</div>
</fieldset>
</div> </div>
</template> </template>

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "@layui/layui-vue", "name": "@layui/layui-vue",
"version": "0.3.2", "version": "0.3.4",
"author": "sleeprite", "author": "sleeprite",
"license": "MIT", "license": "MIT",
"description": "a component library for Vue 3 base on layui-vue", "description": "a component library for Vue 3 base on layui-vue",
@ -24,20 +24,21 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build --emptyOutDir && npm run build:types", "build": "vite build --emptyOutDir && npm run build:types",
"build:es": "es use",
"build:umd": "umd use",
"build:types": "rimraf types && tsc -d", "build:types": "rimraf types && tsc -d",
"build:example": "vite build example", "build:example": "vite build example",
"lint:eslint": "eslint 'src/**/*.{vue,ts,tsx}' --fix", "lint:eslint": "eslint 'src/**/*.{vue,ts,tsx}' --fix",
"lint:prettier": "prettier --write 'src/**/*'", "lint:prettier": "prettier --write 'src/**/*'"
"commit": "git cz"
}, },
"dependencies": { "dependencies": {
"@layui/hooks-vue": "^0.1.6", "@layui/hooks-vue": "^0.1.6",
"@layui/icons-vue": "^1.0.2", "@layui/icons-vue": "^1.0.3",
"@layui/layer-vue": "^1.2.4", "@layui/layer-vue": "^1.2.5",
"async-validator": "^4.0.7", "async-validator": "^4.0.7",
"countup.js": "^2.0.8", "countup.js": "^2.0.8",
"evtd": "^0.2.3", "evtd": "^0.2.3",
"vue": "^3.2.26", "vue": "^3.2.27",
"vue-router": "^4.0.12" "vue-router": "^4.0.12"
}, },
"devDependencies": { "devDependencies": {
@ -51,8 +52,8 @@
"@typescript-eslint/eslint-plugin": "^5.8.0", "@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0", "@typescript-eslint/parser": "^5.8.0",
"@vitejs/plugin-vue": "^1.9.3", "@vitejs/plugin-vue": "^1.9.3",
"@vue/compiler-sfc": "^3.2.26", "@vue/compiler-sfc": "^3.2.27",
"@vue/server-renderer": "^3.2.26", "@vue/server-renderer": "^3.2.27",
"commitizen": "^4.2.4", "commitizen": "^4.2.4",
"cz-conventional-changelog": "3.3.0", "cz-conventional-changelog": "3.3.0",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
@ -60,14 +61,14 @@
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.2.0", "eslint-plugin-vue": "^8.2.0",
"less": "^4.1.2",
"markdown-it-container": "^3.0.0", "markdown-it-container": "^3.0.0",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"prismjs": "^1.25.0", "prismjs": "^1.25.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rollup": "^2.61.0", "rollup": "^2.64.0",
"typescript": "^4.5.2", "typescript": "^4.5.2",
"less": "^4.1.2", "vite": "2.7.12",
"vite": "2.7.6",
"vite-plugin-md": "^0.11.6" "vite-plugin-md": "^0.11.6"
}, },
"files": [ "files": [
@ -79,4 +80,4 @@
"last 2 versions and > 2%", "last 2 versions and > 2%",
"ie > 10" "ie > 10"
] ]
} }

View File

@ -2610,7 +2610,6 @@ body .layui-table-tips .layui-layer-content {
display: none; display: none;
position: absolute; position: absolute;
left: 0; left: 0;
top: 38px;
z-index: 899; z-index: 899;
min-width: 100%; min-width: 100%;
max-height: 360px; max-height: 360px;

View File

@ -9,6 +9,7 @@ import { layer } from "@layui/layer-vue";
import LayLayer from "./module/layer/index"; import LayLayer from "./module/layer/index";
import LayBacktop from "./module/backTop/index"; import LayBacktop from "./module/backTop/index";
import LayAvatar from "./module/avatar/index"; import LayAvatar from "./module/avatar/index";
import LayAvatarList from "./module/avatarList/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";
import LayButtonContainer from "./module/buttonContainer/index"; import LayButtonContainer from "./module/buttonContainer/index";
@ -112,6 +113,7 @@ const components: Record<string, IDefineComponent> = {
LayBreadcrumb, LayBreadcrumb,
LayBreadcrumbItem, LayBreadcrumbItem,
LayAvatar, LayAvatar,
LayAvatarList,
LayField, LayField,
LaySelect, LaySelect,
LayScroll, LayScroll,
@ -191,6 +193,7 @@ export {
LayBreadcrumb, LayBreadcrumb,
LayBreadcrumbItem, LayBreadcrumbItem,
LayAvatar, LayAvatar,
LayAvatarList,
LayField, LayField,
LaySelect, LaySelect,
LayScroll, LayScroll,

View File

@ -40,3 +40,8 @@
height: 28px; height: 28px;
width: 28px; width: 28px;
} }
.layui-avatar-list .layui-avatar {
margin-left: -10px;
display: inline-block;
}

View File

@ -3,7 +3,7 @@ import Component from "./index.vue";
import type { IDefineComponent } from "../type/index"; import type { IDefineComponent } from "../type/index";
Component.install = (app: App) => { Component.install = (app: App) => {
app.component(Component.name || "LayCount", Component); app.component(Component.name || "LayAvatarList", Component);
}; };
export default Component as IDefineComponent; export default Component as IDefineComponent;

View File

@ -0,0 +1,15 @@
<script lang="ts">
export default {
name: "LayAvatarList",
};
</script>
<script setup lang="ts">
import { defineProps } from "vue";
</script>
<template>
<div class="layui-avatar-list">
<slot></slot>
</div>
</template>

View File

@ -27,6 +27,14 @@ const props = withDefaults(defineProps<LayButtonProps>(), {
nativeType: "button", nativeType: "button",
}); });
const emit = defineEmits(["click"]);
const onClick = (event : any) => {
if(!props.disabled) {
emit("click", event);
}
}
const classes = computed(() => { const classes = computed(() => {
return [ return [
props.type ? `layui-btn-${props.type}` : "", props.type ? `layui-btn-${props.type}` : "",
@ -48,6 +56,7 @@ const classes = computed(() => {
classes, classes,
]" ]"
:type="nativeType" :type="nativeType"
@click="onClick"
> >
<i <i
v-if="loading" v-if="loading"

View File

@ -1,5 +0,0 @@
<template>
<span class="layui-count"></span>
</template>
<script setup name="LayCount" lang="ts"></script>

View File

@ -1,9 +1,7 @@
.layui-layout { .layui-layout {
display: flex;
flex: 1; flex: 1;
display: flex;
flex-basis: auto; flex-basis: auto;
height: 100%;
width: 100%;
box-sizing: border-box; box-sizing: border-box;
} }

View File

@ -11,7 +11,7 @@ const slots = useSlots();
const props = defineProps<{ const props = defineProps<{
id: string; id: string;
title: string; title?: string;
}>(); }>();
const selectedKey: Ref<string> = inject("selectedKey") as Ref<string>; const selectedKey: Ref<string> = inject("selectedKey") as Ref<string>;

View File

@ -1,122 +1,163 @@
<template> <template>
<div class="layui-box layui-laypage layui-laypage-default"> <div class="layui-box layui-laypage layui-laypage-default">
<span v-if="showCount" class="layui-laypage-count"> {{ total }} </span <span v-if="showCount" class="layui-laypage-count"
><a > {{ total }} {{ maxPage }} </span
href="javascript:;" >
class="layui-laypage-prev" <a
:class="[currentPage === 1 ? 'layui-disabled' : '']" href="javascript:;"
@click="prev()" class="layui-laypage-prev"
><slot v-if="slots.prev" name="prev"></slot> :class="[currentPage === 1 ? 'layui-disabled' : '']"
<template v-else>上一页</template></a @click="prev()"
> >
<template v-if="showPage"> <slot v-if="slots.prev" name="prev"></slot>
<template v-for="index of totalPage" :key="index"> <template v-else>上一页</template>
<span v-if="index === currentPage" class="layui-laypage-curr" </a>
><em <template v-if="showPage">
class="layui-laypage-em" <template v-for="index of totalPage" :key="index">
:class="[theme ? 'layui-bg-' + theme : '']" <span v-if="index === currentPage" class="layui-laypage-curr">
></em <em
><em>{{ index }}</em></span class="layui-laypage-em"
> :class="[theme ? 'layui-bg-' + theme : '']"
<a v-else href="javascript:;" @click="jump(index)"> ></em>
{{ index }} <em>{{ index }}</em>
</a> </span>
</template> <a v-else href="javascript:;" @click="jump(index)">{{ index }}</a>
</template> </template>
</template>
<a <a
href="javascript:;" href="javascript:;"
class="layui-laypage-next" class="layui-laypage-next"
:class="[currentPage === totalPage ? 'layui-disabled' : '']" :class="[currentPage === maxPage ? 'layui-disabled' : '']"
@click="next()" @click="next()"
><slot v-if="slots.next" name="next"></slot> >
<template v-else>下一页</template></a <slot v-if="slots.next" name="next"></slot>
><span v-if="showLimit" class="layui-laypage-limits" <template v-else>下一页</template>
><select v-model="inlimit"> </a>
<option value="10">10 /</option> <span v-if="showLimit" class="layui-laypage-limits">
<option value="20">20 /</option> <select v-model="inlimit">
<option value="30">30 /</option> <option v-for="val of limits" :key="val" :value="val">
<option value="40">40 /</option> {{ val }} /
<option value="50">50 /</option> </option>
</select></span </select>
><a v-if="showRefresh" href="javascript:;" class="layui-laypage-refresh" </span>
><i class="layui-icon layui-icon-refresh"></i></a <a v-if="showRefresh" href="javascript:;" class="layui-laypage-refresh">
><span v-if="showSkip" class="layui-laypage-skip" <i class="layui-icon layui-icon-refresh"></i>
>到第<input </a>
v-model="currentPageShow" <span v-if="showSkip" class="layui-laypage-skip">
type="number" 到第
class="layui-input layui-input-number" <input
/><button type="button" class="layui-laypage-btn" @click="jumpPage()"> v-model="currentPageShow"
确定 @keypress.enter="jumpPage()"
</button></span type="number"
> class="layui-input layui-input-number"
</div> />
<button
type="button"
class="layui-laypage-btn"
@click="jumpPage()"
:disabled="currentPageShow > maxPage"
>
确定
</button>
</span>
</div>
</template> </template>
<script setup name="LayPage" lang="ts"> <script setup name="LayPage" lang="ts">
import { defineProps, Ref, ref, watch, useSlots, computed, ComputedRef } from "vue"; import { defineProps, Ref, ref, watch, useSlots, computed } from "vue";
const slots = useSlots(); const slots = useSlots();
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
total: number; total: number;
limit: number; limit: number;
theme?: string; theme?: string;
showPage?: boolean | string; showPage?: boolean | string;
showSkip?: boolean | string; showSkip?: boolean | string;
showCount?: boolean | string; showCount?: boolean | string;
showLimit?: boolean | string; showLimit?: boolean | string;
showInput?: boolean | string; showInput?: boolean | string;
showRefresh?: boolean | string; showRefresh?: boolean | string;
}>(), pages?: number;
{ limits?: number[];
limit: 10, }>(),
theme: "green", {
showPage: false, limit: 10,
showSkip: false, theme: "green",
showCount: false, showPage: false,
showLimit: true, showSkip: false,
showInput: false, showCount: false,
showRefresh: false, showLimit: true,
} showInput: false,
showRefresh: false,
pages: 10,
limits: () => [10, 20, 30, 40, 50],
}
); );
const limits = ref(props.limits);
const inlimit = ref(props.limit); const pages = props.pages / 2;
const totalPage = ref(Math.ceil(props.total / inlimit.value)); const inlimit = computed({
get() {
return props.limit;
},
set(v: number) {
emit("limit", v);
},
});
const maxPage = ref(0);
const totalPage = computed(() => {
maxPage.value = Math.ceil(props.total / props.limit);
let r: number[] = [],
start =
maxPage.value <= props.pages
? 1
: currentPage.value > pages
? currentPage.value - pages
: 1;
for (let i = start; ; i++) {
if (r.length >= props.pages || i > maxPage.value) {
break;
}
r.push(i);
}
return r;
});
const currentPage: Ref<number> = ref(1); const currentPage: Ref<number> = ref(1);
const currentPageShow: Ref<number> = ref(currentPage.value); const currentPageShow: Ref<number> = ref(currentPage.value);
const emit = defineEmits(["jump"]);
const emit = defineEmits(["jump", "limit"]);
const prev = function () { const prev = function () {
if (currentPage.value === 1) { if (currentPage.value === 1) {
return; return;
} }
currentPage.value--; currentPage.value--;
}; };
const next = function () { const next = function () {
if (currentPage.value === totalPage.value) { if (currentPage.value === maxPage.value) {
return; return;
} }
currentPage.value++; currentPage.value++;
}; };
const jump = function (page: number) { const jump = function (page: number) {
currentPage.value = page; currentPage.value = page;
}; };
const jumpPage = function () { const jumpPage = function () {
currentPage.value = currentPageShow.value; currentPage.value = currentPageShow.value;
}; };
watch(inlimit, function () { watch(inlimit, function () {
currentPage.value = 1; currentPage.value = 1;
totalPage.value = Math.ceil(props.total / inlimit.value); // maxPage.value = Math.ceil(props.total / inlimit.value);
}); });
watch(currentPage, function () { watch(currentPage, function () {
currentPageShow.value = currentPage.value; currentPageShow.value = currentPage.value;
emit("jump", { current: currentPage.value }); emit("jump", { current: currentPage.value });
}); });
</script> </script>

View File

@ -1,91 +1,91 @@
<template> <template>
<div <div
ref="selectRef" ref="selectRef"
class="layui-unselect layui-form-select" class="layui-unselect layui-form-select"
:class="{ 'layui-form-selected': openState }" :class="{ 'layui-form-selected': openState }"
> >
<div class="layui-select-title" @click="open"> <div class="layui-select-title" @click="open">
<input <input
type="text" type="text"
:placeholder=" :placeholder="
selectItem.value !== null && selectItem.value !== null &&
Array.isArray(selectItem.value) && Array.isArray(selectItem.value) &&
selectItem.value.length > 0 selectItem.value.length > 0
? '' ? ''
: emptyMessage ?? placeholder : emptyMessage ?? placeholder
" "
:disabled="disabled" :disabled="disabled"
readonly readonly
:value=" :value="
!selectItem.multiple && selectItem.value !== null !selectItem.multiple && selectItem.value !== null
? selectItem.label ? selectItem.label
: null : null
" "
:name="name" :name="name"
:class="[ :class="[
'layui-input', 'layui-input',
'layui-unselect', 'layui-unselect',
{ 'layui-disabled': disabled }, { 'layui-disabled': disabled },
]" ]"
/> />
<i :class="['layui-edge', { 'layui-disabled': disabled }]"></i> <i :class="['layui-edge', { 'layui-disabled': disabled }]"></i>
<!-- 多选 --> <!-- 多选 -->
<div <div
v-if="selectItem.multiple && Array.isArray(selectItem.label)" v-if="selectItem.multiple && Array.isArray(selectItem.label)"
class="layui-multiple-select-row" class="layui-multiple-select-row"
> >
<div class="layui-multiple-select-badge"> <div class="layui-multiple-select-badge">
<template v-for="(item, index) in selectItem.label" :key="index"> <template v-for="(item, index) in selectItem.label" :key="index">
<lay-badge theme="green"> <lay-badge theme="green">
<span>{{ item }}</span> <span>{{ item }}</span>
<i <i
:class="['layui-icon', { 'layui-icon-close': true }]" :class="['layui-icon', { 'layui-icon-close': true }]"
v-if=" v-if="
!disabled && !disabled &&
!( !(
Array.isArray(selectItem.value) && Array.isArray(selectItem.value) &&
selectItem.value.length > 0 && selectItem.value.length > 0 &&
disabledItemMap[selectItem.value[index]] disabledItemMap[selectItem.value[index]]
) )
" "
@click=" @click="
removeItemHandle($event, { removeItemHandle($event, {
label: item, label: item,
value: Array.isArray(selectItem.value) value: Array.isArray(selectItem.value)
? selectItem.value[index] ? selectItem.value[index]
: null, : null,
}) })
" "
> >
</i> </i>
</lay-badge> </lay-badge>
</template> </template>
</div> </div>
</div> </div>
</div> </div>
<dl class="layui-anim layui-anim-upbit"> <dl class="layui-anim layui-anim-upbit">
<!-- 多选不支持空提示 --> <!-- 多选不支持空提示 -->
<template v-if="!multiple && showEmpty"> <template v-if="!multiple && showEmpty">
<lay-select-option :value="null" :label="emptyMessage ?? placeholder" /> <lay-select-option :value="null" :label="emptyMessage ?? placeholder" />
</template> </template>
<slot></slot> <slot></slot>
</dl> </dl>
</div> </div>
</template> </template>
<script setup name="LaySelect" lang="ts"> <script setup name="LaySelect" lang="ts">
import "./index.less"; import "./index.less";
import LaySelectOption from "../selectOption/index.vue"; import LaySelectOption from "../selectOption/index.vue";
import { import {
defineProps, defineProps,
provide, provide,
isProxy, isProxy,
ref, ref,
watch, watch,
computed, computed,
reactive, reactive,
toRefs, toRefs,
Ref, Ref,
} from "vue"; } from "vue";
import { useClickOutside } from "@layui/hooks-vue"; import { useClickOutside } from "@layui/hooks-vue";
import { SelectItem } from "../type"; import { SelectItem } from "../type";
@ -94,115 +94,127 @@ const selectRef = ref<null | HTMLElement>(null);
const isClickOutside = useClickOutside(selectRef); const isClickOutside = useClickOutside(selectRef);
watch(isClickOutside, () => { watch(isClickOutside, () => {
if (isClickOutside.value) { if (isClickOutside.value) {
openState.value = false; openState.value = false;
} }
}); });
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
modelValue?: string | number | [] | null; modelValue?: string | number | [] | null;
name?: string; name?: string;
placeholder?: string; placeholder?: string;
disabled?: boolean; disabled?: boolean;
showEmpty?: boolean; showEmpty?: boolean;
emptyMessage?: string; emptyMessage?: string;
multiple?: boolean; multiple?: boolean;
}>(), }>(),
{ {
modelValue: null, modelValue: null,
placeholder: "请选择", placeholder: "请选择",
disabled: false, disabled: false,
showEmpty: true, showEmpty: true,
multiple: false, multiple: false,
} }
); );
const openState = ref(false); const openState = ref(false);
const open = function () { const open = function () {
// //
if (props.disabled) { if (props.disabled) {
openState.value = false; openState.value = false;
return; return;
} }
openState.value = !openState.value; openState.value = !openState.value;
}; };
const emit = defineEmits(["update:modelValue", "change"]); const emit = defineEmits(["update:modelValue", "change"]);
const selectItem = ref<SelectItem>({ const selectItem = ref<SelectItem>({
value: !props.multiple value: !props.multiple
? props.modelValue ? props.modelValue
: props.modelValue : props.modelValue
? ([] as any[]).concat(props.modelValue) ? ([] as any[]).concat(props.modelValue)
: [], : [],
label: props.multiple ? [] : null, label: props.multiple ? [] : null,
multiple: props.multiple, multiple: props.multiple,
} as SelectItem); } as SelectItem);
watch( watch(
() => selectItem.value.value, () => selectItem.value.value,
(val) => { (val) => {
emit("update:modelValue", val); emit("update:modelValue", val);
emit("change", val); emit("change", val);
}, },
{ {
deep: true, deep: true,
} }
); );
watch( watch(props, () => {
() => props.modelValue, let value = props.modelValue;
(value) => { if (props.multiple) {
selectItem.value.value = value; if (Array.isArray(value)) {
if (!value && value !== 0) { selectItem.value.value = value;
props.multiple && (selectItem.value.value = []); selectItem.value.label = value.map((o) => ItemsMap.value[o]);
selectItem.value.label = props.multiple ? [] : null; } else {
} console.error("多选时请传入数组值");
} }
); } else {
selectItem.value.value = value;
//@ts-ignore
selectItem.value.label = ItemsMap.value[value] || "";
}
});
// //
const disabledItemMap: { [key: string | number]: boolean } = {}; const disabledItemMap: { [key: string | number]: boolean } = {};
const selectItemHandle = function ( const selectItemHandle = function (
_selectItem: SelectItem, _selectItem: SelectItem,
isChecked?: boolean isChecked?: boolean
) { ) {
if (!props.multiple) { if (!props.multiple) {
openState.value = false; openState.value = false;
} }
disabledItemMap[_selectItem.value as string | number] = disabledItemMap[_selectItem.value as string | number] =
_selectItem.disabled as boolean; _selectItem.disabled as boolean;
if (typeof isChecked !== "boolean") { if (typeof isChecked !== "boolean") {
props.multiple props.multiple
? (selectItem.value.label as any[]).push(_selectItem.label) ? (selectItem.value.label as any[]).push(_selectItem.label)
: (selectItem.value.label = _selectItem.label); : (selectItem.value.label = _selectItem.label);
return; return;
} }
let values = selectItem.value.value; let values = selectItem.value.value;
if (props.multiple && Array.isArray(values)) { if (props.multiple && Array.isArray(values)) {
const _values = values as any[]; const _values = values as any[];
const _labels = selectItem.value.label as any[]; const _labels = selectItem.value.label as any[];
if (isChecked) { if (isChecked) {
_values.push(_selectItem.value); _values.push(_selectItem.value);
_labels.push(_selectItem.label); _labels.push(_selectItem.label);
} else { } else {
_values.splice(_values.indexOf(_selectItem.value), 1); _values.splice(_values.indexOf(_selectItem.value), 1);
_labels.splice(_labels.indexOf(_selectItem.label), 1); _labels.splice(_labels.indexOf(_selectItem.label), 1);
} }
selectItem.value.value = _values; selectItem.value.value = _values;
selectItem.value.label = _labels; selectItem.value.label = _labels;
} else { } else {
selectItem.value.value = _selectItem.value; selectItem.value.value = _selectItem.value;
selectItem.value.label = _selectItem.label; selectItem.value.label = _selectItem.label;
} }
}; };
const removeItemHandle = function (e: MouseEvent, _selectItem: SelectItem) { const removeItemHandle = function (e: MouseEvent, _selectItem: SelectItem) {
e.stopPropagation(); e.stopPropagation();
selectItemHandle(_selectItem, false); selectItemHandle(_selectItem, false);
};
const ItemsMap: Ref<{ [index: string]: string }> = ref({});
const selectItemPush = function (p: SelectItem) {
if (p.value !== null) {
//@ts-ignore
ItemsMap.value[p.value] = p.label;
}
}; };
provide("selectItemHandle", selectItemHandle); provide("selectItemHandle", selectItemHandle);
provide("selectItem", selectItem); provide("selectItem", selectItem);
provide("selectItemPush", selectItemPush);
</script> </script>

View File

@ -1,65 +1,81 @@
<template> <template>
<dd <dd
:value="value" :value="value"
:class="[{ 'layui-this': selected }, { 'layui-disabled': disabled }]" :class="[{ 'layui-this': selected }, { 'layui-disabled': disabled }]"
@click="selectHandle" @click="selectHandle"
> >
<template v-if="selectItem.multiple"> <template v-if="selectItem.multiple">
<lay-checkbox <lay-checkbox
skin="primary" skin="primary"
v-model="selected" v-model="selected"
@change="selectHandle" @change="selectHandle"
label="" label=""
/> />
</template> </template>
<slot>{{ label }}</slot> <slot>{{ label }}</slot>
</dd> </dd>
</template> </template>
<script lang="ts"> <script lang="ts">
export default { export default {
name: "LaySelectOption", name: "LaySelectOption",
}; };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import LayCheckbox from "../checkbox"; import LayCheckbox from "../checkbox";
import { SelectItem, SelectItemHandle } from "../type"; import { SelectItem, SelectItemHandle, SelectItemPush } from "../type";
import { computed, defineProps, inject, onMounted, Ref } from "vue"; import { computed, defineProps, inject, onMounted, Ref } from "vue";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
value: string | null | undefined; value: string | null | undefined;
label?: string; label?: string;
disabled?: boolean; disabled?: boolean;
}>(), }>(),
{ {
disabled: false, disabled: false,
} }
); );
const selectItemHandle = inject("selectItemHandle") as SelectItemHandle; const selectItemHandle = inject("selectItemHandle") as SelectItemHandle;
const selectItem = inject("selectItem") as Ref<SelectItem>; const selectItem = inject("selectItem") as Ref<SelectItem>;
const selectItemPush = inject("selectItemPush") as Ref<SelectItemPush>;
const selectHandle = function () { const selectHandle = function () {
!props.disabled && callSelectItemHandle(!selected.value); !props.disabled && callSelectItemHandle(!selected.value);
} };
const callSelectItemHandle = function(isChecked ?: boolean){ const callSelectItemHandle = function (isChecked?: boolean) {
selectItemHandle({ // console.log("callSelectItemHandle");
value : props.value, selectItemHandle(
label : props.label, {
disabled : props.disabled value: props.value,
}, isChecked); label: props.label,
} disabled: props.disabled,
},
isChecked
);
};
const selected = computed({ const selected = computed({
get(){ get() {
const selectValues = selectItem.value.value; const selectValues = selectItem.value.value;
if (Array.isArray(selectValues)) { if (Array.isArray(selectValues)) {
return (selectValues as any[]).indexOf(props.value) > -1; return (selectValues as any[]).indexOf(props.value) > -1;
} }
return selectItem.value.value === props.value return selectItem.value.value === props.value;
}, },
set(val){} set(val) {},
}) });
onMounted(() => selected.value && callSelectItemHandle()) const callSelectItemPush = function () {
let item = {
value: props.value,
label: props.label,
disabled: props.disabled,
};
selectItemPush(item);
};
onMounted(() => {
callSelectItemPush();
selected.value && callSelectItemHandle();
});
</script> </script>

View File

@ -149,10 +149,24 @@ const vertical_style = reactive({
height: props.modelValue, height: props.modelValue,
}); });
function throttle(func: Function) {
let timer: any = null;
return function (args: any) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
func(args);
}, 60);
}
};
}
const moveAction = throttle(handle_mousemove);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function handle_mousedown() { function handle_mousedown() {
on("selectstart", window, handle_select, { once: true }); on("selectstart", window, handle_select, { once: true });
on("mouseup", window, handle_mouseup); on("mouseup", window, handle_mouseup);
on("mousemove", window, handle_mousemove); on("mousemove", window, moveAction);
} }
function handle_mousemove(e: MouseEvent) { function handle_mousemove(e: MouseEvent) {
@ -179,7 +193,7 @@ function handle_mousemove(e: MouseEvent) {
function handle_mouseup() { function handle_mouseup() {
// off('selectstart', document, handle_select) // off('selectstart', document, handle_select)
off("mouseup", window, handle_mouseup); off("mouseup", window, handle_mouseup);
off("mousemove", window, handle_mousemove); off("mousemove", window, moveAction);
} }
function handle_select(e: Event): void { function handle_select(e: Event): void {

View File

@ -11,7 +11,7 @@ const slots = useSlots();
const props = defineProps<{ const props = defineProps<{
id: string; id: string;
title: string; title?: string;
}>(); }>();
const isTree = inject("isTree"); const isTree = inject("isTree");

View File

@ -13,7 +13,7 @@
> >
{{ children.props.title }} {{ children.props.title }}
<i <i
v-if="allowClose" v-if="allowClose && children.props.closable != false"
class="layui-icon layui-icon-close layui-unselect layui-tab-close" class="layui-icon layui-icon-close layui-unselect layui-tab-close"
@click.stop="close(index, children.props.id)" @click.stop="close(index, children.props.id)"
></i> ></i>

View File

@ -9,3 +9,7 @@ export interface SelectItem {
export interface SelectItemHandle { export interface SelectItemHandle {
(selectItem: SelectItem, isChecked?: boolean): void; (selectItem: SelectItem, isChecked?: boolean): void;
} }
export interface SelectItemPush {
(selectItem: SelectItem): void
}

View File

@ -3,7 +3,7 @@
* <p> * <p>
* @param elem dom * @param elem dom
* */ * */
export function getTop(elem) { export function getTop(elem: any) : any {
return ( return (
elem.offsetTop + ((elem.offsetParent && getTop(elem.offsetParent)) || 0) elem.offsetTop + ((elem.offsetParent && getTop(elem.offsetParent)) || 0)
); );
@ -14,7 +14,7 @@ export function getTop(elem) {
* <p> * <p>
* @param elem dom * @param elem dom
* */ * */
export function getLeft(elem) { export function getLeft(elem: any) : any {
return ( return (
elem.offsetLeft + ((elem.offsetParent && getLeft(elem.offsetParent)) || 0) elem.offsetLeft + ((elem.offsetParent && getLeft(elem.offsetParent)) || 0)
); );
@ -27,7 +27,7 @@ export function getLeft(elem) {
* @param events * @param events
* @param handler * @param handler
* */ * */
export function on(elem, events, handler) { export function on(elem: any, events: any, handler: any) {
[] []
.concat(events) .concat(events)
.forEach((event) => elem.addEventListener(event, handler, false)); .forEach((event) => elem.addEventListener(event, handler, false));
@ -40,8 +40,8 @@ export function on(elem, events, handler) {
* @param events * @param events
* @param handler * @param handler
* */ * */
export function once(elem, events, handler) { export function once(elem: any, events: any, handler: any) {
const listener = function (_this, args) { const listener = function (_this: any, args: any) {
handler.apply(_this, args); handler.apply(_this, args);
off(elem, events, listener); off(elem, events, listener);
}; };
@ -55,7 +55,7 @@ export function once(elem, events, handler) {
* @param events * @param events
* @param handler * @param handler
* */ * */
export function off(elem, events, handler) { export function off(elem: any, events: any, handler: any) {
[] []
.concat(events) .concat(events)
.forEach((event) => elem.removeEventListener(event, handler, false)); .forEach((event) => elem.removeEventListener(event, handler, false));

View File

@ -30,11 +30,12 @@ export default defineConfig({
assetFileNames: 'index.css', assetFileNames: 'index.css',
}, },
plugins: [ plugins: [
// @ts-ignore
babel({ babel({
exclude: 'node_modules/**', exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'], extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
presets: ['@babel/preset-env', '@babel/preset-typescript'], presets: ['@babel/preset-env', '@babel/preset-typescript'],
}), })
], ],
external: ['vue', 'vue-router'], external: ['vue', 'vue-router'],
}, },