重命名 docs 为 example

This commit is contained in:
就眠儀式
2021-11-23 11:08:40 +08:00
parent 97788e3a77
commit 4a4ee87b65
88 changed files with 14 additions and 7 deletions

View File

@@ -0,0 +1,700 @@
##### 基础
::: demo 传入 columns 数据,自动生成表格
<template>
<ele-table
:data="data"
:columns="columns"
/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
data,
columns,
}
}
}
</script>
:::
##### 索引
::: demo 通过配置 index 显示索引列,支持 columns 的参数
<template>
<ele-table
:data="data"
:columns="columns"
:index="{ label: '#' }"
/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
data,
columns,
}
}
}
</script>
:::
##### 多选
::: demo 通过配置 selection 显示多选框,支持 columns 的参数
<template>
<ele-table
:data="data"
:columns="columns"
selection
/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
data,
columns,
}
}
}
</script>
:::
##### 展开
::: demo 通过配置 expand 开启展开插槽,通过 #expand 插槽定制显示内容,支持 columns 的参数
<template>
<ele-table
:data="data"
:columns="columns"
expand
>
<template #expand="{ row }">
{{ row }}
</template>
</ele-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
data,
columns,
}
}
}
</script>
:::
##### 操作
::: demo 通过配置 menu 开启按钮插槽,通过 #menu 插槽定制显示内容,支持 columns 的参数
<template>
<ele-table
:data="data"
:columns="columns"
:menu="menu"
>
<template #menu="{ size }">
<el-button
:size="size"
type="text"
>
详情
</el-button>
</template>
</ele-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const menu = ref({
label: '操作',
align: 'center',
})
const columns = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
menu,
data,
columns,
}
}
}
</script>
:::
##### 插槽
::: demo
<template>
<ele-table
:data="data"
:columns="columns3"
>
<template #name-header="{ column }">
<s>{{ column.label }}</s>
</template>
<template #name="{ row, size }">
<el-tag :size="size">
{{ row?.name }}
</el-tag>
</template>
<template #menu="{ size }">
<el-button
:size="size"
type="text"
>
详情
</el-button>
</template>
</ele-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns3 = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
slot: true,
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
data,
columns3,
}
}
}
</script>
:::
##### 分页
::: demo 当传入 total 数据时,将自动显示分页。可以通过 `v-model:current-page` 绑定当前页数、通过 `v-model:page-size` 绑定每页显示条目个数
<template>
<ele-table
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:data="data"
:columns="columns"
:total="total"
/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(50)
const columns = ref([
{
label: '日期',
prop: 'date',
},
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
currentPage,
pageSize,
total,
data,
columns,
}
}
}
</script>
:::
##### 多级
::: demo 通过 columns 的 `children` 配置多级表头
<template>
<ele-table
:data="data"
:columns="columns2"
/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns2 = ref([
{
label: '日期',
prop: 'date',
},
{
label: '用户',
children: [
{
label: '姓名',
prop: 'name',
},
{
label: '地址',
prop: 'address',
},
],
},
])
const data = ref([
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
])
return {
data,
columns2,
}
}
}
</script>
:::
##### 配置
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| :---------------------- | :------------------------------------------------------------------ | :------------------------------------------------------ | :----------------------------- | :--------------------------------------------------- |
| data | 显示的数据 | array | - | - |
| columns | 自动生成表单的参数,参考下面 columns | array | - | - |
| selection | 显示多选框,支持 columns 的配置 | boolean / object | - | false |
| index | 显示索引,支持 columns 的配置 | boolean / object | - | false |
| expand | 开启展开插槽,支持 columns 的配置 | boolean / object | - | false |
| menu | 开启操作按钮插槽,支持 columns 的配置 | boolean / object | - | false |
| show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | boolean | - | false |
| align | 对齐方式 | string | left / center / right | left |
| header-align | 表头对齐方式 | string | left / center / right | 同 align |
| total | 总条目数 | number | - | - |
| current-page | 当前页数,可以通过 `v-model:current-page` 绑定值 | number | - | - |
| page-size | 每页显示条目个数,可以通过 `v-model:page-size` 绑定值 | number | - | - |
| pagination | pagination 的配置,同 el-pagination | object | - | [参考全局配置](../guide/index#全局配置) |
| height | Table 的高度 | string / number | - | 自动高度 |
| max-height | Table 的最大高度 | string / number | - | - |
| stripe | 是否为斑马纹 table | boolean | - | false |
| border | 是否带有纵向边框 | boolean | - | false |
| size | Table 的尺寸 | string | medium / small / mini | - |
| fit | 列的宽度是否自撑开 | boolean | - | true |
| show-header | 是否显示表头 | boolean | - | true |
| highlight-current-row | 是否要高亮当前行 | boolean | - | false |
| current-row-key | 当前行的 key只写属性 | string / number | - | - |
| row-class-name | 为行增加 className | Function({row, rowIndex}) / string | - | - |
| row-style | 为行增加 style | Function({row, rowIndex}) / object | - | - |
| cell-class-name | 为单元格增加 className | Function({row, column, rowIndex, columnIndex}) / string | - | - |
| cell-style | 为单元格增加 style | Function({row, column, rowIndex, columnIndex}) / object | - | - |
| header-row-class-name | 为表头行增加 className | Function({row, rowIndex}) / string | - | - |
| header-row-style | 为表头行增加 style | Function({row, rowIndex}) / object | - | - |
| header-cell-class-name | 为表头单元格增加 className | Function({row, column, rowIndex, columnIndex}) / string | - | - |
| header-cell-style | 为表头单元格增加 style | Function({row, column, rowIndex, columnIndex}) / object | - | - |
| row-key | 行数据的 Key使用 reserveSelection 功能时必填 | Function(row) / string | - | - |
| empty-text | 空数据时显示的文本内容 | string | - | 暂无数据 |
| default-expand-all | 是否默认展开所有行 | boolean | - | false |
| expand-row-keys | Table 目前的展开行,与 row-key 配合使用 | array | - | - |
| default-sort | 默认的排序列的 prop 和顺序 | Object | `order`: ascending, descending | ascending |
| tooltip-effect | tooltip `effect` 属性 | String | dark / light | - |
| show-summary | 是否在表尾显示合计行 | Boolean | - | false |
| sum-text | 合计行第一列的文本 | String | - | 合计 |
| summary-method | 自定义的合计计算方法 | Function({ columns, data }) | - | - |
| span-method | 合并行或列的计算方法 | Function({ row, column, rowIndex, columnIndex }) | - | - |
| select-on-indeterminate | 当仅有部分行被选中时,点击表头的多选框时的行为,配合 selection 使用 | boolean | - | true |
| indent | 展示树形数据时,树节点的缩进 | number | - | 16 |
| lazy | 是否懒加载子节点数据 | boolean | - | - |
| load | 加载子节点数据的函数lazy 为 true 时生效 | Function(row, treeNode, resolve) | - | - |
| tree-props | 渲染嵌套数据的配置选项 | Object | - | { hasChildren: 'hasChildren', children: 'children' } |
##### 参数
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| :------------------ | :-------------------------------------------------------------------- | :-------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :-------------------------------- |
| prop | 对应 data 的字段名 (**必填,需要是唯一值**) | string | - | - |
| label | 显示的标题 | string | - | - |
| slot | 是否开启自定义插槽功能 | boolean | - | false |
| hide | 是否在表格中隐藏 | boolean | - | false |
| children | 实现多级表头 | array | - | - |
| columnKey | 当前项的 key使用 filter-change 事件时需要 | string | - | - |
| width | 对应列的宽度 | string | - | - |
| minWidth | 对应列的最小宽度 | string | - | - |
| fixed | 列是否固定true 表示固定在左侧 | string / boolean | true / left / right | - |
| renderHeader | 列标题 Label 区域渲染使用的 Function | Function(h, { column, $index }) | - | - |
| sortable | 对应列是否可以排序 | boolean / string | true / false / 'custom' | false |
| sortMethod | 对数据进行排序的时候使用的方法 | Function(a, b) | - | - |
| sortBy | 指定数据按照哪个属性进行排序 | string / array / Function(row, index) | - | - |
| sortOrders | 数据在排序时所使用排序策略的轮转顺序 | array | `ascending` 表示升序,`descending` 表示降序,`null` 表示还原为原始顺序 | ['ascending', 'descending', null] |
| resizable | 对应列是否可以通过拖动改变宽度,配合 border 使用 | boolean | - | true |
| formatter | 用来格式化内容 | Function(row, column, cellValue, index) | - | - |
| showOverflowTooltip | 当内容过长被隐藏时显示 tooltip | Boolean | - | false |
| align | 对齐方式 | string | left / center / right | left |
| headerAlign | 表头对齐方式 | string | left / center / right | 同 align |
| className | 列的 className | string | - | - |
| labelClassName | 当前列标题的自定义类名 | string | - | - |
| filters | 数据过滤的选项 | Array[{ text, value }] | - | - |
| filterPlacement | 过滤弹出框的定位 | string | top / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end | - |
| filterMultiple | 数据过滤的选项是否多选 | boolean | - | true |
| filterMethod | 数据过滤使用的方法 | Function(value, row, column) | - | - |
| filteredValue | 选中的数据过滤项 | array | - | - |
| index | 自定义索引,只能够在 index 中配置 | Function(index) / number | - | - |
| selectable | 这一行的 CheckBox 是否可以勾选,只能够在 selection 中配置 | Function(row, index) | - | - |
| reserveSelection | 是否保留之前选中的数据(需指定 `row-key`),只能够在 selection 中配置 | boolean | - | false |
##### 事件
| 事件名 | 说明 | 参数 |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| select | 当用户手动勾选数据行的 Checkbox 时触发的事件 | selection, row |
| select-all | 当用户手动勾选全选 Checkbox 时触发的事件 | selection |
| selection-change | 当选择项发生变化时会触发该事件 | selection |
| cell-mouse-enter | 当单元格 hover 进入时会触发该事件 | row, column, cell, event |
| cell-mouse-leave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |
| cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
| cell-dblclick | 当某个单元格被双击击时会触发该事件 | row, column, cell, event |
| row-click | 当某一行被点击时会触发该事件 | row, column, event |
| row-contextmenu | 当某一行被鼠标右键点击时会触发该事件 | row, column, event |
| row-dblclick | 当某一行被双击时会触发该事件 | row, column, event |
| header-click | 当某一列的表头被点击时会触发该事件 | column, event |
| header-contextmenu | 当某一列的表头被鼠标右键点击时触发该事件 | column, event |
| sort-change | 当表格的排序条件发生变化的时候会触发该事件 | { column, prop, order } |
| filter-change | 当表格的筛选条件发生变化的时候会触发该事件,参数的值是一个对象,对象的 key 是 column 的 columnKey对应的 value 为用户选择的筛选条件的数组。 | filters |
| current-change | 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性 | currentRow, oldCurrentRow |
| header-dragend | 当拖动表头改变了列的宽度的时候会触发该事件 | newWidth, oldWidth, column, event |
| expand-change | 当用户对某一行展开或者关闭的时候会触发该事件(展开行时,回调的第二个参数为 expandedRows树形表格时第二参数为 expanded | row, (expandedRows \| expanded) |
| size-change | pageSize 改变时会触发 | 每页条数 |
| current-change | currentPage 改变时会触发 | 当前页 |
| prev-click | 用户点击上一页按钮改变当前页后触发 | 当前页 |
| next-click | 用户点击下一页按钮改变当前页后触发 | 当前页 |
##### 方法
| 方法名 | 说明 | 参数 |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| clearSelection | 用于多选表格,清空用户的选择 | - |
| toggleRowSelection | 用于多选表格切换某一行的选中状态如果使用了第二个参数则是设置这一行选中与否selected 为 true 则选中) | row, selected |
| toggleAllSelection | 用于多选表格,切换全选和全不选 | - |
| toggleRowExpansion | 用于可展开表格与树形表格切换某一行的展开状态如果使用了第二个参数则是设置这一行展开与否expanded 为 true 则展开) | row, expanded |
| setCurrentRow | 用于单选表格,设定某一行为选中行,如果调用时不加参数,则会取消目前高亮行的选中状态。 | row |
| clearSort | 用于清空排序条件,数据会恢复成未排序的状态 | - |
| clearFilter | 不传入参数时用于清空所有过滤条件,数据会恢复成未过滤的状态,也可传入由 columnKey 组成的数组以清除指定列的过滤条件 | columnKey |
| doLayout | 对 Table 进行重新布局。当 Table 或其祖先元素由隐藏切换为显示时,可能需要调用此方法 | - |
| sort | 手动对 Table 进行排序。参数`prop`属性指定排序列,`order`指定排序顺序。 | prop: string, order: string |
::: tip 提示
如果使用 `typescript` 可以从组件中导出 `ITableExpose` 提供更好的类型推导
:::
### 插槽
| name | 说明 |
| :------------ | :----------------------------------------------------------------------- |
| - | 在右侧菜单前插入的任意内容 |
| menu | 表格右侧自定义按钮,参数为 { size, row, column, $index } |
| expand | 当 expand 为 true 时,配置展开显示的内容,参数为 { row, column, $index } |
| append | 插入至表格最后一行之后的内容 |
| [prop] | 当前这列的内容,参数为 { size, row, column, $index } |
| [prop]-header | 当前这列表头的内容,参数为 { size, column, $index } |
::: tip 提示
[prop] 为 columns 中定义的 prop
:::

View File

@@ -0,0 +1 @@
##### 介绍

View File

@@ -0,0 +1,5 @@
##### 安装
```
npm install layui-vue --save
```

View File

@@ -0,0 +1,94 @@
::: title 基础使用
:::
::: demo
<template>
<div class="anim">
<ul class="layui-border-box site-doc-icon site-doc-anim">
<li style="height:auto">
<div class="layui-anim layui-anim-down">顶部往下滑入</div>
<div class="code">layui-anim-down</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-downbit">微微往下滑入</div>
<div class="code">layui-anim-downbit</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-up">底部往上滑入</div>
<div class="code">layui-anim-up</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-upbit">微微往上滑入</div>
<div class="code">layui-anim-upbit</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-scale">平滑放大</div>
<div class="code">layui-anim-scale</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-scaleSpring">弹簧式放大</div>
<div class="code">layui-anim-scaleSpring</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-scalesmall">平滑放小</div>
<div class="code">layui-anim-scalesmall</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-scalesmall-spring">弹簧式放小</div>
<div class="code">layui-anim-scalesmall-spring</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-fadein">渐现</div>
<div class="code">layui-anim-fadein</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-fadeout">渐隐</div>
<div class="code">layui-anim-fadeout</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-rotate">360度旋转</div>
<div class="code">layui-anim-rotate</div>
</li>
<li style="height:auto">
<div class="layui-anim layui-anim-rotate layui-anim-loop">循环动画</div>
<div class="code">追加layui-anim-loop</div>
</li>
</ul>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 动画类名
:::
::: table
| 类名 | 描述 | 使用 |
| --------------------------------- | ------------ | ---------------------------------------------- |
| layui-anim-down | 顶部往下滑入 | `layui-anim layui-anim-down` |
| layui-anim-downbit | 微微往下滑入 | `layui-anim layui-anim-downbit` |
| layui-anim-up | 底部往上滑入 | `layui-anim layui-anim-up` |
| layui-anim-upbit | 微微往上滑入 | `layui-anim ayui-anim-upbit` |
| layui-anim-scale | 平滑放大 | `layui-anim layui-anim-scale` |
| layui-anim-scaleSpring | 弹簧式放大 | `layui-anim layui-anim-scaleSpring` |
| layui-anim-scalesmall | 平滑放小 | `layui-anim layui-anim-scalesmall` |
| layui-anim-scalesmall-spring | 弹簧式放小 | `layui-anim layui-anim-scalesmall-spring` |
| layui-anim-fadein | 渐现 | `layui-anim layui-anim-fadein` |
| layui-anim-fadeout | 渐隐 | `layui-anim layui-anim-fadeout` |
| layui-anim-rotate | 360 度旋转 | `layui-anim layui-anim-rotate` |
| layui-anim-rotate layui-anim-loop | 循环动画 | `layui-anim layui-anim-rotate layui-anim-loop` |
:::

View File

@@ -0,0 +1,94 @@
::: title 基础使用
:::
::: demo
<template>
<lay-avatar :src="src"></lay-avatar>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const src = ref("https://portrait.gitee.com/uploads/avatars/user/2813/8441097_shaynas_1610801433.png")
return {
src
}
}
}
</script>
:::
::: title 圆角头像
:::
::: demo
<template>
<lay-avatar :src="src" radius></lay-avatar>
</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 尺寸大小
:::
::: demo
<template>
<lay-avatar :src="src" size="xs"></lay-avatar>
<lay-avatar :src="src" size="sm"></lay-avatar>
<lay-avatar :src="src"></lay-avatar>
<lay-avatar :src="src" size="lg"></lay-avatar>
</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 头像属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ------ | ---- | -------------- |
| src | 图源 | -- |
| size | 尺寸 | `xs` `sm` `lg` |
| radius | 圆形 | `true` `false` |
:::

View File

@@ -0,0 +1,49 @@
::: title 基础使用
:::
::: demo
<template>
<lay-badge type="dot"></lay-badge>&nbsp;
<lay-badge type="dot" theme="orange"></lay-badge>&nbsp;
<lay-badge type="dot" theme="green"></lay-badge>&nbsp;
<lay-badge type="dot" theme="cyan"></lay-badge>&nbsp;
<lay-badge type="dot" theme="blue"></lay-badge>&nbsp;
<lay-badge type="dot" theme="black"></lay-badge>&nbsp;
<lay-badge type="dot" theme="gray"></lay-badge>&nbsp;
<lay-badge >赤</lay-badge>&nbsp;
<lay-badge theme="orange">橙</lay-badge>&nbsp;
<lay-badge theme="green">绿</lay-badge>&nbsp;
<lay-badge theme="cyan">青</lay-badge>&nbsp;
<lay-badge theme="blue">蓝</lay-badge>&nbsp;
<lay-badge theme="black">黑</lay-badge>&nbsp;
<lay-badge theme="gray">灰</lay-badge>&nbsp;
<lay-badge type="rim">6</lay-badge>&nbsp;
<lay-badge type="rim">Hot</lay-badge>&nbsp;
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 徽章属性
:::
::: table
| | | |
| ----- | ---- | --------------------------------------------- |
| type | 类型 | `dot` `rim` |
| theme | 主题 | `orange` `green` `cyan` `blue` `black` `gray` |
:::

View File

@@ -0,0 +1,59 @@
::: title 基础使用
:::
::: demo
<template>
<lay-block>引用区域的文字</lay-block>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 灰色主题
:::
::: demo
<template>
<lay-block :nm="nm">引用区域的文字</lay-block>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const nm = ref(true)
return {
nm
}
}
}
</script>
:::
::: title Block 属性
:::
::: table
| Name | Description | Accepted Values |
| ---- | ----------- | --------------- |
| nm | 灰色样式 | -- |
:::

View File

@@ -0,0 +1,102 @@
::: title 基础使用
:::
::: demo
<template>
<lay-breadcrumb>
<lay-breadcrumb-item title="工作空间"></lay-breadcrumb-item>
<lay-breadcrumb-item title="控制台"></lay-breadcrumb-item>
<lay-breadcrumb-item title="访问量"></lay-breadcrumb-item>
</lay-breadcrumb>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 指定分割
:::
::: demo
<template>
<lay-breadcrumb separator=">">
<lay-breadcrumb-item title="热门音乐"></lay-breadcrumb-item>
<lay-breadcrumb-item title="王杰"></lay-breadcrumb-item>
<lay-breadcrumb-item title="谁明浪子心"></lay-breadcrumb-item>
</lay-breadcrumb>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 使用插槽
:::
::: demo
<template>
<lay-breadcrumb separator="--">
<lay-breadcrumb-item>今天</lay-breadcrumb-item>
<lay-breadcrumb-item>有些</lay-breadcrumb-item>
<lay-breadcrumb-item>不开心</lay-breadcrumb-item>
</lay-breadcrumb>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 面包屑属性
:::
::: table
| 属性 | 描述 | 默认值 |
| --------- | ------ | ------ |
| separator | 分割符 | `/` |
:::
::: title 面包屑插槽
:::
::: table
| 插槽 | 描述 | 默认值 |
| ------- | -------- | ------ |
| default | 默认插槽 | `--` |
:::

View File

@@ -0,0 +1,307 @@
::: title 基础使用
:::
::: demo 使用 lay-button 标签, 创建一个按钮
<template>
<lay-button type="primary">原始按钮</lay-button>
<lay-button type="default">默认按钮</lay-button>
<lay-button type="normal">百搭按钮</lay-button>
<lay-button type="warm">暖色按钮</lay-button>
<lay-button type="danger">警告按钮</lay-button>
<lay-button type="disabled">禁用按钮</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 简约按钮
:::
::: demo 使用 border 属性设置 主要按钮 边框主题
<template>
<lay-button type="primary">原始按钮</lay-button>
<lay-button type="primary" border="green">默认按钮</lay-button>
<lay-button type="primary" border="blue">百搭按钮</lay-button>
<lay-button type="primary" border="orange">暖色按钮</lay-button>
<lay-button type="primary" border="red">警告按钮</lay-button>
<lay-button type="primary" border="black">禁用按钮</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 按钮尺寸
:::
::: demo 传入 size 属性, 创建指定尺寸的按钮, 可选值 `lg` `sm` `xs`
<template>
<lay-button type="primary" size="lg">原始按钮</lay-button>
<lay-button type="default" size="lg">默认按钮</lay-button>
<lay-button type="normal" size="lg">百搭按钮</lay-button>
<lay-button type="warm" size="lg">暖色按钮</lay-button>
<lay-button type="danger" size="lg">警告按钮</lay-button>
<lay-button type="disabled" size="lg">禁用按钮</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 流式按钮
:::
::: demo 传入 fluid 属性, 创建最大化按钮
<template>
<lay-button type="primary" fluid>最大化按钮</lay-button>
<br/>
<br/>
<lay-button type="default" fluid>最大化按钮</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 圆角按钮
:::
::: demo 传入 radius 属性,创建圆角按钮
<template>
<lay-button type="primary" radius>原始按钮</lay-button>
<lay-button type="default" radius>默认按钮</lay-button>
<lay-button type="normal" radius>百搭按钮</lay-button>
<lay-button type="warm" radius>暖色按钮</lay-button>
<lay-button type="danger" radius>警告按钮</lay-button>
<lay-button type="disabled" radius>禁用按钮</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 按钮分组
:::
::: demo 使用 lay-button-group 标签, 创建一个按钮组
<template>
<div>
<lay-button-group>
<lay-button type="default">默认按钮</lay-button>
<lay-button type="default">默认按钮</lay-button>
<lay-button type="default">默认按钮</lay-button>
</lay-button-group>
<lay-button-group>
<lay-button type="primary">默认按钮</lay-button>
<lay-button type="primary">默认按钮</lay-button>
<lay-button type="primary">默认按钮</lay-button>
</lay-button-group>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 图标按钮
:::
::: demo 结合 lay-icon 组件, 创建图标按钮
<template>
<lay-button-container>
<lay-button type="primary"><lay-icon type="layui-icon-left"></lay-icon></lay-button>
<lay-button type="primary"><lay-icon type="layui-icon-right"></lay-icon></lay-button>
</lay-button-container>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 按钮容器
:::
::: demo 使用 lay-button-container 标签, 创建一个按钮容器
<template>
<lay-button-container>
<lay-button type="default">新增</lay-button>
<lay-button type="default">删除</lay-button>
<lay-button type="default">修改</lay-button>
</lay-button-container>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 加载按钮
:::
::: demo 传入 loading 属性, 控制按钮的加载状态
<template>
<lay-button-container>
<lay-button type="default" :loading="loading">加载</lay-button>
<lay-switch v-model="loading"></lay-switch>
</lay-button-container>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const loading = ref(true)
return {
loading
}
}
}
</script>
:::
::: title 事件处理
:::
::: demo 使用 @click 设置单击回调
<template>
<lay-button type="default" @click="clickHandle">单击事件</lay-button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const clickHandle = function() {
console.log('点击事件')
}
return {
clickHandle
}
}
}
</script>
:::
::: title 按钮属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ------ | ------ | --------------------------------------------- |
| type | 主题 | `primary` `normal` `warm` `danger` `disabled` |
| size | 尺寸 | `lg` `sm` `xs` |
| fluid | 最大化 | `true` `false` |
| radius | 圆角 | `true` `false` |
| border | 边框 | `green` `blue` `orange` `red` `black` |
:::
::: title 按钮事件
:::
::: table
| 事件 | 描述 | 参数 |
| ----- | -------- | ---- |
| click | 单击事件 | `--` |
:::

View File

@@ -0,0 +1,129 @@
::: title 基础使用
:::
::: demo
<template>
<div class="card-container">
<lay-card title="标题">
内容
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 卡片插槽
:::
::: demo
<template>
<div class="card-container">
<lay-card>
<template v-slot:header>
标题
</template>
<template v-slot:body>
内容
</template>
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 简单使用
:::
::: demo
<template>
<div class="card-container">
<lay-card>
内容
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 卡片属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----- | ---- | ------ |
| title | 标题 | -- |
:::
::: title 卡片插槽
:::
::: table
| 插槽 | 描述 | 可选值 |
| ------ | -------- | ------ |
| header | 头部插槽 | -- |
| body | 内容插槽 | -- |
:::

View File

@@ -0,0 +1,141 @@
::: title 基础使用
:::
::: demo
<template>
<lay-carousel v-model="active">
<lay-carousel-item id="1">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目一</div>
</lay-carousel-item>
<lay-carousel-item id="2">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目二</div>
</lay-carousel-item>
<lay-carousel-item id="3">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目三</div>
</lay-carousel-item>
<lay-carousel-item id="4">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目四</div>
</lay-carousel-item>
</lay-carousel>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active = ref("1")
return {
active
}
}
}
</script>
:::
::: title 不同方向
:::
::: demo
<template>
<lay-carousel v-model="active" anim="updown">
<lay-carousel-item id="1">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目一</div>
</lay-carousel-item>
<lay-carousel-item id="2">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目二</div>
</lay-carousel-item>
<lay-carousel-item id="3">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目三</div>
</lay-carousel-item>
<lay-carousel-item id="4">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目四</div>
</lay-carousel-item>
</lay-carousel>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active = ref("1")
return {
active
}
}
}
</script>
:::
::: title 控制位置
:::
::: demo
<template>
<lay-carousel v-model="active" indicator="outside">
<lay-carousel-item id="1">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目一</div>
</lay-carousel-item>
<lay-carousel-item id="2">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目二</div>
</lay-carousel-item>
<lay-carousel-item id="3">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目三</div>
</lay-carousel-item>
<lay-carousel-item id="4">
<div style="color: white;text-align: center;width:100%;height:300px;line-height:300px;background-color:#79C48C;">条目四</div>
</lay-carousel-item>
</lay-carousel>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active = ref("1")
return {
active
}
}
}
</script>
:::
::: title 轮播属性
:::
::: table
| 属性 | 描述 | 可选值 |
| --------- | ------------ | ------------------------- |
| v-model | 当前激活项 | `--` |
| anim | 切换方向 | `default` `updown` |
| indicator | 控制器位置 | `inside` `outside` `none` |
| arrow | 切换按钮状态 | `hover` `always` `none` |
:::
::: title 轮播事件
:::
::: table
| 事件 | 描述 | 可选值 |
| ------ | -------- | ------ |
| change | 切换回调 | id |
:::

View File

@@ -0,0 +1,212 @@
::: title 基础使用
:::
::: demo
<template>
<lay-form>
<lay-checkbox name="like" skin="primary" v-model="checked1" label="1" ></lay-checkbox>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const checked1 = ref(false)
return {
checked1
}
}
}
</script>
:::
::: title 默认样式
:::
::: demo
<template>
<lay-form>
<lay-checkbox name="like" label="1" v-model="checked2" >普通</lay-checkbox>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const checked2 = ref(false)
return {
checked2
}
}
}
</script>
:::
::: title 复选框组
:::
::: demo
<template>
<lay-form>
<lay-checkbox-group v-model="checkeds" @change="groupChange">
<lay-checkbox name="like" skin="primary" label="1">写作</lay-checkbox>
<lay-checkbox name="like" skin="primary" label="2">画画</lay-checkbox>
<lay-checkbox name="like" skin="primary" label="3">运动</lay-checkbox>
</lay-checkbox-group>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const checkeds = ref(['1','2']);
const groupChange = function(val) {
console.log("回调:" + JSON.stringify(val))
}
return {
checkeds,
groupChange
}
}
}
</script>
:::
::: title 完整案例
:::
::: demo
<template>
<lay-form>
<lay-checkbox name="like" skin="primary" v-model="checked3" label="1">写作</lay-checkbox>
<lay-checkbox name="like" skin="primary" v-model="checked4" label="2">画画</lay-checkbox>
<lay-checkbox name="like" skin="primary" v-model="checked5" label="3">运动</lay-checkbox>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const checked3 = ref(true);
const checked4 = ref(true);
const checked5 = ref(true);
return {
checked3, checked4, checked5
}
}
}
</script>
:::
::: title 禁用状态
:::
::: demo
<template>
<lay-form>
<lay-checkbox name="like" skin="primary" label="1" :disabled="disabled" v-model="checked6">禁用</lay-checkbox>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const disabled = ref(true)
const checked6 = ref(false);
return {
disabled,checked6
}
}
}
</script>
:::
::: title 事件回调
:::
::: demo
<template>
<lay-form>
<lay-checkbox name="like" skin="primary" label="1" @change="change" v-model="checked7">回调</lay-checkbox>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const checked7 = ref(true);
const change = function(isChecked) {
console.log("是否选中:" + isChecked)
}
return {
change,
checked7
}
}
}
</script>
:::
::: title 复选框属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ------------------- | ------------- | -------------------- |
| name | 原始属性 name | -- |
| skin | 主题 | -- |
| label | 选中值 | -- |
| v-model | 是否选中 | `true` `false` |
| change | 切换事件 | isChecked : 当前状态 |
:::
::: title 复选框事件
:::
::: table
| 事件 | 描述 | 可选值 |
| ------ | -------- | -------------------- |
| change | 切换事件 | isChecked : 当前状态 |
:::

View File

@@ -0,0 +1,52 @@
::: title 基础使用
:::
::: demo
<template>
<lay-collapse :openKeys="openKeys">
<lay-collapse-item title="标题" id="1"> 内容 </lay-collapse-item>
<lay-collapse-item title="标题" id="2"> 内容 </lay-collapse-item>
<lay-collapse-item title="标题" id="3"> 内容 </lay-collapse-item>
</lay-collapse>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const openKeys = ref(["1","2","3"])
return {
openKeys
}
}
}
</script>
:::
::: title Collapse 属性
:::
::: table
| Name | Description | Accepted Values |
| -------- | ----------- | --------------- |
| openKeys | 打开的目录 | `array` |
:::
::: title Collapse-item 属性
:::
::: table
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| id | 编号 | -- |
| title | 标题 | -- |
:::

View File

@@ -0,0 +1,162 @@
::: title 主色调
:::
::: demo
<template>
<ul class="layui-row layui-col-space15">
<li class="layui-col-sm6">
<div style="background-color: #009688;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#009688</p><p>
</p><p tips="">主色调之一</p>
</div>
</li>
<li class="layui-col-sm6">
<div style="background-color: #5FB878;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#5FB878</p><p>
</p><p tips="">一般用于选中状态</p>
</div>
</li>
<li class="layui-col-sm6">
<div style="background-color: #393D49;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#393D49</p><p>
</p><p tips="">通常用于导航</p>
</div>
</li>
<li class="layui-col-sm6">
<div style="background-color: #1E9FFF;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#1E9FFF</p><p>
</p><p tips="">经典蓝</p>
</div>
</li>
</ul>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 次色调
:::
::: demo
<template>
<ul class="layui-row layui-col-space15">
<li class="layui-col-sm6">
<div style="background-color: #FFB800;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#FFB800</p><p>
</p><p tips="">暖色系</p>
</div>
</li>
<li class="layui-col-sm6">
<div style="background-color: #FF5722;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#FF5722</p><p>
</p><p tips="">比较引人注意的颜色</p>
</div>
</li>
<li class="layui-col-sm6">
<div style="background-color: #01AAED;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#01AAED</p><p>
</p><p tips="">文本链接着色</p>
</div>
</li>
<li class="layui-col-sm6">
<div style="background-color: #2F4056;padding:10px;color:whitesmoke;padding:30px;border-radius:2px;">
<p>#2F4056</p><p>
</p><p tips="">侧边色</p>
</div>
</li>
</ul>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 中性色
:::
::: demo
<template>
<ul class="layui-row site-doc-color site-doc-necolor">
<li class="layui-col-md12">
<div style="background-color: #FAFAFA;">
<p>#FAFAFA</p><p>
</p></div>
</li>
<li class="layui-col-md12">
<div style="background-color: #f6f6f6;"><p>#F6F6F6</p><p></p></div>
</li>
<li class="layui-col-md4">
<div style="background-color: #eeeeee;"><p>#eeeeee</p><p></p></div>
</li>
<li class="layui-col-md4">
<div style="background-color: #e2e2e2;"><p>#e2e2e2</p><p></p></div>
</li>
<li class="layui-col-md4">
<div style="background-color: #dddddd;"><p>#dddddd</p><p></p></div>
</li>
<li class="layui-col-md4">
<div style="background-color: #d2d2d2;"><p>#d2d2d2</p><p></p></div>
</li>
<li class="layui-col-md4">
<div style="background-color: #cccccc;"><p>#cccccc</p><p></p></div>
</li>
<li class="layui-col-md4">
<div style="background-color: #c2c2c2;"><p>#c2c2c2</p><p></p></div>
</li>
</ul>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 颜色说明
:::
::: table
| Class | 描述 | 使用 |
| --------------- | ---- | ----------------------- |
| layui-bg-red | 赤色 | class="layui-bg-red" |
| layui-bg-orange | 橙色 | class="layui-bg-orange" |
| layui-bg-green | 墨绿 | class="layui-bg-green" |
| layui-bg-cyan | 藏青 | class="layui-bg-cyan" |
| layui-bg-blue | 蓝色 | class="layui-bg-blue" |
| layui-bg-black | 雅黑 | class="layui-bg-black" |
:::

View File

@@ -0,0 +1,30 @@
::: title 基础使用
:::
::: demo
<template>
<lay-color-picker></lay-color-picker>
</template>
<script>
export default {
setup() {
return {
}
}
}
</script>
::: title icon-picker 属性
:::
::: table
| | | |
| ---------- | -------- | --- |
| v-model | 默认值 | -- |
| page | 开启分页 | -- |
| showSearch | 启用搜索 | -- |
:::

View File

@@ -0,0 +1,77 @@
::: title 普通容器
:::
::: demo
<template>
<lay-container>
<div class="container-demo"></div>
</lay-container>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.container-demo {
width:100%;
height: 300px;
background: #79C48C;
border-radius: 2px;
}
</style>
:::
::: title 流式容器
:::
::: demo
<template>
<lay-container fluid>
<div class="container-demo"></div>
</lay-container>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.container-demo {
width:100%;
height: 300px;
background: #79C48C;
}
</style>
:::
::: title 容器属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----- | ------ | -------------- |
| fluid | 流模式 | `true` `false` |
:::

View File

@@ -0,0 +1,90 @@
::: title 基础使用
:::
::: demo
<template>
<lay-dropdown>
<lay-button type="primary">下拉菜单</lay-button>
<template #content>
<lay-dropdown-item>选项一</lay-dropdown-item>
<lay-dropdown-item>选项二</lay-dropdown-item>
<lay-dropdown-item>选项三</lay-dropdown-item>
</template>
</lay-dropdown>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 触发方式
:::
::: demo
<template>
<lay-dropdown trigger="hover">
<lay-button>Hover 触发</lay-button>
<template #content>
<lay-dropdown-item>选项一</lay-dropdown-item>
<lay-dropdown-item>选项二</lay-dropdown-item>
<lay-dropdown-item>选项三</lay-dropdown-item>
</template>
</lay-dropdown>
&nbsp;&nbsp;
<lay-dropdown>
<lay-button>Click 触发</lay-button>
<template #content>
<lay-dropdown-item>选项一</lay-dropdown-item>
<lay-dropdown-item>选项二</lay-dropdown-item>
<lay-dropdown-item>选项三</lay-dropdown-item>
</template>
</lay-dropdown>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 下拉属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ------- | -------- | --------------- |
| trigger | 触发方式 | `click` `hover` |
:::
::: title 下拉插槽
:::
::: table
| 插槽 | 描述 | 可选值 |
| ------- | -------- | ------ |
| content | 下拉内容 | -- |
:::

View File

@@ -0,0 +1,56 @@
::: title 基础使用
:::
::: demo
<template>
<lay-empty></lay-empty>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 指定描述
:::
::: demo
<template>
<lay-empty description="刷新试试"></lay-empty>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title empty 属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----------- | -------- | ------ |
| description | 描述信息 | -- |
:::

View File

@@ -0,0 +1,70 @@
::: demo
<template>
<lay-field title="标题">内容</lay-field>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: demo
<template>
<lay-field title="标题">内容</lay-field>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: demo
<template>
<lay-field title="标题"></lay-field>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 字段属性
:::
::: table
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| title | 标题 | -- |
:::

View File

@@ -0,0 +1,76 @@
::: title 基础使用
:::
::: demo
<template>
<lay-form @submit="submit" :model="model">
<lay-form-item label="账户">
<lay-input v-model="model.username"></lay-input>
</lay-form-item>
<lay-form-item label="密码">
<lay-input v-model="model.password"></lay-input>
</lay-form-item>
<lay-form-item>
<lay-button naive-type="submit">提交</lay-button>
</lay-form-item>
</lay-form>
</template>
<script>
import { ref, reactive } from 'vue'
export default {
setup() {
const model = reactive({
username: "admin",
password: "admin"
})
const submit = function(val) {
alert(JSON.stringify(val))
}
return {
model,
submit
}
}
}
</script>
:::
::: title 表单事件
:::
::: table
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| model | 表单绑定值 | -- |
:::
::: title 表单事件
:::
::: table
| Name | Description | Accepted Values |
| ------ | ----------- | --------------- |
| submit | 提交事件 | -- |
:::
::: title 表单项属性
:::
::: table
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| label | 标题名称 | -- |
:::

View File

@@ -0,0 +1,166 @@
::: title 基础使用
:::
::: demo
<template>
<lay-row space="10">
<lay-col md="12"><div class="grid-demo">1</div></lay-col>
<lay-col md="12"><div class="grid-demo grid-demo-bg1">2</div></lay-col>
<lay-col md="6"><div class="grid-demo">3</div></lay-col>
<lay-col md="6"><div class="grid-demo grid-demo-bg1">4</div></lay-col>
<lay-col md="6"><div class="grid-demo">5</div></lay-col>
<lay-col md="6"><div class="grid-demo grid-demo-bg1">6</div></lay-col>
</lay-row>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.grid-demo-bg1 {
background-color: #63BA79;
}
.grid-demo {
padding: 10px;
line-height: 50px;
border-radius: 2px;
text-align: center;
background-color: #79C48C;
color: #fff;
}
</style>
:::
::: title 栅格偏移
:::
::: demo
<template>
<lay-row space="10">
<lay-col md="12"><div class="grid-demo">1</div></lay-col>
<lay-col md="6" mdOffset="6"><div class="grid-demo grid-demo-bg1">2</div></lay-col>
</lay-row>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.grid-demo-bg1 {
background-color: #63BA79;
}
.grid-demo {
padding: 10px;
line-height: 50px;
border-radius: 2px;
text-align: center;
background-color: #79C48C;
color: #fff;
}
</style>
:::
::: title 栅格适应
:::
::: demo
<template>
<lay-row space="10">
<lay-col md="12" sm="12" xs="24"><div class="grid-demo">1</div></lay-col>
<lay-col md="12" sm="12" xs="24"><div class="grid-demo grid-demo-bg1">2</div></lay-col>
</lay-row>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 流式布局
:::
::: demo
<template>
<lay-container fluid>
<lay-row space="10">
<lay-col md="4" sm="12" xs="24"><div class="grid-demo">1</div></lay-col>
<lay-col md="4" sm="12" xs="24"><div class="grid-demo grid-demo-bg1">2</div></lay-col>
<lay-col md="4" sm="12" xs="24"><div class="grid-demo">3</div></lay-col>
<lay-col md="4" sm="12" xs="24"><div class="grid-demo grid-demo-bg1">4</div></lay-col>
<lay-col md="4" sm="12" xs="24"><div class="grid-demo">5</div></lay-col>
<lay-col md="4" sm="12" xs="24"><div class="grid-demo grid-demo-bg1">6</div></lay-col>
</lay-row>
</lay-container>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 行属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----- | ---- | ------ |
| space | 间隔 | 0 - 30 |
:::
::: title 列属性
:::
::: table
| 属性 | 描述 | 可选值 |
| --------- | ------------------------------ | ------ |
| xs | 尺寸 - 超小屏幕 (手机<768px) | 0 - 12 |
| sm | 尺寸 - 小屏幕 (平板 ≥768px) | 0 - 12 |
| md | 尺寸 - 中等屏幕 (桌面 ≥992px) | 0 - 12 |
| lg | 尺寸 - 大型屏幕 (桌面 ≥1200px) | 0 - 12 |
| xs-offset | 偏移 - 超小屏幕 (手机<768px) | 0 - 12 |
| sm-offset | 偏移 - 小屏幕 (平板 ≥768px) | 0 - 12 |
| md-offset | 偏移 - 中等屏幕 (桌面 ≥992px) | 0 - 12 |
| lg-offset | 偏移 - 大型屏幕 (桌面 ≥1200px) | 0 - 12 |
:::

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
::: title 基础使用
:::
::: demo
<template>
<lay-icon-picker type="layui-icon-face-smile"></lay-icon-picker>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const icon = ref("layui-icon-home")
return {
}
}
}
</script>
:::
::: title 默认选择
:::
::: demo
<template>
<lay-icon-picker v-model="icon" type="layui-icon-face-smile"></lay-icon-picker>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const icon = ref("layui-icon-home")
return {
}
}
}
</script>
:::
::: title 开启分页
:::
::: demo
<template>
<lay-icon-picker v-model="icon" type="layui-icon-face-smile" page></lay-icon-picker>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const icon = ref("layui-icon-home")
return {
}
}
}
</script>
:::
::: title 开启搜索
:::
::: demo
<template>
<lay-icon-picker v-model="icon" type="layui-icon-face-smile" page showSearch></lay-icon-picker>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const icon = ref("layui-icon-home")
return {
}
}
}
</script>
:::
::: title icon-picker 属性
:::
::: table
| | | |
| ---------- | -------- | --- |
| v-model | 默认值 | -- |
| page | 开启分页 | -- |
| showSearch | 启用搜索 | -- |
:::

View File

@@ -0,0 +1,131 @@
::: title 基础使用
:::
::: demo
<template>
<lay-input v-model="data1"></lay-input>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const data1 = ref("内容");
return {
data1
}
}
}
</script>
:::
::: title 提示信息
:::
::: demo
<template>
<lay-input placeholder="提示信息"></lay-input>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 事件回调
:::
::: demo
<template>
<lay-input v-model="data2" @input="input"></lay-input>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const data2 = ref("Input 事件");
const input = function( val ) {
console.log("当前值:" + val)
}
return {
data2,
input
}
}
}
</script>
:::
::: title 禁止输入
:::
::: demo
<template>
<lay-input placeholder="禁止输入" :disabled="disabled"></lay-input>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const disabled = ref(true)
return {
disabled
}
}
}
</script>
:::
::: title 输入框属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----------- | ------------- | -------------- |
| name | 原始属性 name | -- |
| placeholder | 提示信息 | -- |
| disabled | 禁用 | `true` `false` |
| v-model | 值 | -- |
:::
::: title 输入框属性
:::
::: table
| 事件 | 描述 | 参数 |
| ----- | --------------- | ---------------- |
| input | 原生 input 事件 | event : 事件对象 |
| foucs | 原生 foucs 事件 | event : 事件对象 |
| blur | 原生 blur 事件 | -- |
:::

View File

@@ -0,0 +1,274 @@
::: title 基本使用
:::
::: demo
<template>
<lay-button @click="changeVisible1" type="primary">基础使用</lay-button>
<lay-layer title="基础使用" v-model:visible="visible1">
<div style="padding:10px">
这是一个基础弹窗
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible1 = ref(false)
const changeVisible1 = function() {
visible1.value = !visible1.value
}
return {
visible1
};
},
};
</script>
:::
::: title 允许拖动
:::
::: demo
<template>
<lay-button @click="changeVisible2" type="primary">允许拖动</lay-button>
<lay-layer title="允许拖动" v-model:visible="visible2" move="true">
<div style="padding:10px">
这是一个可以拖拽的弹窗
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible2 = ref(false)
const changeVisible2 = function() {
visible2.value = !visible2.value
}
return {
visible2
};
},
};
</script>
:::
::: title 放大缩小
:::
::: demo
<template>
<lay-button @click="changeVisible3" type="primary">放大缩小</lay-button>
<lay-layer title="放大缩小" v-model:visible="visible3" move="true" maxmin="true">
<div style="padding:10px">
该弹窗支持放大缩小
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible3 = ref(false)
const changeVisible3 = function() {
visible3.value = !visible3.value
}
return {
visible3
};
},
};
</script>
:::
::: title 指定位置
:::
::: demo
<template>
<lay-button @click="changeVisible4" type="primary">指定位置</lay-button>
<lay-layer title="指定位置" v-model:visible="visible4" move="true" :offset="['100px','100px']">
<div style="padding:10px">
指定弹窗显示的默认位置
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible4 = ref(false)
const changeVisible4 = function() {
visible4.value = !visible4.value
}
return {
visible4
};
},
};
</script>
:::
::: title 远程窗体
:::
::: demo
<template>
<lay-button @click="changeVisible5" type="primary">远程窗体</lay-button>
<lay-layer title="加载 Iframe 内容" width="500px" height="400px" maxmin="true" v-model:visible="visible5" move="true" :type="type5" content="http://www.pearadmin.com"></lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const type5 = ref(2)
const visible5 = ref(false)
const changeVisible5 = function() {
visible5.value = !visible5.value
}
return {
type5,
visible5
};
},
};
</script>
:::
::: title 定义操作
:::
::: demo
<template>
<lay-button @click="changeVisible6" type="primary">定义操作</lay-button>
<lay-layer title="定义操作" v-model:visible="visible6" move="true" :btn="btn6">
<div style="padding:10px">
定义一组弹窗操作按钮
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible6 = ref(false)
const btn6 = [
{text:'确认', callback: ()=>{ alert("确认事件") }},
{text:'取消', callback: ()=>{ alert("取消事件") }}
]
const changeVisible6 = function() {
visible6.value = !visible6.value
}
return {
btn6,
visible6
};
},
};
</script>
:::
::: title 开启遮盖
:::
::: demo
<template>
<lay-button @click="changeVisible7" type="primary">开启遮盖</lay-button>
<lay-layer title="开启遮盖" move="true" shade="true" v-model:visible="visible7">
<div style="padding:10px">
允许点击遮盖层关闭弹窗
</div>
</lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
const visible7 = ref(false)
const changeVisible7 = function() {
visible7.value = !visible7.value
}
return {
visible7
};
},
};
</script>
:::
::: title 弹层属性
:::
::: table
| 备注 | 描述 | 默认值 |
| --------------- | ------------- | -------------------------- |
| title | 标题 | -- |
| move | 允许拖拽 | `false` |
| maxmin | 最小化 最大化 | `false` |
| offset | 位置 | -- |
| width | 宽 | -- |
| height | 高 | -- |
| v-model:visible | 展示 隐藏 | false |
| content | 内容 | -- |
| shade | 开启遮盖 | -- |
| shadeClose | 遮盖点击关闭 | -- |
| zIndex | 自定义层级 | -- |
| type | 类型 | `1: component` `2: iframe` |
| closeBtn | 显示关闭 | true |
| btn | 按钮 | |
| btnAlign | 按钮布局 | `l` `r` `c` |
| anim | 入场动画 | `0` `-` `6` |
| isOutAnim | 关闭动画 | `true` `false` |
:::

View File

@@ -0,0 +1,186 @@
::: title 基础使用
:::
::: demo
<template>
<lay-layout>
<lay-header>header</lay-header>
<lay-body>content</lay-body>
<lay-footer>footer</lay-footer>
</lay-layout>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
return {
}
}
}
</script>
<style>
.lay-code .layui-footer,
.lay-code .layui-header {
line-height: 60px;
text-align: center;
background: #87ca9a;
color: white;
}
.lay-code .layui-side {
display: flex;
background: #77c38c;
align-items: center;
justify-content: center;
color: white;
}
.lay-code .layui-body {
display: flex;
background: #5FB878;
align-items: center;
justify-content: center;
color: white;
}
</style>
:::
::: title 左右布局
:::
::: demo
<template>
<lay-layout>
<lay-side>left</lay-side>
<lay-body>content</lay-body>
<lay-side>right</lay-side>
</lay-layout>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 后台布局
:::
::: demo
<template>
<lay-layout>
<lay-header>header</lay-header>
<lay-layout>
<lay-side>side</lay-side>
<lay-body>content</lay-body>
</lay-layout>
</lay-layout>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 复杂布局
:::
::: demo
<template>
<lay-layout>
<lay-side>side</lay-side>
<lay-layout>
<lay-header>header</lay-header>
<lay-body>body</lay-body>
<lay-footer>footer</lay-footer>
</lay-layout>
</lay-layout>
<hr>
<lay-layout>
<lay-layout>
<lay-header>header</lay-header>
<lay-body>body</lay-body>
<lay-footer>footer</lay-footer>
</lay-layout>
<lay-side>side</lay-side>
</lay-layout>
<hr>
<lay-layout>
<lay-header>Header</lay-header>
<lay-body>
<lay-layout>
<lay-side :width="160">Left</lay-side>
<lay-body>Content</lay-body>
</lay-layout>
</lay-body>
<lay-footer>Footer</lay-footer>
</lay-layout>
<hr>
<lay-layout>
<lay-header>Header</lay-header>
<lay-body>
<lay-layout>
<lay-body>Content</lay-body>
<lay-side :width="160">Right</lay-side>
</lay-layout>
</lay-body>
<lay-footer>Footer</lay-footer>
</lay-layout>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
return {
}
}
}
</script>
:::
<br>
<br>
::: title 布局组件
:::
::: table
| 组件 | 描述 | |
| ---------- | ---- | --- |
| lay-layout | 容器 | -- |
| lay-header | 顶部 | -- |
| lay-logo | 图标 | -- |
| lay-side | 侧边 | -- |
| lay-body | 内容 | -- |
| lay-footer | 底部 | -- |
:::

View File

@@ -0,0 +1,43 @@
::: demo
<template>
默认分割线
<lay-line></lay-line><br/>
赤色分割线
<lay-line theme="red"></lay-line><br/>
橙色分割线
<lay-line theme="orange"></lay-line><br/>
墨绿分割线
<lay-line theme="green"></lay-line><br/>
青色分割线
<lay-line theme="cyan"></lay-line><br/>
蓝色分割线
<lay-line theme="blue"></lay-line><br/>
黑色分割线
<lay-line theme="black"></lay-line><br/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 分割属性
:::
::: table
| Name | Description | Accepted Values |
| ----- | ----------- | --------------------------------------------- |
| theme | 主题 | `orange` `green` `cyan` `blue` `black` `gray` |
:::

View File

@@ -0,0 +1,101 @@
::: title 基础使用
:::
::: demo
<template>
<lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys">
<lay-menu-item title="首页" id="1"></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="7">
<lay-menu-child-item title="菜单一" id="4"></lay-menu-child-item>
<lay-menu-child-item title="菜单二" id="5"></lay-menu-child-item>
<lay-menu-child-item title="菜单三" id="6"></lay-menu-child-item>
</lay-menu-item>
</lay-menu>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const selectedKey = ref("5")
const openKeys = ref(["7"])
return {
selectedKey,
openKeys
}
}
}
</script>
:::
::: title 垂直导航
:::
::: demo
<template>
<lay-menu v-model:selectedKey="selectedKey" v-model:openKeys="openKeys" v-model:tree="isTree">
<lay-menu-item title="首页" id="1">
<template v-slot:title>
<router-link to="">无感</router-link>
</template>
</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="7">
<lay-menu-child-item title="菜单一" id="4"></lay-menu-child-item>
<lay-menu-child-item title="菜单二" id="5"></lay-menu-child-item>
<lay-menu-child-item title="菜单三" id="6"></lay-menu-child-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
| 属性 | 描述 | 备注 |
| ------------------- | ------ | ---- |
| v-model:selectedKey | 选中项 | -- |
| v-model:openKeys | 打开项 | -- |
:::
::: title 菜单插槽
:::
::: table
| 插槽 | 描述 | 备注 |
| ----- | -------- | ---- |
| title | 菜单标题 | -- |
:::

View File

@@ -0,0 +1,234 @@
::: title 基础使用
:::
::: demo
<template>
<lay-page :limit="limit" :total="total" :show-page="showPage"></lay-page>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(20)
const total = ref(100)
const showPage = ref(true)
return {
limit,
total,
showPage
}
}
}
</script>
:::
::: title 简单模式
:::
::: demo
<template>
<lay-page :limit="limit" :total="total"></lay-page>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(20)
const total = ref(100)
return {
limit,
total
}
}
}
</script>
:::
::: title 插槽使用
:::
::: demo
<template>
<lay-page :limit="limit" :total="total">
<template v-slot:prev>上</template>
<template v-slot:next>下</template>
</lay-page>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(20)
const total = ref(100)
return {
limit,
total
}
}
}
</script>
:::
::: title 不同主题
:::
::: demo
<template>
<lay-page :limit="limit" :total="total" :show-page="showPage" theme="red"></lay-page>
<br>
<lay-page :limit="limit" :total="total" :show-page="showPage" theme="blue"></lay-page>
<br>
<lay-page :limit="limit" :total="total" :show-page="showPage" theme="orange"></lay-page>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(20)
const total = ref(100)
const showPage = ref(true)
return {
limit,
total,
showPage
}
}
}
</script>
:::
::: title 完整分页
:::
::: demo
<template>
<lay-page :limit="limit" :total="total" :show-count="showCount" :show-page="showPage" :show-limit="showLimit" :show-refresh="showRefresh" showSkip="showSkip"></lay-page>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(20)
const total = ref(100)
const showCount = ref(true)
const showPage = ref(true)
const showLimit = ref(true)
const showRefresh = ref(true)
const showSkip = ref(true)
return {
limit,
total,
showCount,
showPage,
showLimit,
showRefresh,
showSkip
}
}
}
</script>
:::
::: title 切换事件
:::
::: demo
<template>
<lay-page :limit="limit" :total="total" @jump="jump" :show-page="showSkip"></lay-page>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const limit = ref(20)
const total = ref(100)
const showPage = ref(true)
const jump = function({ current }) {
console.log("当前页:" + current)
}
return {
limit,
total,
jump,
showPage
}
}
}
</script>
:::
::: title 分页属性
:::
::: table
| 属性 | 描述 | 默认值 |
| ----------- | ------------ | ------- |
| limit | 每页数量 | -- |
| total | 总条数 | -- |
| showCount | 显示总数 | `false` |
| showPage | 显示每页 | `false` |
| showLimit | 显示每页数量 | `false` |
| showRefresh | 显示刷新按钮 | `false` |
| showSkip | 显示跳转 | `false` |
:::
::: title 分页事件
:::
::: table
| 事件 | 描述 | 参数 |
| ---- | -------- | --------------------- |
| jump | 切换回调 | { current: 当前页面 } |
:::
::: title 分页插槽
:::
::: table
| 插槽 | 描述 | 默认值 |
| ---- | ------ | ------ |
| prev | 上一页 | 上一页 |
| next | 下一页 | 下一页 |
:::

View File

@@ -0,0 +1,33 @@
::: title 基础使用
:::
::: demo
<template>
<lay-panel><div style="padding: 30px;">面板</div></lay-panel>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 面板插槽
:::
::: table
| 插槽 | 描述 | 可选值 |
| ------- | -------- | ------ |
| default | 默认插槽 | -- |
:::

View File

@@ -0,0 +1,127 @@
::: title 基础使用
:::
::: demo
<template>
<lay-progress percent="70"></lay-progress>
<br>
<lay-progress percent="60"></lay-progress>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 尺寸大小
:::
::: demo
<template>
<lay-progress percent="40" size="big"></lay-progress>
<br>
<lay-progress percent="60" size="big" theme="green"></lay-progress>
<br>
<lay-progress percent="80" size="big" theme="cyan"></lay-progress>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 指定主题
:::
::: demo
<template>
<lay-progress percent="60" theme="red"></lay-progress>
<br>
<lay-progress percent="60" theme="orange"></lay-progress>
<br>
<lay-progress percent="60" theme="green"></lay-progress>
<br>
<lay-progress percent="60" theme="blue"></lay-progress>
<br>
<lay-progress percent="60" theme="cyan"></lay-progress>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 显示文字
:::
::: demo
<template>
<lay-progress percent="80" :show-text="showText"></lay-progress>
<br/>
<br/>
<lay-progress percent="80" :show-text="showText" text="销售量"></lay-progress>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const showText = ref(true)
return {
showText
}
}
}
</script>
:::
::: title 进度属性
:::
::: table
| 属性 | 描述 | 可选值 |
| -------- | -------- | --------------------------------------------- |
| percent | 进度 | -- |
| theme | 主题 | `orange` `green` `cyan` `blue` `black` `gray` |
| size | 尺寸 | `big` |
| text | 提示 | -- |
| color | 颜色 | -- |
| showText | 展示描述 | -- |
:::

View File

@@ -0,0 +1,119 @@
::: title 基础使用
:::
::: demo
<template>
<lay-form>
<lay-radio v-model="selected1" name="action" label="1">写作</lay-radio>
<lay-radio v-model="selected1" name="action" label="2">画画</lay-radio>
<lay-radio v-model="selected1" name="action" label="3">运动</lay-radio>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const selected1 = ref("1");
return {
selected1
}
}
}
</script>
:::
::: title 禁用状态
:::
::: demo
<template>
<lay-form>
<lay-radio v-model="selected2" name="action" label="1">写作</lay-radio>
<lay-radio v-model="selected2" name="action" label="2">画画</lay-radio>
<lay-radio v-model="selected2" name="action" label="3">运动</lay-radio>
<lay-radio v-model="selected2" name="action" label="4" :disabled="disabled">禁用</lay-radio>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const disabled = ref(true);
const selected2 = ref("1");
return {
disabled,
selected2
}
}
}
</script>
:::
::: title 事件回调
:::
::: demo
<template>
<lay-form>
<lay-radio v-model="selected3" name="action" label="1" @change="change">写作</lay-radio>
<lay-radio v-model="selected3" name="action" label="2" @change="change">画画</lay-radio>
<lay-radio v-model="selected3" name="action" label="3" @change="change">运动</lay-radio>
</lay-form>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const selected3 = ref("1");
const change = function( current ) {
console.log("当前值:" + current)
}
return {
selected3,
change
}
}
}
</script>
:::
::: title 单选框属性
:::
::: table
| 属性 | 描述 | 默认值 |
| ------- | ------------- | ------ |
| name | 原始属性 name | -- |
| label | 当前值 | -- |
| v-model | 选中值 | -- |
:::
::: title 单选框事件
:::
::: table
| 事件 | 描述 | 参数 |
| ------ | -------- | ---------------- |
| change | 切换事件 | current : 当前值 |
:::

View File

@@ -0,0 +1,148 @@
::: title 基础使用
:::
::: demo
<template>
<lay-rate v-model="all1"></lay-rate>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const all1 = ref(0)
return {
all1
}
}
}
</script>
:::
::: title 响应结果
:::
::: demo
<template>
<lay-rate v-model="all"></lay-rate> {{all}}
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const all = ref(4)
return {
all
}
}
}
</script>
:::
::: title 指定长度
:::
::: demo
<template>
<lay-rate v-model="all2" :length="length"></lay-rate>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const all2 = ref(4);
const length = ref(10)
return {
all2,
length
}
}
}
</script>
:::
::: title 只读模式
:::
::: demo
<template>
<lay-rate v-model="all3" readonly="true"></lay-rate>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const all3 = ref(4)
return {
all3
}
}
}
</script>
:::
::: title 定义主题
:::
::: demo
<template>
<lay-rate v-model="all4" theme="#FF8000"></lay-rate><br>
<lay-rate v-model="all4" theme="#009688"></lay-rate><br>
<lay-rate v-model="all4" theme="#1E9FFF"></lay-rate><br>
<lay-rate v-model="all4" theme="#2F4056"></lay-rate><br>
<lay-rate v-model="all4" theme="#FE0000"></lay-rate><br>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const all4 = ref(4)
return {
all4
}
}
}
</script>
:::
::: title 评分属性
:::
::: table
| 属性 | 描述 | 默认值 |
| -------- | -------- | ------ |
| v-model | 评分值 | -- |
| length | 评分长度 | -- |
| readonly | 只读模式 | -- |
:::

View File

@@ -0,0 +1,102 @@
::: title 基础使用
:::
::: demo
<template>
<lay-select>
<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>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 选择禁用
:::
::: demo
<template>
<lay-select v-model="selected">
<lay-select-option value="1" label="学习"></lay-select-option>
<lay-select-option value="2" label="编码" disabled="true"></lay-select-option>
<lay-select-option value="3" label="运动"></lay-select-option>
</lay-select>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const selected = ref('1')
return {
selected
}
}
}
</script>
:::
::: title select 属性
:::
::: table
| Name | Description | Accepted Values |
| ------- | -------------- | --------------- |
| name | 原生 name 属性 | -- |
| v-model | 选中值 | -- |
:::
::: title select-option 属性
:::
::: table
| Name | Description | Accepted Values |
| ----- | ----------- | --------------- |
| label | 标签 | -- |
| value | 值 | -- |
:::
::: title select-option 插槽
:::
::: table
| Name | Description | Accepted Values |
| ------- | ----------- | --------------- |
| default | 默认 | -- |
:::
::: title select 事件
:::
::: table
| Name | Description | Accepted Values |
| ------ | ----------- | --------------- |
| change | 切换事件 | value |
:::

View File

@@ -0,0 +1,42 @@
::: demo
<template>
<lay-slider></lay-slider>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: demo
<template>
<lay-slider :vertical="vertical"></lay-slider>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const vertical = ref(true)
return {
vertical
}
}
}
</script>
:::

View File

@@ -0,0 +1,135 @@
::: title 基础使用
:::
::: demo
<template>
<lay-switch v-model="active1"></lay-switch>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active1 = ref(false);
return {
active1
}
}
}
</script>
:::
::: title 事件回调
:::
::: demo
<template>
<lay-switch v-model="active2" @change="change"></lay-switch>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active2 = ref(true);
const change = function( val ) {
console.log("当前值:" + val)
}
return {
active2,
change
}
}
}
</script>
:::
::: title 禁用状态
:::
::: demo
<template>
<lay-switch v-model="active3" :disabled="disabled"></lay-switch>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active3 = ref(true);
const disabled = ref(true)
return {
active3
}
}
}
</script>
:::
::: title 修改描述
:::
::: demo
<template>
<lay-switch v-model="active4" active-text="白天" inactive-text="夜间"></lay-switch>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const active4 = ref(true)
return {
active4
}
}
}
</script>
:::
::: title 开关属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ------------- | -------------- | -------------- |
| name | 原生 name 属性 | -- |
| v-model | 是否启用 | `true` `false` |
| disabled | 禁用 | `true` `false` |
| active-text | 启用描述 | `启动` |
| inactive-text | 禁用描述 | `禁用` |
:::
::: title 开关事件
:::
::: table
| 属性 | 描述 | 可选值 |
| ------ | -------- | ---------------- |
| change | 切换事件 | current : 当前值 |
:::

View File

@@ -0,0 +1,192 @@
::: title 基础使用
:::
::: demo
<template>
<lay-tab v-model="current1">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item>
</lay-tab>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const current1 = ref("1")
return {
current1
}
}
}
</script>
:::
::: title 简约模式
:::
::: demo
<template>
<lay-tab type="brief" v-model="current2">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item>
</lay-tab>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const current2 = ref("1")
return {
current2
}
}
}
</script>
:::
::: title 卡片模式
:::
::: demo
<template>
<lay-tab type="card" v-model="current3">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item>
</lay-tab>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const current3 = ref("1")
return {
current3
}
}
}
</script>
:::
::: title 允许关闭
:::
::: demo
<template>
<lay-tab type="card" v-model="current4" :allow-close="allowClose" @change="change" @close="close">
<lay-tab-item title="选项一" id="1"><div style="padding:20px">选项一</div></lay-tab-item>
<lay-tab-item title="选项二" id="2"><div style="padding:20px">选项二</div></lay-tab-item>
</lay-tab>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const current4 = ref("1")
const allowClose = ref(true)
const change = function(id){
console.log("当前值:" +id)
}
const close = function(id){
console.log("需要关闭:" + id)
}
return {
current4,
allowClose,
change,
close
}
}
}
</script>
:::
::: title 嵌套循环
:::
::: demo
<template>
<lay-tab type="card" v-model="current5" @change="change5">
<lay-tab-item v-for="a in arr" :key="a" :title="a.title" :id="a.id">
</lay-tab-item>
</lay-tab>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const current5 = ref('1')
const change5 = function(id){
alert(id)
}
const arr = ref([
{id:'1', title:'选项一'},
{id:'2', title:'选项二'}
])
arr.value.push({id:'3', title:'选项三'})
return {
current5,
arr
}
}
}
</script>
:::
::: title 选项卡属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----------- | -------- | -------------- |
| v-model | 当前激活 | -- |
| type | 主题样式 | -- |
| allow-close | 允许关闭 | `true` `false` |
:::
::: title 选项卡事件
:::
::: table
| 事件 | 描述 | 参数 |
| ------ | -------- | ---- |
| change | 选中切换 | -- |
| close | 关闭事件 | -- |
:::

View File

@@ -0,0 +1,311 @@
::: title 基础使用
:::
::: demo
<template>
<lay-table :columns="columns" :dataSource="dataSource">
<template v-slot:username="{ data }"> {{data.username}} </template>
<template v-slot:password="{ data }"> {{data.password}} </template>
<template v-slot:operator="{ data }">
<lay-button >修改</lay-button>
<lay-button type="primary">删除</lay-button>
</template>
</lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns = [
{
title:"账户",
width:"200px",
slot:"username",
key:"username"
},{
title:"密码",
width: "180px",
slot:"password",
key:"password"
},{
title:"年龄",
width: "180px",
key:"age"
},{
title:"操作",
width: "180px",
customSlot:"operator",
key:"operator"
}
]
const dataSource = [
{username:"root", password:"root", age:"18"},
{username:"woow", password:"woow", age:"20"}
]
return {
columns,
dataSource
}
}
}
</script>
:::
::: title 不同尺寸
:::
::: demo
<template>
<lay-table :columns="columns" :dataSource="dataSource" size="lg">
<template v-slot:username="{ data }"> {{data.username}} </template>
<template v-slot:password="{ data }"> {{data.password}} </template>
<template v-slot:operator="{ data }">
<lay-button >修改</lay-button>
<lay-button type="primary">删除</lay-button>
</template>
</lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const columns = [
{
title:"账户",
width:"200px",
slot:"username",
key:"username"
},{
title:"密码",
width: "180px",
slot:"password",
key:"password"
},{
title:"年龄",
width: "180px",
key:"age"
},{
title:"操作",
width: "180px",
customSlot:"operator",
key:"operator"
}
]
const dataSource = [
{username:"root", password:"root", age:"18"},
{username:"woow", password:"woow", age:"20"}
]
return {
columns,
dataSource
}
}
}
</script>
:::
::: title 开启分页
:::
::: demo
<template>
<lay-table :columns="columns" :dataSource="dataSource" :page="page" @change="change">
<template v-slot:username="{ data }"> {{data.username}} </template>
<template v-slot:password="{ data }"> {{data.password}} </template>
<template v-slot:operator="{ data }">
<lay-button >修改</lay-button>
<lay-button type="primary">删除</lay-button>
</template>
</lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const page = {
total: 100,
limit: 10
}
const change = function({ current }){
console.log("当前页:" + JSON.stringify(current))
}
const columns = [
{
title:"账户",
width:"200px",
slot:"username",
key:"username"
},{
title:"密码",
width: "180px",
slot:"password",
key:"password"
},{
title:"年龄",
width: "180px",
key:"age"
},{
title:"操作",
width: "180px",
customSlot:"operator",
key:"operator"
}
]
const dataSource = [
{username:"root", password:"root", age:"18"},
{username:"woow", password:"woow", age:"20"}
]
return {
page,
change,
columns,
dataSource
}
}
}
</script>
:::
::: title 完整表格
:::
::: demo
<template>
<lay-table :columns="columns" id="id" :dataSource="dataSource" v-model:selectedKeys="selectedKeys" :checkbox="checkbox" :default-toolbar="defaultToolbar" @row="rowClick">
<template v-slot:toolbar>
<lay-button size="sm">新增</lay-button>
<lay-button size="sm">删除</lay-button>
</template>
<template v-slot:username="{ data }"> {{data.username}} </template>
<template v-slot:password="{ data }"> {{data.password}} </template>
<template v-slot:operator="{ data }">
<lay-button >修改</lay-button>
<lay-button type="primary">删除</lay-button>
</template>
</lay-table>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const selectedKeys = ref(['1'])
const checkbox = ref(true)
const defaultToolbar = ref(true)
const columns = [
{
title:"账户",
width:"200px",
slot:"username",
key:"username"
},{
title:"密码",
width: "180px",
slot:"password",
key:"password"
},{
title:"年龄",
width: "180px",
key:"age"
},{
title:"操作",
width: "180px",
customSlot:"operator",
key:"operator"
}
]
const dataSource = [
{id:"1", username:"root", password:"root", age:"18"},
{id:"2", username:"woow", password:"woow", age:"20"}
]
const rowClick = function(data) {
alert(JSON.stringify(data))
}
const rowDoubleClick = function(data) {
alert(JSON.stringify(data))
}
return {
columns,
dataSource,
selectedKeys,
checkbox,
defaultToolbar,
rowClick,
rowDoubleClick
}
}
}
</script>
:::
::: title 表格属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ------------------------ | ---------- | -------------- |
| columns | 列配置 | -- |
| dataSource | 数据源 | -- |
| checkbox | 开启复现框 | -- |
| id | 主键 | -- |
| selectedKeys ( v-model ) | 选中项 | -- |
| default-toolbar | 开启工具栏 | `lg` `md` `sm` |
| size | 尺寸 | -- |
:::
::: title 表格事件
:::
::: table
| 属性 | 描述 | 参数 |
| ---------- | ------ | ------------- |
| row | 行单击 | data : 当前行 |
| row-double | 行双击 | data : 当前行 |
:::
::: title 表格插槽
:::
::: table
| 插槽 | 描述 | 默认 |
| ------- | ------------ | ---- |
| toolbar | 自定义工具栏 | -- |
:::

View File

@@ -0,0 +1,110 @@
::: title 基础使用
:::
::: demo
<template>
<lay-textarea placeholder="请输入描述" v-model="data1"></lay-textarea>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const data1 = ref("");
return {
data1
}
}
}
</script>
:::
::: title 事件回调
:::
::: demo
<template>
<lay-textarea placeholder="Input 事件" v-model="data2" @input="input"></lay-textarea>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const data2 = ref("");
const input = function( val ) {
console.log(val)
}
return {
data2,
input
}
}
}
</script>
:::
::: title 禁止输入
:::
::: demo
<template>
<lay-textarea placeholder="禁止输入" v-model="data3" :disabled="disabled"></lay-textarea>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const data3 = ref("");
const disabled = ref(true)
return {
data3,
disabled
}
}
}
</script>
:::
::: title 文本域属性
:::
::: table
| 属性 | 描述 | 可选值 |
| ----------- | ------------- | -------------- |
| name | 原始属性 name | -- |
| placeholder | 提示信息 | -- |
| disabled | 禁用 | `true` `false` |
| v-model | 值 | -- |
:::
::: title 文本域事件
:::
::: table
| 事件 | 描述 | 可选值 |
| ----- | --------------- | ---------------- |
| input | 原生 input 事件 | event : 事件对象 |
| foucs | 原生 foucs 事件 | event : 事件对象 |
| blur | 原生 blur 事件 | -- |
:::

View File

@@ -0,0 +1,85 @@
::: title 基础使用
:::
::: demo
<template>
<lay-timeline>
<lay-timeline-item title="8月18日">
<p>
layui 2.0 的一切准备工作似乎都已到位。发布之弦,一触即发。
<br>不枉近百个日日夜夜与之为伴。因小而大,因弱而强。
<br>无论它能走多远,抑或如何支撑?至少我曾倾注全心,无怨无悔 <i class="layui-icon"></i>
</p>
</lay-timeline-item>
<lay-timeline-item title="8月16日">
<p>杜甫的思想核心是儒家的仁政思想,他有<em>“致君尧舜上,再使风俗淳”</em>的宏伟抱负。</p>
<ul>
<li>《登高》</li>
<li>《茅屋为秋风所破歌》</li>
</ul>
</lay-timeline-item>
<lay-timeline-item title="8月15日">
<p>
中国人民抗日战争胜利日
<br>铭记、感恩
<br>所有为中华民族浴血奋战的英雄将士
<br>永垂不朽
</p>
</lay-timeline-item>
</lay-timeline>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 简单模式
:::
::: demo
<template>
<lay-timeline>
<lay-timeline-item title="2021年layui vue 里程碑版本 1.0 发布" simple></lay-timeline-item>
<lay-timeline-item title="2017年layui 里程碑版本 2.0 发布" simple></lay-timeline-item>
<lay-timeline-item title="2016年layui 首个版本发布" simple></lay-timeline-item>
<lay-timeline-item title="2015年layui 孵化" simple></lay-timeline-item>
</lay-timeline>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::
::: title timeline-item attributes
:::
::: table
| | | |
| ------ | -------- | --- |
| simple | 简单模式 | -- |
| title | 标题 | -- |
:::

View File

@@ -0,0 +1,108 @@
::: title 基础使用
:::
::: demo
<template>
<lay-transfer :dataSource="dataSource1"></lay-transfer>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const dataSource1 = [{id:'1', title:'易大师'},{id:'2', title:'战争之王'}]
return {
dataSource1
}
}
}
</script>
:::
::: title 指定标题
:::
::: demo
<template>
<lay-transfer :dataSource="dataSource2" :title="title"></lay-transfer>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const dataSource2 = [{id:'1', title:'易大师'},{id:'2', title:'战争之王'}]
const title = ['我喜欢的','我不喜欢的']
return {
dataSource2,
title
}
}
}
</script>
:::
::: title 使用插槽
:::
::: demo
<template>
<lay-transfer :dataSource="dataSource1">
<template v-slot:item="{ data }">
{{data.id}}
</template>
</lay-transfer>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const dataSource1 = [{id:'1', title:'易大师'},{id:'2', title:'战争之王'}]
return {
dataSource1
}
}
}
</script>
:::
::: title transfer 属性
:::
::: table
| Name | Description | Accepted Values |
| ---------- | ----------- | --------------- |
| dataSource | 数据来源 | -- |
| title | 标题 | -- |
| id | 主键 | -- |
:::
::: title transfer 插槽
:::
::: table
| Name | Description | Accepted Values |
| ---- | ----------- | --------------- |
| item | 列表项 | { data } |
:::

View File

@@ -0,0 +1,255 @@
::: demo
<template>
<lay-tree
:data="data"
:onlyIconControl="iconCtrl"
:showLine="showLine"
:showCheckbox="showCheckbox"
v-model:checkedKeys="checkedKeys"
@node-click="handleClick"
:disabled="disabled"
>
</lay-tree>
<br/>
是否可开启选择框:
<br/>
<lay-switch v-model="showCheckbox"></lay-switch>
<br/>
checkedKeys
<pre>
{{ checkedKeys }}
</pre>
只能通过节点左侧图标来展开收缩:
<br/>
<lay-switch v-model="iconCtrl"></lay-switch>
<br/>
是否开启连接线:
<br/>
<lay-switch v-model="showLine"></lay-switch>
<br/>
当前点击的节点:
<br/>
<pre>
{{ clickNode }}
</pre>
<br/>
</template>
<script setup>
import { ref } from 'vue';
const data = ref([{
title: '一级1',
id: 1,
field: 'name1',
checked: true,
spread: true,
children: [{
title: '二级1-1 可允许跳转',
id: 3,
field: 'name11',
href: 'https://www.layui.com/',
children: [{
title: '三级1-1-3',
id: 23,
field: '',
children: [{
title: '四级1-1-3-1',
id: 24,
field: '',
children: [{
title: '五级1-1-3-1-1',
id: 30,
field: ''
},
{
title: '五级1-1-3-1-2',
id: 31,
field: ''
}]
}]
},
{
title: '三级1-1-1',
id: 7,
field: '',
children: [{
title: '四级1-1-1-1 可允许跳转',
id: 15,
field: '',
href: 'https://www.layui.com/doc/'
}]
},
{
title: '三级1-1-2',
id: 8,
field: '',
children: [{
title: '四级1-1-2-1',
id: 32,
field: ''
}]
}]
},
{
title: '二级1-2',
id: 4,
spread: true,
children: [{
title: '三级1-2-1',
id: 9,
field: '',
disabled: true
},
{
title: '三级1-2-2',
id: 10,
field: ''
}]
},
{
title: '二级1-3',
id: 20,
field: '',
children: [{
title: '三级1-3-1',
id: 21,
field: ''
},
{
title: '三级1-3-2',
id: 22,
field: ''
}]
}]
},
{
title: '一级2',
id: 2,
field: '',
spread: true,
children: [{
title: '二级2-1',
id: 5,
field: '',
spread: true,
children: [{
title: '三级2-1-1',
id: 11,
field: ''
},
{
title: '三级2-1-2',
id: 12,
field: ''
}]
},
{
title: '二级2-2',
id: 6,
field: '',
children: [{
title: '三级2-2-1',
id: 13,
field: ''
},
{
title: '三级2-2-2',
id: 14,
field: '',
disabled: true
}]
}]
},
{
title: '一级3',
id: 16,
field: '',
children: [{
title: '二级3-1',
id: 17,
field: '',
fixed: true,
children: [{
title: '三级3-1-1',
id: 18,
field: ''
},
{
title: '三级3-1-2',
id: 19,
field: ''
}]
},
{
title: '二级3-2',
id: 27,
field: '',
children: [{
title: '三级3-2-1',
id: 28,
field: ''
},
{
title: '三级3-2-2',
id: 29,
field: ''
}]
}]
}]);
const iconCtrl = ref(false);
const showLine = ref(true);
const clickNode = ref(null);
const showCheckbox = ref(true);
const checkedKeys = ref([1]);
const disabled = ref(false);
function handleClick(node) {
clickNode.value = node
}
</script>
:::
::: title tree attributes
:::
::: table
| Name | Description | Accepted Values |
| -------------------------------- | ---------------------------------------- | --------------- |
| data | 树型组件数据,类型 TreeData \| TreeData[] | null |
| showCheckbox | 是否显示复选框 | false |
| onlyIconControl | 是否仅允许节点左侧图标控制展开收缩 | false |
| showLine | 是否开启连接线 | true |
| checkedKeys(v-model:checkedKeys) | 开启 showCheckbox 后, 选中的节点 | [] |
:::
::: title TreeData
:::
::: table
| Name | Description | Accepted Values |
| -------- | -------------- | --------------- |
| id | 唯一值 | - |
| title | 节点名称 | - |
| children | 子节点 | [] |
| disabled | 该节点是否禁用 | false |
| spread | 该节点是否展开 | false |
:::
::: title tree events
:::
::: table
| Name | Description | Accepted Params |
| ---------- | --------------- | --------------- |
| node-click | 节点 click 事件 | -- |
:::

View File

@@ -0,0 +1,164 @@
::: title 更新记录
:::
<lay-timeline style="padding-left:30px;padding-top:30px;">
<lay-timeline-item title="尾版本号:日常 bugfix 更新" simple></lay-timeline-item>
<lay-timeline-item title="次版本号:带有新特性的向下兼容的版本。" simple></lay-timeline-item>
<lay-timeline-item title="主版本号:含有破坏性更新和新特性,不在发布周期内。" simple></lay-timeline-item>
</lay-timeline>
::: demo
<template>
<lay-timeline>
<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>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
:::

View File

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

View File

@@ -0,0 +1,54 @@
::: title 快速上手
:::
<br>
::: describe 这里是 Layui 的 Vue 实现,开发和服务于企业级后台产品。
:::
<img src="https://portrait.gitee.com/uploads/avatars/namespace/2849/8547475_layui-vue_1633242524.png" style="margin-left:24px;border-radius: 10px;" width="140px" />
<br>
<br>
<br>
::: describe 1.使用 npm 下载
:::
```
npm install @layui/layui-vue --save
```
<br>
::: describe 2.在 main.ts 中依赖
:::
```js
import App from './App.vue'
import { createApp } from 'vue'
import Layui from '@layui/layui-vue'
import '@layui/layui-vue/lib/layui.css'
createApp(App).use(Layui).mount('#app')
```
<br>
::: describe 3.在 index.vue 使用
:::
```html
<lay-layout>
<lay-header>
<lay-logo>Layui Admin</lay-logo>
</lay-header>
<lay-side></lay-side>
<lay-body>
<router-view></router-view>
</lay-body>
<lay-footer>pearadmin.com</lay-footer>
</lay-layout>
```
- 前往: [layui-vue-sample](https://gitee.com/layui-vue/layui-vue-sample)

View File

@@ -0,0 +1,19 @@
::: title 基本介绍
:::
<img src="http://layui-doc.pearadmin.com/static/images/layui/logo-2.png" />
<br>
::: block
layui - vue谐音类 UI) 是 一 套 Vue 3.0 的 桌 面 端 组 件 库 , Layui 的 另 一 种 呈 现 方 式
:::
<lay-timeline>
<lay-timeline-item title="2021年layui vue 里程碑版本 0.2.0 发布" simple></lay-timeline-item>
<lay-timeline-item title="2017年layui 里程碑版本 2.0 发布" simple></lay-timeline-item>
<lay-timeline-item title="2016年layui 首个版本发布" simple></lay-timeline-item>
<lay-timeline-item title="2015年layui 孵化" simple></lay-timeline-item>
</lay-timeline>

View File

@@ -0,0 +1,2 @@
::: title 开发规范
:::

View File

@@ -0,0 +1,2 @@
::: title 常见问题
:::

View File

@@ -0,0 +1,23 @@
::: title 沙盒环境
:::
::: demo
<template>
<lay-layer title="一任流行坎止"></lay-layer>
<lay-layer title="身如不系之舟" :offset="['260px','220px']"></lay-layer>
</template>
<script>
import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
export default {
setup() {
return {
};
},
};
</script>
:::

View File

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

View File

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

View File

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

26
example/index.html Normal file
View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<meta name="force-rendering" content="webkit" />
<meta name="applicable-device" content="pc,mobile" />
<meta name="author" content="Jmys <jmys1992@gmail.com>" />
<meta
name="keywords"
content="element-pro,pro-components,admin,element-plus,components,vue,ui"
/>
<link rel="icon" href="/favicon.ico" />
<title>Layui - Vue 开源前端 UI 框架</title>
<!--preload-links-->
</head>
<body>
<div id="app">
<!--app-html-->
</div>
<script type="module" src="/src/entry-client.ts"></script>
</body>
</html>

46
example/prerender.js Normal file
View File

@@ -0,0 +1,46 @@
const fs = require('fs')
const path = require('path')
const toAbsolute = (p) => path.resolve(__dirname, p).replace(/\\/, '/')
const manifest = require('./dist/static/ssr-manifest.json')
const template = fs.readFileSync(toAbsolute('dist/static/index.html'), 'utf-8')
const { render } = require('./dist/server/entry-server.js')
const writeFileRecursive = function (path, buffer) {
const lastPath = path.substring(0, path.lastIndexOf('/'))
fs.mkdir(lastPath, { recursive: true }, () => {
fs.writeFileSync(path, buffer)
})
}
const fileDisplay = (file) => {
fs.readdirSync(toAbsolute(file)).forEach(async (filename) => {
const filedir = path.join(file, filename).replace(/\\/, '/')
if (fs.statSync(toAbsolute(filedir)).isDirectory()) {
fileDisplay(filedir)
} else {
const url = filedir
.replace(/^docs/, '')
.replace(/\.(vue|md)$/, '')
.replace(/index$/, '')
.replace(/\/([^/]*)$/, (item) =>
item.replace(/\B([A-Z])/g, '-$1').toLowerCase()
)
const [appHtml, preloadLinks] = await render(url, manifest)
const html = template
.replace('<!--preload-links-->', preloadLinks)
.replace('<!--app-html-->', appHtml)
const filePath = `dist/static${url.replace(/\/$/, '/index')}.html`
writeFileRecursive(toAbsolute(filePath), html)
console.log('pre-rendered:', filePath)
}
})
}
fileDisplay('docs')
fs.unlinkSync(toAbsolute('dist/static/ssr-manifest.json'))

BIN
example/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

3
example/src/App.vue Normal file
View File

@@ -0,0 +1,3 @@
<template>
<router-view />
</template>

View File

@@ -0,0 +1,213 @@
code {
margin: 0;
border-radius: 3px;
padding: 0.25rem 0.5rem;
font-family: var(--code-font-family);
font-size: 0.85em;
color: var(--c-text-light);
background-color: var(--code-inline-bg-color);
}
code .token.deleted {
color: #ec5975;
}
code .token.inserted {
color: var(--c-brand);
}
div[class*='language-'] {
position: relative;
margin: 1rem -1.5rem;
background-color: #fafafa;
overflow-x: auto;
border: 1px solid whitesmoke;
}
li > div[class*='language-'] {
border-radius: 6px 0 0 6px;
margin: 1rem -1.5rem 1rem -1.25rem;
}
@media (min-width: 420px) {
div[class*='language-'] {
margin: 1rem 0;
border-radius: 6px;
}
li > div[class*='language-'] {
margin: 1rem 0 1rem 0rem;
border-radius: 6px;
}
}
[class*='language-'] pre,
[class*='language-'] code {
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
[class*='language-'] pre {
position: relative;
z-index: 1;
margin: 0;
padding: 1.25rem 1.5rem;
background: transparent;
overflow-x: auto;
}
[class*='language-'] pre p {
margin: auto !important;
}
[class*='language-'] code {
padding: 0;
line-height: var(--code-line-height);
font-size: var(--code-font-size);
color: #000;
background-color: #fafafa;
}
/* Line highlighting */
.highlight-lines {
position: absolute;
top: 0;
bottom: 0;
left: 0;
padding: 1.25rem 0;
width: 100%;
line-height: var(--code-line-height);
font-family: var(--code-font-family);
font-size: var(--code-font-size);
user-select: none;
overflow: hidden;
}
.highlight-lines .highlighted {
background-color: rgba(0, 0, 0, 0.66);
}
/* Line numbers mode */
div[class*='language-'].line-numbers-mode {
padding-left: 3.5rem;
}
.line-numbers-wrapper {
position: absolute;
top: 0;
bottom: 0;
left: 0;
z-index: 3;
border-right: 1px solid rgba(0, 0, 0, 0.5);
padding: 1.25rem 0;
width: 3.5rem;
text-align: center;
line-height: var(--code-line-height);
font-family: var(--code-font-family);
font-size: var(--code-font-size);
color: #888;
}
/* Language marker */
[class*='language-']:before {
position: absolute;
top: 0.6em;
right: 1em;
z-index: 2;
font-size: 0.8rem;
color: #888;
}
/**
* prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML.
* Based on https://github.com/chriskempson/tomorrow-theme
*
* @author Rose Pritchard
*/
.token.comment,
.token.block-comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #999;
}
.token.punctuation {
color: #ccc;
}
.token.tag,
.token.attr-name,
.token.namespace,
.token.deleted {
color: #e2777a;
}
.token.function-name {
color: #6196cc;
}
.token.boolean,
.token.number,
.token.function {
color: #f08d49;
}
.token.property,
.token.class-name,
.token.constant,
.token.symbol {
color: #f8c555;
}
.token.selector,
.token.important,
.token.atrule,
.token.keyword,
.token.builtin {
color: #cc99cd;
}
.token.string,
.token.char,
.token.attr-value,
.token.regex,
.token.variable {
color: #7ec699;
}
.token.operator,
.token.entity,
.token.url {
color: #67cdcc;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.token.inserted {
color: green;
}

View File

@@ -0,0 +1,3 @@
@import './code.css';
@import './markdown.css';
@import './vars.css';

View File

@@ -0,0 +1,262 @@
html {
line-height: 1.4;
font-size: 16px;
-webkit-text-size-adjust: 100%;
}
h4 {
font-weight: 600 !important;
font-size: 16.8px !important;
margin-top: 20px !important;
margin-bottom: 20px !important;
}
h5 {
font-weight: 700;
font-size: 16.8px;
}
h1,
h3,
h4,
h5,
h6 {
margin: 0;
color: #333;
line-height: 1.25;
}
h1:hover .header-anchor,
h1:focus .header-anchor,
h2:hover .header-anchor,
h2:focus .header-anchor,
h3:hover .header-anchor,
h3:focus .header-anchor,
h4:hover .header-anchor,
h4:focus .header-anchor,
h5:hover .header-anchor,
h5:focus .header-anchor,
h6:hover .header-anchor,
h6:focus .header-anchor {
opacity: 1;
}
h1 {
margin-top: 1.5rem;
font-size: 1.9rem;
}
@media screen and (min-width: 420px) {
h1 {
font-size: 2.2rem;
}
}
h4 {
font-size: 1.15rem;
}
h1 {
margin-top: 4px !important;
margin-bottom: 22px !important;
color: #000000d9 !important;
font-weight: 500 !important;
font-size: 20px !important;
font-family: Avenir, -apple-system, BlinkMacSystemFont, segoe ui, Roboto,
helvetica neue, Arial, noto sans, sans-serif, apple color emoji,
segoe ui emoji, segoe ui symbol, noto color emoji, sans-serif;
line-height: 38px;
}
area,
button,
[role='button'],
input,
label,
select,
summary,
textarea {
touch-action: manipulation;
}
a.header-anchor {
float: left;
margin-top: 0.125em;
margin-left: -0.87em;
padding-right: 0.23em;
font-size: 0.85em;
opacity: 0;
}
a.header-anchor:hover,
a.header-anchor:focus {
text-decoration: none;
}
figure {
margin: 0;
}
img {
max-width: 100%;
}
form {
margin: 0;
}
.source .layui-avatar {
margin-right: 30px;
}
.site-doc-icon {
margin-bottom: 50px;
font-size: 0;
}
.site-doc-icon li .doc-icon-name,
.site-doc-icon li .doc-icon-code {
color: #c2c2c2;
}
.site-doc-icon li .doc-icon-fontclass {
height: 40px;
line-height: 20px;
padding: 0 5px;
font-size: 13px;
color: #333;
}
.site-doc-icon li {
display: inline-block;
vertical-align: middle;
width: 16.5%;
height: 105px;
line-height: 25px;
padding: 20px 0;
margin-right: -1px;
margin-bottom: -1px;
border: 1px solid #e2e2e2;
font-size: 14px;
text-align: center;
color: #666;
transition: all 0.3s;
-webkit-transition: all 0.3s;
}
.site-doc-icon li .layui-icon {
display: inline-block;
font-size: 32px;
}
.site-doc-color {
margin: 15px 0;
}
.site-doc-necolor li div {
border-radius: 0;
color: #000 !important;
}
.site-doc-color li div {
padding: 20px 10px;
color: #fff;
text-align: center;
line-height: 1.6;
font-size: 14px;
}
.site-doc-bgcolor li {
padding: 20px 10px;
}
.site-idea {
margin: 30px 0;
margin-top: 16px;
font-weight: 300;
}
.site-idea li {
font-size: 14px;
}
.site-idea li div {
padding: 25px;
line-height: 24px;
border: 1px solid #d2d2d2;
border-radius: 6px;
}
.site-idea .layui-field-title {
border-color: #d2d2d2;
}
.site-idea .layui-field-title legend {
margin: 0 20px 20px 0;
padding: 0 20px;
text-align: center;
}
.anim .site-doc-icon {
margin-bottom: 50px;
font-size: 0;
}
.anim .site-doc-icon li {
width: 50%;
}
.anim .site-doc-anim li {
height: auto;
}
.anim .site-doc-icon li {
display: inline-block;
vertical-align: middle;
width: 16.5%;
height: 105px;
line-height: 25px;
padding: 20px 0;
margin-right: -1px;
margin-bottom: -1px;
border: 1px solid #e2e2e2;
font-size: 14px;
text-align: center;
color: #666;
transition: all 0.3s;
-webkit-transition: all 0.3s;
}
.anim .site-doc-icon li .layui-anim {
width: 125px;
height: 125px;
line-height: 125px;
margin: 0 auto 10px;
text-align: center;
background-color: #009688;
cursor: pointer;
color: #fff;
border-radius: 50%;
}
.anim .site-doc-icon li .code {
white-space: nowrap;
}
.markdown-body th {
text-align: left;
}
body::-webkit-scrollbar {
width: 0px;
height: 0px;
}
.layui-menu-item-group {
padding-left: 10px !important;
padding-right: 10px !important;
}
.layui-menu .layui-menu-item-group > .layui-menu-body-title {
padding-left: 15px;
}

View File

@@ -0,0 +1,12 @@
:root {
--c-white: #ffffff;
--c-black: #000000;
}
:root {
--code-line-height: 24px;
--code-font-family: var(--font-family-mono);
--code-font-size: 14px;
--code-inline-bg-color: rgba(27, 31, 35, 0.05);
--code-bg-color: #282c34;
}

BIN
example/src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,152 @@
<template>
<div class="lay-code">
<div id="source" class="source">
<slot />
</div>
<div ref="meta" class="meta">
<div v-if="$slots.description" class="description">
<slot name="description" />
</div>
<div class="language-html">
<slot name="code" />
</div>
</div>
<div :class="{ 'is-fixed': isFixContorl }" class="control">
<i class="layui-icon layui-icon-file" @click="copy" />
<i class="layui-icon layui-icon-fonts-code" @click="toggle" />
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
const meta = ref<HTMLElement>({} as HTMLElement)
const isFixContorl = ref(false)
const codeAreaHeight = ref(0)
const show = ref(false)
const toggle = function () {
show.value = !show.value
}
const copy = function () {
var Url2 = document.getElementById('source') as any
Url2.select()
document.execCommand('Copy')
}
onMounted(() => {
const foundDescs = meta.value.getElementsByClassName('description')
const foundCodes = meta.value.getElementsByClassName('language-html')
if (foundDescs.length) {
codeAreaHeight.value =
foundDescs[0].clientHeight + foundCodes[0].clientHeight + 30
} else {
codeAreaHeight.value = foundCodes[0].clientHeight + 20
}
})
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll)
})
watch(show, (value) => {
if (value) {
meta.value.style.height = `${codeAreaHeight.value}px`
window.addEventListener('scroll', handleScroll)
setTimeout(handleScroll, 100)
} else {
meta.value.style.height = '0'
window.removeEventListener('scroll', handleScroll)
}
})
function handleScroll() {
const { top, bottom } = meta.value.getBoundingClientRect()
isFixContorl.value =
bottom > window.innerHeight && top + 44 <= window.innerHeight
}
</script>
<style>
.lay-code {
margin: 1rem 0;
border: 1px solid whitesmoke;
border-radius: 3px;
background: var(--c-bg);
transition: all 0.2s;
}
.lay-code:hover {
box-shadow: var(--shadow-2);
}
.lay-code .source {
padding: 24px;
}
.lay-code .meta {
padding: 0 10px;
height: 0;
background-color: var(--c-page-background);
overflow: hidden;
transition: height 0.2s;
}
.lay-code .meta .description {
padding: 20px;
margin: 10px 0;
border: 1px solid whitesmoke;
box-sizing: border-box;
background: var(--c-bg);
font-size: 14px;
line-height: 22px;
color: var(--c-text-light-1);
word-break: break-word;
}
.lay-code .meta .description p {
margin: 0 !important;
line-height: 26px !important;
}
.lay-code .meta .description code {
display: inline-block;
padding: 1px 5px;
margin: 0 4px;
height: 18px;
border-radius: 2px;
background-color: var(--code-inline-bg-color);
font-size: 12px;
line-height: 18px;
color: var(--c-text-light);
}
.lay-code .control {
height: 44px;
box-sizing: border-box;
margin-top: 10px;
border-top: 1px solid whitesmoke;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
background: var(--c-bg);
text-align: center;
color: var(--c-text);
cursor: pointer;
width: 100%;
user-select: none;
}
.lay-code .control.is-fixed {
position: sticky;
z-index: 11;
bottom: 0;
}
.lay-code .control:hover {
background-color: var(--c-page-background);
color: var(--c-brand);
}
.lay-code .control > i {
display: inline-block;
font-size: 16px;
line-height: 44px;
transition: all 0.3s;
padding-left: 10px;
padding-right: 10px;
}
</style>

View File

@@ -0,0 +1,124 @@
<template>
<select :name="name" lay-verify="required" />
<div
class="layui-unselect layui-form-select layui-search"
:class="[openState ? 'layui-form-selected' : '']"
@click="open"
style="margin-left: 20px"
>
<div class="layui-select-title">
<input
type="text"
placeholder="Search"
class="layui-input layui-unselect"
:value="name"
style="
background: rgba(255, 255, 255, 0.05);
border: none;
color: rgba(255, 255, 255, 0.7);
width: 196px;
height: 34px;
"
@input="change"
/><i class="layui-edge"></i>
</div>
<dl class="layui-anim layui-anim-upbit" style="">
<dd v-if="menus.length <= 0" class="layui-select-tips">无内容</dd>
<dd
v-for="data in menus"
v-else
:key="data"
:value="name"
class="layui-select-tips"
@click="jump(data)"
>
{{ data.title }}
</dd>
</dl>
</div>
</template>
<script setup name="LaySelect" lang="ts">
import { defineProps, ref } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Recordable } from '/@src/module/type'
const props = defineProps<{
datas?: Recordable[]
}>()
const route = useRoute()
const router = useRouter()
const openState = ref(false)
const menus = ref(props.datas)
const name = ref('')
const open = function () {
openState.value = !openState.value
}
const jump = function (data: any) {
name.value = data.title
router.push(data.path)
}
const change = function (e: any) {
name.value = e.target.value
if (e.target.value === '') {
menus.value = props.datas
} else {
menus.value = searchList(e.target.value, props.datas)
}
}
const searchList = function (str: string, container: any) {
var newList = []
var startChar = str.charAt(0)
var strLen = str.length
for (var i = 0; i < container.length; i++) {
var obj = container[i]
var isMatch = false
for (var p in obj) {
if (typeof obj[p] == 'function') {
obj[p]()
} else {
var curItem = ''
if (obj[p] != null) {
curItem = obj[p]
}
for (var j = 0; j < curItem.length; j++) {
if (curItem.charAt(j) == startChar) {
if (curItem.substring(j).substring(0, strLen) == str) {
isMatch = true
break
}
}
}
}
}
if (isMatch) {
newList.push(obj)
}
}
return newList
}
</script>
<style>
.layui-search .layui-anim::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.layui-search .layui-anim::-webkit-scrollbar-corner {
background: #f6f6f6;
}
.layui-search .layui-anim::-webkit-scrollbar-thumb {
background: #e6e6e6;
border-radius: 2px;
}
.layui-search .layui-anim::-webkit-scrollbar-track {
background: white;
border-radius: 2px;
}
</style>

View File

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

View File

@@ -0,0 +1,7 @@
import { createApp } from './main'
const { app, router } = createApp()
router.isReady().then(() => {
app.mount('#app')
})

View File

@@ -0,0 +1,52 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { createApp } from './main'
import { renderToString } from '@vue/server-renderer'
export async function render(url, manifest): Promise<string[]> {
const { app, router } = createApp()
// set the router to the desired URL before rendering
router.push(url)
await router.isReady()
// passing SSR context object which will be available via useSSRContext()
// @vitejs/plugin-vue injects code into a component's setup() that registers
// itself on ctx.modules. After the render, ctx.modules would contain all the
// components that have been instantiated during this render call.
const ctx = {}
const html = await renderToString(app, ctx)
// the SSR manifest generated by Vite contains module -> chunk/asset mapping
// which we can then use to determine what files need to be preloaded for this
// request.
const preloadLinks = renderPreloadLinks(ctx.modules, manifest)
return [html, preloadLinks]
}
function renderPreloadLinks(modules, manifest) {
let links = ''
const seen = new Set()
modules.forEach((id) => {
const files = manifest[id]
if (files) {
files.forEach((file) => {
if (!seen.has(file)) {
seen.add(file)
links += renderPreloadLink(file)
}
})
}
})
return links
}
function renderPreloadLink(file) {
if (file.endsWith('.js')) {
return `<link rel="modulepreload" crossorigin href="${file}">`
} else if (file.endsWith('.css')) {
return `<link rel="stylesheet" href="${file}">`
} else {
return ''
}
}

View File

@@ -0,0 +1,393 @@
<template>
<lay-layout class="layui-layout-document">
<lay-header
><lay-logo style="box-shadow: 0 0px 2px 0 rgba(0, 0, 0, 0.15)">
<img src="../assets/logo.png" />
</lay-logo>
<ul
class="layui-nav layui-layout-left"
style="margin-top: 0px; margin-bottom: 0px"
>
<li class="layui-nav-item">
<router-link to="/zh-CN/index"> 首页 </router-link>
</li>
<li class="layui-nav-item">
<router-link to="/zh-CN/guide"> 指南 </router-link>
</li>
<li class="layui-nav-item">
<router-link to="/zh-CN/components"> 组件 </router-link>
</li>
<li class="layui-nav-item">
<router-link to="/zh-CN/hooks"> hooks </router-link>
</li>
<li class="layui-nav-item">
<lay-form>
<lay-search :datas="menus" />
</lay-form>
</li>
</ul>
<ul
class="layui-nav layui-layout-right"
style="margin-top: 0px; margin-bottom: 0px"
>
<li class="layui-nav-item">
<a href="https://gitee.com/layui-vue">
<lay-icon type="layui-icon-fonts-code" size="14px"></lay-icon>
</a>
</li>
<li class="layui-nav-item">
<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="
>
<lay-icon type="layui-icon-chat" size="14px"></lay-icon>
</a>
</li>
<li class="layui-nav-item">
<a href="javascript:void(0)"> 0.2.4 </a>
</li>
</ul>
</lay-header>
<router-view></router-view>
</lay-layout>
</template>
<script>
import { ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const route = useRoute()
const router = useRouter()
const currentPath = ref('/zh-CN/guide')
watch(
() => route.path,
(val) => {
currentPath.value = val
},
{
immediate: true,
deep: true,
}
)
const menus = [
{
id: 1,
title: '介绍',
subTitle: 'introduce',
path: '/zh-CN/guide/introduce',
},
{
id: 2,
title: '安装',
subTitle: 'get started',
path: '/zh-CN/guide/getStarted',
},
{
id: 3,
title: '更新',
subTitle: 'change log',
path: '/zh-CN/guide/changelog',
},
{
id: 4,
title: '布局',
subTitle: 'layout',
path: '/zh-CN/components/layout',
},
{
id: 5,
title: '容器',
subTitle: 'container',
path: '/zh-CN/components/container',
},
{
id: 6,
title: '按钮',
subTitle: 'button',
path: '/zh-CN/components/button',
},
{
id: 7,
title: '图标',
subTitle: 'iconfont',
path: '/zh-CN/components/icon',
},
{
id: 8,
title: '面板',
subTitle: 'panel',
path: '/zh-CN/components/panel',
},
{
id: 9,
title: '卡片',
subTitle: 'card',
path: '/zh-CN/components/card',
},
{
id: 10,
title: '动画',
subTitle: 'animation',
path: '/zh-CN/components/animation',
},
{
id: 11,
title: '栅格',
subTitle: 'grid',
path: '/zh-CN/components/grid',
},
{
id: 12,
title: '表单',
subTitle: 'form',
path: '/zh-CN/components/form',
},
{
id: 13,
title: '徽章',
subTitle: 'badge',
path: '/zh-CN/components/badge',
},
{
id: 14,
title: '区块',
subTitle: 'block',
path: '/zh-CN/components/block',
},
{
id: 15,
title: '分割',
subTitle: 'line',
path: '/zh-CN/components/line',
},
{
id: 16,
title: '菜单',
subTitle: 'nav',
path: '/zh-CN/components/menu',
},
{
id: 17,
title: '面包屑',
subTitle: 'breadcrumb',
path: '/zh-CN/components/breadcrumb',
},
{
id: 18,
title: '进度',
subTitle: 'progress',
path: '/zh-CN/components/progress',
},
{
id: 19,
title: '时间线',
subTitle: 'timeline',
path: '/zh-CN/components/timeline',
},
{
id: 20,
title: '颜色',
subTitle: 'color',
path: '/zh-CN/components/color',
},
{
id: 21,
title: '手风琴',
subTitle: 'collapse',
path: '/zh-CN/components/collapse',
},
{
id: 22,
title: '表格',
subTitle: 'table',
path: '/zh-CN/components/table',
},
{
id: 23,
title: '头像',
subTitle: 'avatar',
path: '/zh-CN/components/avatar',
},
{
id: 24,
title: '字段',
subTitle: 'field',
path: '/zh-CN/components/field',
},
{
id: 25,
title: '空',
subTitle: 'empty',
path: '/zh-CN/components/empty',
},
{
id: 26,
title: '评分',
subTitle: 'rate',
path: '/zh-CN/components/rate',
},
{
id: 27,
title: '下拉菜单',
subTitle: 'dropdown',
path: '/zh-CN/components/dropdown',
},
{
id: 28,
title: '选项卡',
subTitle: 'tab',
path: '/zh-CN/components/tab',
},
{
id: 29,
title: '图标选择',
subTitle: 'iconPicker',
path: '/zh-CN/components/iconPicker',
},
{
id: 29,
title: '分页',
subTitle: 'page',
path: '/zh-CN/components/page',
},
{
id: 30,
title: '树形组件',
subTitle: 'tree',
path: '/zh-CN/components/tree',
},
{
id: 31,
title: '穿梭框',
subTitle: 'transfer',
path: '/zh-CN/components/transfer',
},
{
id: 32,
title: '复选框',
subTitle: 'checkbox',
path: '/zh-CN/components/checkbox',
},
{
id: 33,
title: '单选框',
subTitle: 'radio',
path: '/zh-CN/components/radio',
},
{
id: 34,
title: '输入框',
subTitle: 'input',
path: '/zh-CN/components/input',
},
{
id: 35,
title: '文本域',
subTitle: 'textarea',
path: '/zh-CN/components/textarea',
},
{
id: 36,
title: '开关',
subTitle: 'switch',
path: '/zh-CN/components/switch',
},
{
id: 37,
title: '滑块',
subTitle: 'slider',
path: '/zh-CN/components/slider',
},
{
id: 38,
title: '轮播',
subTitle: 'carousel',
path: '/zh-CN/components/carousel',
},
{
id: 39,
title: '下拉选择',
subTitle: 'select',
path: '/zh-CN/components/select',
},
{
id: 40,
title: '颜色选择器',
subTitle: 'colorPicker',
path: '/zh-CN/components/colorPicker',
},
]
const handleClick = function (menu) {
router.push(menu.path)
}
return {
menus,
currentPath,
handleClick,
}
},
}
</script>
<style>
.layui-layout-document > .layui-header {
z-index: 9999;
width: 100%;
position: fixed;
background: #393d49;
border-bottom: 1px solid #404553;
}
.layui-layout-document > .layui-layout > .layui-side {
overflow-x: hidden;
position: fixed;
margin-top: 60px;
height: calc(100% - 60px);
box-shadow: 2px 0 8px 0 rgb(29 35 41 / 5%);
}
.layui-layout-document > .layui-layout > .layui-body {
margin-top: 60px;
left: 200px;
position: absolute;
width: calc(100% - 200px);
height: calc(100% - 60px);
}
.layui-logo img {
height: 31px;
width: 82px;
left: 15px;
top: 16px;
}
.layui-header > .layui-nav {
background-color: transparent;
}
.layui-menu-docs {
padding-top: 10px;
}
.layui-menu-docs .layui-menu-body-title .layui-font-gray {
padding-left: 10px;
}
.layui-side hr {
margin: 8px;
}
@media screen and (max-width: 768px) {
.layui-side {
width: 0px !important;
}
.layui-body {
left: 0px !important;
width: 100% !important;
}
.layui-logo {
display: none !important;
}
.layui-layout-left {
left: 0px !important;
}
}
</style>

29
example/src/main.ts Normal file
View File

@@ -0,0 +1,29 @@
import Layout from './App.vue'
import { App, createApp as _createApp, createSSRApp } from 'vue'
import { createRouter } from './router/index'
import { Router } from 'vue-router'
import Layui from '/@src/index'
import LayCode from './components/LayCode.vue'
import LaySearch from './components/LaySearch.vue'
import LayTableBox from './components/LayTableBox.vue'
import './assets/css/index.css'
export function createApp(): {
app: App<Element>
router: Router
} {
const app =
import.meta.env.MODE === 'production'
? createSSRApp(Layout)
: _createApp(Layout)
const router = createRouter()
app
.use(router)
.component('LayCode', LayCode)
.component('LaySearch', LaySearch)
.component('LayTableBox', LayTableBox)
.use(Layui)
return { app, router }
}

View File

@@ -0,0 +1,36 @@
import vue from '@vitejs/plugin-vue'
import Markdown from 'vite-plugin-md'
import container from 'markdown-it-container'
import highlight from './highlight'
import snippet from './snippet'
import demo from './demo'
import createTitle from './create-title'
import createBlock from './create-block'
import createDescribe from './create-describe'
import createTable from './create-table'
import preWrapper from './pre-wrapper'
const plugins = [
vue({
include: [/\.vue$/, /\.md$/],
}),
Markdown({
markdownItOptions: {
html: true,
linkify: true,
typographer: true,
highlight,
},
markdownItSetup(md) {
md.use(snippet)
.use(preWrapper)
.use(container, 'demo', demo)
.use(...createTable('table', ''))
.use(...createBlock('block', ''))
.use(...createTitle('title', ''))
.use(...createDescribe('describe', ''))
},
}),
] as any
export default plugins

View File

@@ -0,0 +1,31 @@
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]
const info = token.info.trim().slice(klass.length).trim()
if (token.nesting === 1) {
return `<lay-block style="margin-left:8px;margin-bottom:40px;">${info}`
} else {
return '</lay-block>\n'
}
},
},
]
}

View File

@@ -0,0 +1,31 @@
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]
const info = token.info.trim().slice(klass.length).trim()
if (token.nesting === 1) {
return `<p style="margin-left: 24px;margin-bottom:20px;">${info}`
} else {
return '</p>\n'
}
},
},
]
}

View File

@@ -0,0 +1,31 @@
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]
const info = token.info.trim().slice(klass.length).trim()
if (token.nesting === 1) {
return `<lay-table-box>${info}`
} else {
return '</lay-table-box>\n'
}
},
},
]
}

View File

@@ -0,0 +1,33 @@
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]
const info = token.info.trim().slice(klass.length).trim()
if (token.nesting === 1) {
return `<lay-field title="${
info || defaultTitle
}" style="margin-top:20px;margin-bottom: 20px;">`
} else {
return '</lay-field>\n'
}
},
},
]
}

141
example/src/plugin/demo.ts Normal file
View File

@@ -0,0 +1,141 @@
import markdown from 'markdown-it'
import highlight from './highlight'
import type Token from 'markdown-it/lib/token'
function assignScript(script: string) {
const dependencies = {} as Record<string, string[]>
const attrs = {} as Record<string, string>
const content = script
.replace(/import\s?\{.*\}.*/g, (item) => {
const key = getInnerString(item.replace(/'/g, '"'), '"', '"')
const value = getInnerString(item.replace(/\s+/g, ''), '{', '}')
const list = value ? value.split(',') : []
if (key && dependencies[key]) {
dependencies[key] = dependencies[key].concat(list)
} else if (key) {
dependencies[key] = list
}
return ''
})
/**
* const -> let
*
* const a = -> let a =
* const a = -> a =
*/
.replace(/(const|let|var)\s\w*\s?=/g, (item) => {
const attr = getInnerString(item, '\\s', '\\s?=')
if (attr && !(attr in attrs)) {
attrs[attr] = attr
return `let ${attr} =`
} else {
return attr + ' ='
}
})
// Remove extra line breaks
.replace(/\n+/gm, '\n')
// Combine the import
const reImport = Object.keys(dependencies).reduce((all, item) => {
const filterAttrs = [...new Set(dependencies[item])]
return all + `import {${filterAttrs + ','}} from '${item}';\n`
}, '')
return reImport + content
}
/**
* Extract part of the new string from the middle of the string
* @param {string} string string
* @param {string} prefix RegExp string
* @param {string} postfix RegExp string
* @param {string} type g | m | i
*/
function getInnerString(
string: string,
prefix: string,
postfix = '',
type: 'i' | 'g' | 'm' = 'i'
): string | undefined {
const result = new RegExp(`${prefix}(.*)${postfix}`, type)
const match = string.match(result)
return match ? match[1].trim() : undefined
}
let script = '' // Record the <script> label of the current page
export default {
render: (tokens: Token[], idx: number): string => {
// the `demo` block of the current page
const htmlBlock = tokens.filter((item) => item.type === 'html_block')
const { nesting, info = '', map } = tokens[idx]
if (nesting === -1) {
return '</lay-code>'
}
const matchedInfo = info.trim().match(/^demo\s+(.*)$/)
const description = matchedInfo && matchedInfo[1]
const descTemplate = markdown().render(description || '')
let str = '' // copy the current `demo` block code
let lastLine = NaN
for (let i = 0; i < htmlBlock.length; i++) {
const item = htmlBlock[i]
if (item.map && map && item.map[0] >= map[0] && item.map[1] <= map[1]) {
const { map, content } = item
const delta = map[0] - (lastLine || map[1])
if (delta > 0) {
str += '\n'.repeat(delta)
}
str += content
lastLine = map[1]
if (i === 0) {
script = ''
}
// Remove top <template>
if (/^<template>/.test(content)) {
const reContent = content.match(/^<template>((\s|\S)*)<\/template>/m)
htmlBlock[i].content = (reContent && reContent[1]) || ''
}
// Extract the <script> label content
if (content.includes('<script')) {
if (/export\sdefault\s?\{/m.test(content)) {
const setup = content.match(
/setup\s?\(\)\s?\{((\s|\S)*)return\s?\{/m
)
const reContent = content.replace(
/export\sdefault\s?\{((\s|\S)*)\}/m,
(setup && setup[1]) || ''
)
const reScript = reContent.match(
/^<script\s?.*?>((\s|\S)*)<\/script>/m
)
script += (reScript && reScript[1]) || ''
} else {
const reScript = content.match(
/^<script\s?.*?>((\s|\S)*)<\/script>/m
)
script += (reScript && reScript[1]) || ''
}
htmlBlock[i].content = ''
}
// Change the last content to <script> of the current page
if (i + 1 === htmlBlock.length) {
htmlBlock[i].content = `
<script setup>
${assignScript(script)}
</script>`
}
}
}
return `
<lay-code>
${description ? `<template #description>${descTemplate}</template>` : ''}
<template #code>${highlight(str, 'vue')}</template>
`
},
}

View File

@@ -0,0 +1,44 @@
import prism from 'prismjs'
import loadLanguages from 'prismjs/components/index'
import escapeHtml from 'escape-html'
loadLanguages(['markup', 'css', 'javascript'])
function wrap(code: string, lang: string): string {
if (lang === 'text') {
code = escapeHtml(code)
}
return `<pre v-pre><code>${code}</code></pre>`
}
export default (str: string, lang: string): string => {
if (!lang) {
return wrap(str, 'text')
}
lang = lang.toLowerCase()
const rawLang = lang
if (lang === 'vue' || lang === 'html') {
lang = 'markup'
}
if (lang === 'md') {
lang = 'markdown'
}
if (lang === 'ts') {
lang = 'typescript'
}
if (lang === 'py') {
lang = 'python'
}
if (!prism.languages[lang]) {
try {
loadLanguages([lang])
} catch (e) {
console.warn(lang, e)
}
}
if (prism.languages[lang]) {
const code = prism.highlight(str, prism.languages[lang], lang)
return wrap(code, rawLang)
}
return wrap(str, 'text')
}

View File

@@ -0,0 +1,11 @@
import MarkdownIt from 'markdown-it'
export default (md: MarkdownIt): void => {
const fence = md.renderer.rules.fence!
md.renderer.rules.fence = (...args) => {
const [tokens, idx] = args
const token = tokens[idx]
const rawCode = fence(...args)
return `<div class="language-${token.info.trim()}">${rawCode}</div>`
}
}

View File

@@ -0,0 +1,39 @@
import fs from 'fs'
import MarkdownIt from 'markdown-it'
import { RuleBlock } from 'markdown-it/lib/parser_block'
export default (md: MarkdownIt): void => {
const parser: RuleBlock = (state, startLine, endLine, silent) => {
const CH = '<'.charCodeAt(0)
const pos = state.bMarks[startLine] + state.tShift[startLine]
const max = state.eMarks[startLine]
if (state.sCount[startLine] - state.blkIndent >= 4) {
return false
}
for (let i = 0; i < 3; ++i) {
const ch = state.src.charCodeAt(pos + i)
if (ch !== CH || pos + i >= max) return false
}
if (silent) {
return true
}
const start = pos + 3
const end = state.skipSpacesBack(max, pos)
const rawPath = state.src
.slice(start, end)
.trim()
.replace(/^@/, process.cwd())
const content = fs.existsSync(rawPath)
? fs.readFileSync(rawPath).toString()
: 'Not found: ' + rawPath
const meta = rawPath.replace(rawPath, '')
state.line = startLine + 1
const token = state.push('fence', 'code', 0)
token.info = rawPath.split('.').pop() + meta
token.content = content
token.markup = '```'
token.map = [startLine, startLine + 1]
return true
}
md.block.ruler.before('fence', 'snippet', parser)
}

View File

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

296
example/src/router/zh-CN.ts Normal file
View File

@@ -0,0 +1,296 @@
import BaseLayout from '../layouts/Layout.vue'
import Component from '../view/component.vue'
import Hooks from '../view/hooks.vue'
import Guide from '../view/guide.vue'
import Index from '../view/index.vue'
const zhCN = [
{
path: '/',
redirect: '/zh-CN/index',
component: BaseLayout,
meta: { title: '首页' },
children: [
{
path: '/zh-CN/index',
component: Index,
meta: { title: '指南' },
},
{
path: '/zh-CN/guide',
redirect: '/zh-CN/guide/introduce',
component: Guide,
meta: { title: '指南' },
children: [
{
path: '/zh-CN/guide/introduce',
component: () => import('../../docs/zh-CN/guide/introduce.md'),
meta: { title: '介绍' },
},
{
path: '/zh-CN/guide/getStarted',
component: () => import('../../docs/zh-CN/guide/getStarted.md'),
meta: { title: '安装' },
},
{
path: '/zh-CN/guide/changelog',
component: () => import('../../docs/zh-CN/guide/changelog.md'),
meta: { title: '更新' },
},
{
path: '/zh-CN/guide/problem',
component: () => import('../../docs/zh-CN/guide/problem.md'),
meta: { title: '问题' },
},
{
path: '/zh-CN/guide/contribution',
component: () => import('../../docs/zh-CN/guide/contribution.md'),
meta: { title: '贡献' },
},
{
path: '/zh-CN/guide/norms',
component: () => import('../../docs/zh-CN/guide/norms.md'),
meta: { title: '规范' },
},
{
path: '/zh-CN/guide/sandbox',
component: () => import('../../docs/zh-CN/guide/sandbox.md'),
meta: { title: '沙盒' },
},
],
},
{
path: '/zh-CN/components',
redirect: '/zh-CN/components/color',
component: Component,
meta: { title: '组件' },
children: [
{
path: '/zh-CN/components/layout',
component: () => import('../../docs/zh-CN/components/layout.md'),
meta: { title: '布局' },
},
{
path: '/zh-CN/components/color',
component: () => import('../../docs/zh-CN/components/color.md'),
meta: { title: '颜色' },
},
{
path: '/zh-CN/components/container',
component: () => import('../../docs/zh-CN/components/container.md'),
meta: { title: '容器' },
},
{
path: '/zh-CN/components/breadcrumb',
component: () =>
import('../../docs/zh-CN/components/breadcrumb.md'),
meta: { title: '面包屑' },
},
{
path: '/zh-CN/components/button',
component: () => import('../../docs/zh-CN/components/button.md'),
meta: { title: '按钮' },
},
{
path: '/zh-CN/components/icon',
component: () => import('../../docs/zh-CN/components/icon.md'),
meta: { title: '图标' },
},
{
path: '/zh-CN/components/panel',
component: () => import('../../docs/zh-CN/components/panel.md'),
meta: { title: '面板' },
},
{
path: '/zh-CN/components/animation',
component: () => import('../../docs/zh-CN/components/animation.md'),
meta: { title: '动画' },
},
{
path: '/zh-CN/components/card',
component: () => import('../../docs/zh-CN/components/card.md'),
meta: { title: '卡片' },
},
{
path: '/zh-CN/components/grid',
component: () => import('../../docs/zh-CN/components/grid.md'),
meta: { title: '栅格' },
},
{
path: '/zh-CN/components/form',
component: () => import('../../docs/zh-CN/components/form.md'),
meta: { title: '表单' },
},
{
path: '/zh-CN/components/badge',
component: () => import('../../docs/zh-CN/components/badge.md'),
meta: { title: '徽章' },
},
{
path: '/zh-CN/components/block',
component: () => import('../../docs/zh-CN/components/block.md'),
meta: { title: '辅助' },
},
{
path: '/zh-CN/components/line',
component: () => import('../../docs/zh-CN/components/line.md'),
meta: { title: '分割' },
},
{
path: '/zh-CN/components/progress',
component: () => import('../../docs/zh-CN/components/progress.md'),
meta: { title: '进度' },
},
{
path: '/zh-CN/components/menu',
component: () => import('../../docs/zh-CN/components/menu.md'),
meta: { title: '菜单' },
},
{
path: '/zh-CN/components/timeline',
component: () => import('../../docs/zh-CN/components/timeline.md'),
meta: { title: '时间线' },
},
{
path: '/zh-CN/components/collapse',
component: () => import('../../docs/zh-CN/components/collapse.md'),
meta: { title: '手风琴' },
},
{
path: '/zh-CN/components/table',
component: () => import('../../docs/zh-CN/components/table.md'),
meta: { title: '表格' },
},
{
path: '/zh-CN/components/avatar',
component: () => import('../../docs/zh-CN/components/avatar.md'),
meta: { title: '头像' },
},
{
path: '/zh-CN/components/field',
component: () => import('../../docs/zh-CN/components/field.md'),
meta: { title: '字段' },
},
{
path: '/zh-CN/components/empty',
component: () => import('../../docs/zh-CN/components/empty.md'),
meta: { title: '空' },
},
{
path: '/zh-CN/components/rate',
component: () => import('../../docs/zh-CN/components/rate.md'),
meta: { title: '评分' },
},
{
path: '/zh-CN/components/dropdown',
component: () => import('../../docs/zh-CN/components/dropdown.md'),
meta: { title: '下拉' },
},
{
path: '/zh-CN/components/tab',
component: () => import('../../docs/zh-CN/components/tab.md'),
meta: { title: '选项卡' },
},
{
path: '/zh-CN/components/iconPicker',
component: () =>
import('../../docs/zh-CN/components/iconPicker.md'),
meta: { title: '图标选择' },
},
{
path: '/zh-CN/components/tree',
component: () => import('../../docs/zh-CN/components/tree.md'),
meta: { title: '树形组件' },
},
{
path: '/zh-CN/components/page',
component: () => import('../../docs/zh-CN/components/page.md'),
meta: { title: '分页' },
},
{
path: '/zh-CN/components/transfer',
component: () => import('../../docs/zh-CN/components/transfer.md'),
meta: { title: '穿梭框' },
},
{
path: '/zh-CN/components/checkbox',
component: () => import('../../docs/zh-CN/components/checkbox.md'),
meta: { title: '复选框' },
},
{
path: '/zh-CN/components/radio',
component: () => import('../../docs/zh-CN/components/radio.md'),
meta: { title: '单选框' },
},
{
path: '/zh-CN/components/input',
component: () => import('../../docs/zh-CN/components/input.md'),
meta: { title: '输入框' },
},
{
path: '/zh-CN/components/textarea',
component: () => import('../../docs/zh-CN/components/textarea.md'),
meta: { title: '文本域' },
},
{
path: '/zh-CN/components/switch',
component: () => import('../../docs/zh-CN/components/switch.md'),
meta: { title: '开关' },
},
{
path: '/zh-CN/components/slider',
component: () => import('../../docs/zh-CN/components/slider.md'),
meta: { title: '滑块' },
},
{
path: '/zh-CN/components/carousel',
component: () => import('../../docs/zh-CN/components/carousel.md'),
meta: { title: '轮播' },
},
{
path: '/zh-CN/components/select',
component: () => import('../../docs/zh-CN/components/select.md'),
meta: { title: '下拉选择' },
},
{
path: '/zh-CN/components/colorPicker',
component: () =>
import('../../docs/zh-CN/components/colorPicker.md'),
meta: { title: '颜色选择器' },
},
{
path: '/zh-CN/components/layer',
component: () => import('../../docs/zh-CN/components/layer.md'),
meta: { title: '弹层' },
},
],
},
{
path: '/zh-CN/hooks',
redirect: '/zh-CN/hooks/useClickOutside',
component: Hooks,
meta: { title: 'hooks' },
children: [
{
path: '/zh-CN/hooks/useClickOutside',
component: () =>
import('../../docs/zh-CN/hooks/useClickOutside.md'),
meta: { title: 'useClickOutside' },
},
{
path: '/zh-CN/hooks/useFullScreen',
component: () => import('../../docs/zh-CN/hooks/useFullScreen.md'),
meta: { title: 'useFullScreen' },
},
{
path: '/zh-CN/hooks/useMove',
component: () => import('../../docs/zh-CN/hooks/useMove.md'),
meta: { title: 'useMove' },
},
],
},
],
},
]
export default zhCN

View File

@@ -0,0 +1,4 @@
{
"extends": "../../tsconfig.json",
"include": [".", "../../shims-vue.d.ts"]
}

View File

@@ -0,0 +1,360 @@
<template>
<lay-layout>
<lay-side>
<lay-scroll style="overflow-y: scroll">
<ul class="layui-menu layui-menu-lg layui-menu-docs">
<li
v-for="menu in menus"
:key="menu"
class="layui-menu-item-group"
lay-options="{type: 'group', isAllowSpread: true}"
>
<div class="layui-menu-body-title">{{ menu.title }}</div>
<hr />
<ul>
<li
v-for="children in menu.children"
:key="children"
:class="[
currentPath === children.path
? 'layui-menu-item-checked2'
: '',
]"
@click="handleClick(children)"
>
<div class="layui-menu-body-title">
<router-link :to="children.path">
<span>{{ children.title }}</span>
<span class="layui-font-12 layui-font-gray">
{{ children.subTitle }}
</span>
</router-link>
</div>
</li>
</ul>
</li>
</ul>
</lay-scroll>
</lay-side>
<lay-body>
<div style="padding: 20px">
<router-view />
</div>
</lay-body>
</lay-layout>
</template>
<script>
import { ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const route = useRoute()
const router = useRouter()
const currentPath = ref('/zh-CN/guide')
watch(
() => route.path,
(val) => {
currentPath.value = val
},
{
immediate: true,
deep: true,
}
)
const menus = [
{
id: 1,
title: '通用',
children: [
{
id: 20,
title: '颜色',
subTitle: 'color',
path: '/zh-CN/components/color',
},
{
id: 6,
title: '按钮',
subTitle: 'button',
path: '/zh-CN/components/button',
},
{
id: 7,
title: '图标',
subTitle: 'iconfont',
path: '/zh-CN/components/icon',
},
{
id: 10,
title: '动画',
subTitle: 'animation',
path: '/zh-CN/components/animation',
},
],
},
{
id: 1,
title: '布局',
children: [
{
id: 4,
title: '布局',
subTitle: 'layout',
path: '/zh-CN/components/layout',
},
{
id: 5,
title: '容器',
subTitle: 'container',
path: '/zh-CN/components/container',
},
{
id: 11,
title: '栅格',
subTitle: 'grid',
path: '/zh-CN/components/grid',
},
{
id: 8,
title: '面板',
subTitle: 'panel',
path: '/zh-CN/components/panel',
},
{
id: 9,
title: '卡片',
subTitle: 'card',
path: '/zh-CN/components/card',
},
],
},
{
id: 1,
title: '导航',
children: [
{
id: 16,
title: '菜单',
subTitle: 'nav',
path: '/zh-CN/components/menu',
},
{
id: 17,
title: '面包屑',
subTitle: 'breadcrumb',
path: '/zh-CN/components/breadcrumb',
},
{
id: 28,
title: '选项卡',
subTitle: 'tab',
path: '/zh-CN/components/tab',
},
{
id: 27,
title: '下拉菜单',
subTitle: 'dropdown',
path: '/zh-CN/components/dropdown',
},
],
},
{
id: 1,
title: '表单',
children: [
{
id: 36,
title: '开关',
subTitle: 'switch',
path: '/zh-CN/components/switch',
},
{
id: 32,
title: '复选框',
subTitle: 'checkbox',
path: '/zh-CN/components/checkbox',
},
{
id: 33,
title: '单选框',
subTitle: 'radio',
path: '/zh-CN/components/radio',
},
{
id: 34,
title: '输入框',
subTitle: 'input',
path: '/zh-CN/components/input',
},
{
id: 35,
title: '文本域',
subTitle: 'textarea',
path: '/zh-CN/components/textarea',
},
{
id: 39,
title: '下拉选择',
subTitle: 'select',
path: '/zh-CN/components/select',
},
{
id: 40,
title: '颜色选择器',
subTitle: 'colorPicker',
path: '/zh-CN/components/colorPicker',
},
{
id: 29,
title: '图标选择器',
subTitle: 'iconPicker',
path: '/zh-CN/components/iconPicker',
},
{
id: 26,
title: '评分',
subTitle: 'rate',
path: '/zh-CN/components/rate',
},
{
id: 37,
title: '滑块',
subTitle: 'slider',
path: '/zh-CN/components/slider',
},
{
id: 12,
title: '表单',
subTitle: 'form',
path: '/zh-CN/components/form',
},
],
},
{
id: 1,
title: '展示',
children: [
{
id: 18,
title: '进度',
subTitle: 'progress',
path: '/zh-CN/components/progress',
},
{
id: 19,
title: '时间线',
subTitle: 'timeline',
path: '/zh-CN/components/timeline',
},
{
id: 21,
title: '手风琴',
subTitle: 'collapse',
path: '/zh-CN/components/collapse',
},
{
id: 22,
title: '表格',
subTitle: 'table',
path: '/zh-CN/components/table',
},
{
id: 23,
title: '头像',
subTitle: 'avatar',
path: '/zh-CN/components/avatar',
},
{
id: 25,
title: '空',
subTitle: 'empty',
path: '/zh-CN/components/empty',
},
{
id: 29,
title: '分页',
subTitle: 'page',
path: '/zh-CN/components/page',
},
{
id: 30,
title: '树形组件',
subTitle: 'tree',
path: '/zh-CN/components/tree',
},
{
id: 31,
title: '穿梭框',
subTitle: 'transfer',
path: '/zh-CN/components/transfer',
},
{
id: 38,
title: '轮播',
subTitle: 'carousel',
path: '/zh-CN/components/carousel',
},
],
},
{
id: 1,
title: '辅助',
children: [
{
id: 13,
title: '徽章',
subTitle: 'badge',
path: '/zh-CN/components/badge',
},
{
id: 14,
title: '区块',
subTitle: 'block',
path: '/zh-CN/components/block',
},
{
id: 15,
title: '分割',
subTitle: 'line',
path: '/zh-CN/components/line',
},
{
id: 24,
title: '字段',
subTitle: 'field',
path: '/zh-CN/components/field',
},
],
},
{
id: 1,
title: '反馈',
children: [
{
id: 90,
title: '弹层',
subTitle: 'layer',
path: '/zh-CN/components/layer',
},
],
},
]
const selected = ref(1)
const handleClick = function (menu) {
selected.value = menu.id
router.push(menu.path)
}
return {
menus,
selected,
currentPath,
handleClick,
}
},
}
</script>

108
example/src/view/guide.vue Normal file
View File

@@ -0,0 +1,108 @@
<template>
<lay-layout>
<lay-side>
<lay-scroll style="overflow-y: scroll">
<ul class="layui-menu layui-menu-lg layui-menu-docs">
<li
v-for="menu in menus"
:key="menu"
class="layui-menu-item-group"
lay-options="{type: 'group', isAllowSpread: true}"
>
<div class="layui-menu-body-title">{{ menu.title }}</div>
<hr />
<ul>
<li
v-for="children in menu.children"
:key="children"
:class="[
currentPath === children.path
? 'layui-menu-item-checked2'
: '',
]"
@click="handleClick(children)"
>
<div class="layui-menu-body-title">
<router-link :to="children.path">
<span>{{ children.title }}</span>
<span class="layui-font-12 layui-font-gray">
{{ children.subTitle }}
</span>
</router-link>
</div>
</li>
</ul>
</li>
</ul>
</lay-scroll>
</lay-side>
<lay-body>
<div style="padding: 20px">
<router-view />
</div>
</lay-body>
</lay-layout>
</template>
<script>
import { ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const route = useRoute()
const router = useRouter()
const currentPath = ref('/zh-CN/guide')
watch(
() => route.path,
(val) => {
currentPath.value = val
},
{
immediate: true,
deep: true,
}
)
const menus = [
{
id: 1,
title: '基础',
children: [
{
id: 1,
title: '介绍',
subTitle: 'introduce',
path: '/zh-CN/guide/introduce',
},
{
id: 2,
title: '安装',
subTitle: 'get started',
path: '/zh-CN/guide/getStarted',
},
{
id: 3,
title: '更新',
subTitle: 'change log',
path: '/zh-CN/guide/changelog',
}
],
},
]
const selected = ref(1)
const handleClick = function (menu) {
selected.value = menu.id
router.push(menu.path)
}
return {
menus,
selected,
currentPath,
handleClick,
}
},
}
</script>

108
example/src/view/hooks.vue Normal file
View File

@@ -0,0 +1,108 @@
<template>
<lay-layout>
<lay-side>
<lay-scroll style="overflow-y: scroll">
<ul class="layui-menu layui-menu-lg layui-menu-docs">
<li
v-for="menu in menus"
:key="menu"
class="layui-menu-item-group"
lay-options="{type: 'group', isAllowSpread: true}"
>
<div class="layui-menu-body-title">{{ menu.title }}</div>
<hr />
<ul>
<li
v-for="children in menu.children"
:key="children"
:class="[
currentPath === children.path
? 'layui-menu-item-checked2'
: '',
]"
@click="handleClick(children)"
>
<div class="layui-menu-body-title">
<router-link :to="children.path">
<span>{{ children.title }}</span>
<span class="layui-font-12 layui-font-gray">
{{ children.subTitle }}
</span>
</router-link>
</div>
</li>
</ul>
</li>
</ul>
</lay-scroll>
</lay-side>
<lay-body>
<div style="padding: 20px">
<router-view />
</div>
</lay-body>
</lay-layout>
</template>
<script>
import { ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const route = useRoute()
const router = useRouter()
const currentPath = ref('/zh-CN/guide')
watch(
() => route.path,
(val) => {
currentPath.value = val
},
{
immediate: true,
deep: true,
}
)
const menus = [
{
id: 1,
title: 'hooks',
children: [
{
id: 1,
title: '事件',
subTitle: 'useClickOutside',
path: '/zh-CN/hooks/useClickOutside',
},
{
id: 3,
title: '拖拽',
subTitle: 'useMove',
path: '/zh-CN/hooks/useMove',
},
{
id: 2,
title: '全屏',
subTitle: 'useFullScreen',
path: '/zh-CN/hooks/useFullScreen',
},
],
},
]
const selected = ref(1)
const handleClick = function (menu) {
selected.value = menu.id
router.push(menu.path)
}
return {
menus,
selected,
currentPath,
handleClick,
}
},
}
</script>

248
example/src/view/index.vue Normal file
View File

@@ -0,0 +1,248 @@
<template>
<div
style="
margin-top: 60px;
background-color: whitesmoke;
height: 100%;
width: 100%;
"
>
<div class="site-banner">
<div class="site-banner-main">
<div class="site-zfj site-zfj-anim">
<i
class="layui-icon"
style="color: #fff; color: rgba(255, 255, 255, 0.6)"
></i
>
</div>
<div class="layui-anim site-desc site-desc-anim">
<p class="web-font-desc">layui - vue</p>
<cite>layui vue, A component library for Vue 3 base on layui</cite>
</div>
<div class="site-download">
<router-link
class="layui-inline site-down"
to="/zh-CN/guide/getStarted"
>Get Started</router-link
>
</div>
<div class="site-version">
<span>当前版本v<cite class="site-showv">0.2.4</cite></span>
<span
><router-link
class="layui-inline site-down"
to="/zh-CN/guide/changelog"
>更新日志</router-link
></span
>
<span>下载量<em class="site-showdowns">1824</em></span>
</div>
</div>
<div class="site-banner-other">
<a
href="https://gitee.com/layui-vue"
target="_blank"
rel="nofollow"
class="site-star"
>
<i class="layui-icon"></i> Star <cite id="getStars">257</cite>
</a>
<a
href="https://gitee.com/layui-vue"
target="_blank"
rel="nofollow"
class="site-fork"
>
Gitee
</a>
</div>
</div>
<div style="margin-left: 10%; margin-right: 10%">
<div>
<ul class="layui-row layui-col-space30 site-idea">
<li class="layui-col-md8">
<div>
<fieldset class="layui-elem-field layui-field-title">
<legend>返璞归真</legend>
<p>
身处在前端社区的繁荣之下我们都在有意或无意地追逐 layui
偏偏回望当初奔赴在返璞归真的漫漫征途自信并勇敢着追寻于原生态的书写指令试图以最简单的方式诠释高效
</p>
</fieldset>
</div>
</li>
<li class="layui-col-md8">
<div>
<fieldset class="layui-elem-field layui-field-title">
<legend>双面体验</legend>
<p>
拥有双面的不仅是人生还有
layui一面极简一面丰盈极简是视觉所见的外在是开发所念的简易丰盈是倾情雕琢的内在是信手拈来的承诺一切本应如此简而全双重体验
</p>
</fieldset>
</div>
</li>
<li class="layui-col-md8">
<div>
<fieldset class="layui-elem-field layui-field-title">
<legend>星辰大海</legend>
<p>
如果眼下还是一团零星之火那运筹帷幄之后迎面东风就是一场烈焰燎原吧那必定会是一番尽情的燃烧秋风萧瑟时散作满天星辰你看那四季轮回<!--海天相接-->正是
layui 不灭的执念
</p>
</fieldset>
</div>
</li>
</ul>
</div>
</div>
<div class="footer footer-index">
<p>
Copyright © 2021 <a href="/index.html">layui-vue.pearadmin.com</a> MIT
Licensed
</p>
<p></p>
</div>
</div>
</template>
<style>
.site-banner {
position: relative;
height: 600px;
text-align: center;
overflow: hidden;
background-color: #393d49;
}
.site-banner-bg {
background-position: center 0;
}
.site-banner-bg,
.site-banner-main {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.site-download {
margin-top: 72px;
font-size: 0;
}
.site-download a {
position: relative;
padding: 0 50px 0 50px;
height: 60px;
line-height: 60px;
border-radius: 4px;
border: 1px solid #c2c2c2;
border-color: rgba(255, 255, 255, 0.2);
font-size: 24px;
color: #ccc;
transition: all 0.5s;
-webkit-transition: all 0.5s;
}
.site-download a:hover {
background-color: rgba(255, 255, 255, 0.05);
border-radius: 50px;
color: #ccc;
}
.site-zfj {
padding-top: 25px;
height: 220px;
}
.site-zfj-anim i {
-webkit-animation-name: site-zfj;
animation-name: site-zfj;
-webkit-animation-duration: 5s;
animation-duration: 5s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
}
.site-zfj i {
position: absolute;
left: 50%;
top: 50px;
width: 200px;
height: 200px;
margin-left: -100px;
font-size: 180px;
color: #c2c2c2;
}
.site-desc-anim {
-webkit-animation-name: site-desc;
animation-name: site-desc;
}
.site-desc {
position: relative;
height: 70px;
margin-top: 20px;
}
.site-desc .web-font-desc {
color: #fff;
color: rgba(255, 255, 255, 0.8);
font-size: 51px;
}
.web-font-desc {
font-style: normal;
font-weight: 300;
}
.site-desc cite {
position: absolute;
bottom: -40px;
left: 0;
width: 100%;
color: #c2c2c2;
color: rgba(255, 255, 255, 0.66);
font-style: normal;
}
.site-version {
position: relative;
margin-top: 18px;
color: #ccc;
font-size: 12px;
}
.site-version span {
padding: 0 3px;
}
.site-version * {
font-style: normal;
}
.site-version a {
color: #e2e2e2;
text-decoration: none;
margin-top: -4px;
}
.site-banner-other {
position: absolute;
left: 0;
bottom: 35px;
width: 100%;
text-align: center;
font-size: 0;
}
.site-banner-other a {
display: inline-block;
vertical-align: middle;
height: 28px;
line-height: 28px;
margin: 0 6px;
padding: 0 8px;
border-radius: 4px;
color: #c2c2c2;
color: rgba(255, 255, 255, 0.8);
border: 1px solid #c2c2c2;
border-color: rgba(255, 255, 255, 0.2);
font-size: 14px;
transition: all 0.5s;
-webkit-transition: all 0.5s;
}
.footer {
width: 100%;
padding: 30px 15px;
line-height: 30px;
text-align: center;
color: #666;
font-weight: 300;
}
</style>

12
example/vite.config.ts Normal file
View File

@@ -0,0 +1,12 @@
import path from 'path'
import { defineConfig } from 'vite'
import plugins from './src/plugin/common-plugins'
export default defineConfig({
resolve: {
alias: {
'/@src': path.resolve(__dirname, '../src'),
},
},
plugins,
})