💬 补充 hooks 文档

This commit is contained in:
就眠儀式 2021-12-06 09:35:18 +08:00
parent 2fd930e6bc
commit 0592b3cd72
26 changed files with 144 additions and 291 deletions

View File

@ -72,6 +72,31 @@ export default {
:::
::: title 图标组件
:::
<br>
::: describe 在 0.2.4 版本后, 我们支持使用组件化调用的方式使用图标, 但你需要安装 `@layui/icons-vue` 库。
:::
```
npm install @layui/icons-vue
```
```vue
<template>
<!-- 组件图标 -->
<AlignCenterIcon></AlignCenterIcon>
<DiamondIcon></DiamondIcon>
</template>
<script setup>
import { AlignCenterIcon, DiamondIcon } from '@layui/icons-vue';
</script>
```
::: title 图标列表
:::

View File

@ -5,10 +5,8 @@
<template>
<lay-button @click="changeVisible1" type="primary">基础使用</lay-button>
<lay-modal title="基础使用" v-model:visible="visible1">
<div style="padding:10px">
<lay-modal title="基础使用" v-model="visible1">
这是一个基础弹窗
</div>
</lay-modal>
</template>
@ -40,10 +38,8 @@ export default {
<template>
<lay-button @click="changeVisible2" type="primary">允许拖动</lay-button>
<lay-modal title="允许拖动" v-model:visible="visible2" move="true">
<div style="padding:10px">
<lay-modal title="允许拖动" v-model="visible2">
这是一个可以拖拽的弹窗
</div>
</lay-modal>
</template>
@ -75,7 +71,7 @@ export default {
<template>
<lay-button @click="changeVisible3" type="primary">放大缩小</lay-button>
<lay-modal title="放大缩小" v-model:visible="visible3" move="true" maxmin="true">
<lay-modal title="放大缩小" v-model="visible3" move="true" maxmin="true">
<div style="padding:10px">
该弹窗支持放大缩小
</div>
@ -110,7 +106,7 @@ export default {
<template>
<lay-button @click="changeVisible4" type="primary">指定位置</lay-button>
<lay-modal title="指定位置" v-model:visible="visible4" move="true" :offset="['100px','100px']">
<lay-modal title="指定位置" v-model="visible4" move="true" :offset="['100px','100px']">
<div style="padding:10px">
指定弹窗显示的默认位置
</div>
@ -145,7 +141,7 @@ export default {
<template>
<lay-button @click="changeVisible5" type="primary">远程窗体</lay-button>
<lay-modal title="加载 Iframe 内容" width="500px" height="400px" maxmin="true" v-model:visible="visible5" move="true" :type="type5" content="http://www.pearadmin.com"></lay-modal>
<lay-modal title="加载 Iframe 内容" width="500px" height="400px" maxmin="true" v-model="visible5" move="true" :type="type5" content="http://www.pearadmin.com"></lay-modal>
</template>
<script>
@ -178,7 +174,7 @@ export default {
<template>
<lay-button @click="changeVisible6" type="primary">定义操作</lay-button>
<lay-modal title="定义操作" v-model:visible="visible6" move="true" :btn="btn6">
<lay-modal title="定义操作" v-model="visible6" move="true" :btn="btn6">
<div style="padding:10px">
定义一组弹窗操作按钮
</div>
@ -218,7 +214,7 @@ export default {
<template>
<lay-button @click="changeVisible7" type="primary">开启遮盖</lay-button>
<lay-modal title="开启遮盖" move="true" shade="false" v-model:visible="visible7">
<lay-modal title="开启遮盖" move="true" shade="false" v-model="visible7">
<div style="padding:10px">
允许点击遮盖层关闭弹窗
</div>

View File

@ -10,6 +10,11 @@
::: demo
<template>
<lay-timeline>
<lay-timeline-item title="0.2.7">
[依赖] hooks-vue 0.1.2。<br>
[升级] layer-vue 1.0.3。<br>
[修复] icons-vue 依赖 not found。<br>
</lay-timeline-item>
<lay-timeline-item title="0.2.6">
[依赖] hooks-vue 0.1.2。<br>
[升级] layer-vue 1.0.3。<br>

View File

@ -1,14 +1,6 @@
::: 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>

View File

@ -0,0 +1,21 @@
::: title 基础使用
:::
::: block 使 用 useBoolean 创 建 布 尔 类 型 的 Ref 响 应 变 量
:::
```vue
<script>
import { useBoolean } from '@layui/hooks-vue'
export default {
setup() {
const { setTrue, setFalse } = useBoolean(true)
return {
setTrue,
setFalse
}
},
}
</script>
```

View File

@ -11,7 +11,7 @@
<script>
import { ref, watch } from 'vue'
import useClickOutside from '/@src/hooks/useClickOutside'
import { useClickOutside } from '@layui/hooks-vue'
export default {
setup() {

View File

@ -10,7 +10,7 @@
</template>
<script>
import useFullScreen from '/@src/hooks/useFullScreen'
import { useFullScreen } from '@layui/hooks-vue'
export default {
setup() {

View File

@ -11,7 +11,7 @@
<script>
import { ref, watch, onMounted } from 'vue'
import useMove from '/@src/hooks/useMove'
import { useMove } from '@layui/hooks-vue'
export default {
setup() {

View File

@ -0,0 +1,12 @@
::: title 快速上手
:::
<br>
<br>
::: describe 1.使用 npm 下载
:::
```
npm install @layui/hooks-vue --save
```

View File

@ -0,0 +1,21 @@
::: title 基础使用
:::
::: block 使 用 useState 创 建 Ref 响 应 变 量
:::
```vue
<script>
import { useState } from '@layui/hooks-vue'
export default {
setup() {
const { state, setState } = useState(0)
return {
state,
setState
}
},
}
</script>
```

View File

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

View File

@ -2,7 +2,7 @@ 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 Layui from '../../src/index'
import LayCode from './components/LayCode.vue'
import LaySearch from './components/LaySearch.vue'
import LayTableBox from './components/LayTableBox.vue'

View File

@ -271,6 +271,12 @@ const zhCN = [
component: Hooks,
meta: { title: 'hooks' },
children: [
{
path: '/zh-CN/hooks/useStarted',
component: () =>
import('../../docs/zh-CN/hooks/useStarted.md'),
meta: { title: 'useStarted' },
},
{
path: '/zh-CN/hooks/useClickOutside',
component: () =>
@ -286,6 +292,15 @@ const zhCN = [
path: '/zh-CN/hooks/useMove',
component: () => import('../../docs/zh-CN/hooks/useMove.md'),
meta: { title: 'useMove' },
}, {
path: '/zh-CN/hooks/useState',
component: () => import('../../docs/zh-CN/hooks/useState.md'),
meta: { title: 'useState' },
},
{
path: '/zh-CN/hooks/useBoolean',
component: () => import('../../docs/zh-CN/hooks/useBoolean.md'),
meta: { title: 'useBoolean' },
},
],
},

View File

@ -68,6 +68,12 @@ export default {
id: 1,
title: 'hooks',
children: [
{
id: 0,
title: '开始',
subTitle: 'useStarted',
path: '/zh-CN/hooks/useStarted',
},
{
id: 1,
title: '事件',
@ -85,6 +91,16 @@ export default {
title: '全屏',
subTitle: 'useFullScreen',
path: '/zh-CN/hooks/useFullScreen',
},{
id: 3,
title: '状态',
subTitle: 'useState',
path: '/zh-CN/hooks/useState',
},{
id: 4,
title: '布尔',
subTitle: 'useBoolean',
path: '/zh-CN/hooks/useBoolean',
},
],
},

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "@layui/layui-vue",
"version": "0.2.6",
"version": "0.2.7",
"description": "a component library for Vue 3 base on layui-vue",
"homepage": "https://gitee.com/layui-vue/layui-vue/blob/master/README.md",
"module": "lib/layui-vue.es.js",
@ -13,7 +13,7 @@
"./lib/": "./lib/"
},
"types": "types/index.d.ts",
"style": "lib/layui.css",
"style": "lib/index.css",
"scripts": {
"dev": "vite",
"build": "vite build --emptyOutDir && npm run build:types",
@ -28,18 +28,18 @@
"author": "就眠儀式",
"license": "MIT",
"peerDependencies": {
"vue": "^3.2.22",
"vue": "^3.2.23",
"vue-router": "^4.0.12",
"@layui/layer-vue": "^1.0.3",
"@layui/layer-vue": "^1.0.6",
"@layui/icons-vue": "^1.0.0",
"@layui/hooks-vue": "^0.1.2"
"@layui/hooks-vue": "^0.1.6"
},
"dependencies": {
"vue": "^3.2.22",
"vue": "^3.2.23",
"vue-router": "^4.0.12",
"@layui/layer-vue": "^1.0.3",
"@layui/layer-vue": "^1.0.6",
"@layui/icons-vue": "^1.0.0",
"@layui/hooks-vue": "^0.1.2"
"@layui/hooks-vue": "^0.1.6"
},
"devDependencies": {
"@babel/core": "^7.15.8",
@ -50,8 +50,8 @@
"@types/markdown-it": "^12.2.3",
"@types/markdown-it-container": "^2.0.4",
"@vitejs/plugin-vue": "^1.9.3",
"@vue/compiler-sfc": "^3.2.22",
"@vue/server-renderer": "^3.2.20",
"@vue/compiler-sfc": "^3.2.23",
"@vue/server-renderer": "^3.2.23",
"escape-html": "^1.0.3",
"less": "^4.1.2",
"markdown-it-container": "^3.0.0",

View File

@ -1 +0,0 @@
import './useClickOutside.ts'

View File

@ -1,23 +0,0 @@
import { ref, onMounted, onUnmounted, Ref } from 'vue'
const x = undefined
const useClickOutside = (elementRef: Ref<HTMLElement | null>) => {
const isClickOutside = ref(false)
const handler = (e: MouseEvent) => {
if (elementRef.value) {
if (elementRef.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false
} else {
isClickOutside.value = true
}
}
}
onMounted(() => {
document.addEventListener('click', handler)
})
onUnmounted(() => {
document.removeEventListener('click', handler)
})
return isClickOutside
}
export default useClickOutside

View File

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

View File

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

View File

@ -1,7 +0,0 @@
import { ref, onMounted, onUnmounted, Ref } from 'vue'
const useNestedEvent = (elementRef: Ref<HTMLElement | null>) => {
const event = ref(false)
return event
}
export default useNestedEvent

View File

@ -1,91 +0,0 @@
// @ts-noCheck
// 是否滚动
export const hasScrollbar = () =>
document.body.scrollHeight >
(window.innerHeight || document.documentElement.clientHeight)
// 窗口宽高
export const winArea = (type?: any) =>
document.documentElement[type ? 'clientWidth' : 'clientHeight']
//
export const scrollArea: any = (type: any) => {
type = type ? 'scrollLeft' : 'scrollTop'
return document.body[type] | document.documentElement[type]
}
export function usePosition(elem?: any, elemView?: any, obj?: any) {
if (!elemView) return
obj = obj || {}
//如果绑定的是 document 或 body 元素,则直接获取鼠标坐标
if (elem === document || elem.name === 'body') {
obj.clickType = 'right'
}
//绑定绑定元素的坐标
const rect =
obj.clickType === 'right'
? (function () {
const e = obj.e || window.event || {}
return {
left: e.clientX,
top: e.clientY,
right: e.clientX,
bottom: e.clientY,
}
})()
: elem.getBoundingClientRect()
const elemWidth = elemView.offsetWidth //控件的宽度
const elemHeight = elemView.offsetHeight //控件的高度
const margin = 5
let left = rect.left
let top = rect.bottom
//相对元素居中
if (obj.align === 'center') {
left = left - (elemWidth - elem.offsetWidth) / 2
} else if (obj.align === 'right') {
left = left - elemWidth + elem.offsetWidth
}
//判断右侧是否超出边界
if (left + elemWidth + margin > winArea('width')) {
left = winArea('width') - elemWidth - margin //如果超出右侧,则将面板向右靠齐
}
//左侧是否超出边界
if (left < margin) left = margin
//判断底部和顶部是否超出边界
if (top + elemHeight + margin > winArea()) {
//优先顶部是否有足够区域显示完全
if (rect.top > elemHeight + margin) {
top = rect.top - elemHeight - margin * 2 //顶部有足够的区域显示
} else {
//如果面板是鼠标右键弹出,且顶部没有足够区域显示,则将面板向底部靠齐
if (obj.clickType === 'right') {
top = winArea() - elemHeight - margin * 2
if (top < 0) top = 0 //不能溢出窗口顶部
}
}
}
//定位类型
const position = obj.position
if (position) elemView.style.position = position
//设置坐标
elemView.style.left = left + (position === 'fixed' ? 0 : scrollArea(1)) + 'px'
elemView.style.top = top + (position === 'fixed' ? 0 : scrollArea()) + 'px'
//防止页面无滚动条时,又因为弹出面板而出现滚动条导致的坐标计算偏差
if (!hasScrollbar()) {
const rect1 = elemView.getBoundingClientRect()
//如果弹出面板的溢出窗口底部,则表示将出现滚动条,此时需要重新计算坐标
if (!obj.SYSTEM_RELOAD && rect1.bottom + margin > winArea()) {
obj.SYSTEM_RELOAD = true
setTimeout(function () {
usePosition(elem, elemView, obj)
}, 50)
}
}
}

View File

@ -2,7 +2,7 @@ import type { App } from 'vue'
import type { IDefineComponent, InstallOptions } from './module/type/index'
import './css/layui.css';
import '@layui/layer-vue/lib/layer.css';
import '@layui/layer-vue/lib/index.css';
import '@layui/icons-vue/lib/index.css';
import { layer } from '@layui/layer-vue'

View File

@ -4,11 +4,11 @@ export default {
}
</script>
<script setup lang="ts">
import { Nullable } from '/@src/module/type'
import { Nullable } from '../type'
import { computed, onMounted, ref } from 'vue'
import { HSBToHEX, RGBSTo, RGBToHSB } from '/@src/module/colorPicker/colorUtil'
import { HSBToHEX, RGBSTo, RGBToHSB } from './colorUtil'
import ColorPicker from './ColorPicker.vue'
import { usePosition } from '/@src/hooks/usePosition'
import { usePosition } from '@layui/hooks-vue'
interface BoxProps {
color?: string

View File

@ -34,7 +34,7 @@
<script setup name="LaySelect" lang="ts">
import { defineProps, provide, ref, watch } from 'vue'
import useClickOutside from '../../hooks/useClickOutside'
import { useClickOutside } from '@layui/hooks-vue'
const dropdownRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(dropdownRef)

View File

@ -22,7 +22,7 @@
<script setup name="LaySelect" lang="ts">
import { defineProps, provide, reactive, ref, watch } from 'vue'
import useClickOutside from '../../hooks/useClickOutside'
import { useClickOutside } from '@layui/hooks-vue'
const selectRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(selectRef)