♻️(document): 调整文档结构

This commit is contained in:
就眠儀式
2022-06-25 20:10:12 +08:00
parent d18425cb2a
commit b86b7d308c
166 changed files with 528 additions and 60 deletions

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
package/document-layer/dist/favicon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

28
package/document-layer/dist/index.html vendored Normal file
View File

@@ -0,0 +1,28 @@
<!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>layer-vue 弹层解决方案</title>
<!--preload-links-->
<script type="module" crossorigin src="/assets/index.1157d8c1.js"></script>
<link rel="stylesheet" href="/assets/index.e9614e1e.css">
</head>
<body>
<div id="app">
<!--app-html-->
</div>
</body>
</html>

View File

View File

@@ -0,0 +1,586 @@
<fieldset class="layui-elem-field layui-field-title">
<legend>安装</legend>
</fieldset>
通过 npm 工具安装 :
```
npm install @layui/layer-vue
```
在 main.ts 完成 layer-vue 的注册, 并导入 css 文件 :
```
import App from './App';
import { createApp } from 'vue';
import layer from '@layui/layer-vue';
import '@layui/layer-vue/lib/index.css';
const app = createApp(App);
app.use(layer).mount('#app');
```
<fieldset class="layui-elem-field layui-field-title">
<legend>场景</legend>
</fieldset>
因 layer-vue 可以独立使用,也可以在 layui-vue 中使用。所以请按照你的实际需求来选择。
如果你想独立使用 layer-vue, 你需要通过 npm 安装。如果你使用的是 layui-vue, 那么你无需安装 layer-vue。
<fieldset class="layui-elem-field layui-field-title">
<legend>入门</legend>
</fieldset>
我们提供 `layer` 函数来创建弹出层 :
```
<template>
<button type="button" @click="open">打开</button>
</template>
<script setup>
import { layer } from "@layui/layer-vue";
const open = function () {
layer.open({title:"标题", content: "内容"});
};
</script>
```
但在较为复杂的应用场景中, `lay-layer` 是一个更好的选择 :
```
<template>
<button @click="changeVisible">显示/隐藏</button>
<lay-layer v-model="visible">
content
</lay-layer>
</template>
<script setup>
import { ref } from "vue";
const visible = ref(false);
const changeVisible = () => {
visible.value = !visible.value;
}
</script>
```
<fieldset class="layui-elem-field layui-field-title">
<legend>消息</legend>
</fieldset>
::: demo 通过 layer.msg(content, options) 创建消息窗, 第一个参数`msg`为消息内容, 第二参数`options`为可选配置, 常用于配置`time`超时时间等。
<template>
<button @click="msg">普通消息</button>
<button @click="success">成功消息</button>
<button @click="failure">失败消息</button>
<button @click="warm">警告消息</button>
<button @click="info">锁定消息</button>
</template>
<script>
import { layer } from "../../../layer/src/index"
const msg = function() {
layer.msg("普通消息", { time: 1000 })
}
const success = function() {
layer.msg("成功消息", { time: 1000, icon: 1})
}
const failure = function() {
layer.msg("失败消息", { time: 1000, icon: 2})
}
const warm = function() {
layer.msg("警告消息", { time: 1000, icon: 3})
}
const info = function() {
layer.msg("疑问消息", { time: 1000, icon: 4})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>加载</legend>
</fieldset>
::: demo 通过 layer.load(type, options) 创建加载层, 第一个参数`type`为加载动画样式, 第二个参数`options`为可选配置, 常用于设置`time`加载时长`shade`遮盖层等。
<template>
<button @click="load1">加载1</button>
<button @click="load2">加载2</button>
<button @click="load3">加载3</button>
<button @click="load4">加载4</button>
</template>
<script setup>
import { layer } from "../../../layer/src/index"
const load1 = function() {
layer.load(0, {time: 2000})
}
const load2 = function() {
layer.load(1, {time: 2000})
}
const load3 = function() {
layer.load(2, {time: 2000})
}
const load4 = function() {
layer.msg("加载中...",{icon: 16, time: 2000})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>模态</legend>
</fieldset>
::: demo 通过 layer.open(option) 创建模态窗, 目前支持`iframe` `page`等类型, 你可以使用`options`选项开启`Resize` `Offset`等更多特性。
<template>
<button @click="open">小试牛刀</button>
<button @click="openSize">指定尺寸</button>
<button @click="openOffset">指定位置</button>
<button @click="openIframe">远程窗体</button>
<button @click="openHtml">HTML</button>
<button @click="openVNode">vNode</button>
<button @click="openMaxmin">缩小放大</button>
<button @click="openResize">尺寸拉伸</button>
<button @click="openIndex">设置层级</button>
<button @click="openAreaAuto">内容自撑开</button>
<button @click="openBtns">自定义按钮组</button>
</template>
<script setup>
import { layer } from "../../../layer/src/index"
const open = function() {
layer.open({
type: 1,
title: "标题",
content: "内容"
})
}
const openSize = function() {
layer.open({
type: 1,
title: "标题",
area: ['400px','400px'],
content: "内容"
})
}
const openOffset = function() {
layer.open({
type: 1,
title: "标题",
offset: ['100px','100px'],
content: "内容"
})
}
const openIframe = function() {
layer.open({
type: 2,
title: "标题",
resize: true,
area: ['500px','500px'],
content: "http://layui-vue.pearadmin.com"
})
}
const openHtml = function() {
layer.open({
type: 1,
title: "标题",
isHtmlFragment: true,
content: "<p style='color:red;'>内容</p>"
})
}
const openVNode = function() {
layer.open({
type: 1,
title: "标题",
content: h('button', { style: 'margin: 10px;' },'按钮')
})
}
const openMaxmin = function() {
layer.open({
type: 1,
title: "标题",
maxmin: true,
content: "内容"
})
}
const openResize = function() {
layer.open({
type: 1,
title: "标题",
resize: true,
content: "内容"
})
}
const openIndex = function() {
layer.open({
type: 1,
title: "标题",
zIndex: 666,
content: "设置层级"
})
}
const openAreaAuto = function(){
layer.open({
type:1,
title:"area:auto",
isHtmlFragment:true,
content:"<img src='https://chixian.oss-cn-hangzhou.aliyuncs.com/20210819230007_346ce.jpeg'/>"
})
}
const openBtns = function(){
layer.open({
type:1,
title:"自定义按钮",
btn:[{text:"第一个按钮",callback:function(){
console.log("第一个按钮被点击");
}},{text:"第二个按钮",callback:function(){
console.log("第二个按钮被点击");
}}]
})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>询问</legend>
</fieldset>
::: demo 通过 layer.confirm(msg, options) 创建确认框, 第一个参数`msg`为文本消息, 第二个参数`options`为选项配置, 你可以使用`options``btn`属性定义操作。
<template>
<button @click="openConfirm1">确认框</button>
<button @click="openConfirm2">询问框</button>
</template>
<script setup>
import { layer } from "../../../layer/src/index"
const openConfirm1 = function() {
layer.confirm("layui-vue 1.0.0 已经发布")
}
const openConfirm2 = function() {
layer.confirm("你如何看待 layui-vue 的发布", {btn: [{text:'站着看', callback: function(){
layer.msg("有点意思");
}},{text:'坐着看', callback: function(){
layer.msg("无聊");
}}]})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>抽屉</legend>
</fieldset>
::: demo 通过 layer.drawer(options) 创建抽屉层, `options`选项配置, 抽屉本质上是一个特殊的模态窗, 你可以使用`offset`选项来设置方向。
<template>
<button @click="openTop">上</button>
<button @click="openBottom">下</button>
<button @click="openLeft">左</button>
<button @click="openRight">右</button>
</template>
<script setup>
import { layer } from "../../../layer/src/index"
const openTop = function() {
layer.drawer({
title: "标题",
content: "内容",
offset: "t"
})
}
const openBottom = function() {
layer.drawer({
title: "标题",
content: "内容",
offset: "b"
})
}
const openLeft = function() {
layer.drawer({
title: "标题",
content: "内容",
offset: "l"
})
}
const openRight = function() {
layer.drawer({
title: "标题",
content: "内容",
offset: "r"
})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>图片层</legend>
</fieldset>
::: demo 通过 layer.photos(options) 创建图片预览弹层, 参数`options`主要传入预览的图片链接。
<template>
<button @click="signleImg">快速预览一张图片</button>
<button @click="signleImg2">单张图片带文字描述</button>
<button @click="groupImg">图片组</button>
</template>
<script>
import { layer } from "../../../layer/src/index"
const signleImg = function() {
layer.photos("/src/assets/logo.jpg")
}
const signleImg2 = function() {
layer.photos({
imgList:[ {src:'/src/assets/logo.jpg',alt:'layer for vue'}]
})
}
const groupImg = function() {
layer.photos({
imgList:[
{ src:'http://www.pearadmin.com/assets/images/un8.svg', alt:'图片1'},
{ src:'http://www.pearadmin.com/assets/images/un32.svg', alt:'图片2'}
]
})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>通讯</legend>
</fieldset>
::: demo 👉 查看 [Children1.vue](https://gitee.com/layui-vue/layer-vue/blob/master/example/src/components/Children1.vue), 通过 h() 函数的第二个参数向 Children1.vue 传递响应式变量。
<template>
<button @click="openComponent1">数据</button>
<input type="text" v-model="data.remark" />
</template>
<script setup>
import { reactive, h, resolveComponent } from 'vue'
import { layer } from "../../../layer/src/index"
const data = reactive({
remark: "信息"
})
const ChildrenOne = resolveComponent('Children1')
const openComponent1 = () => {
layer.open({
title: '标题',
content: h(ChildrenOne, { data }),
shade: false,
})
}
</script>
:::
::: demo 👉 查看 [Children2.vue](https://gitee.com/layui-vue/layer-vue/blob/master/example/src/components/Children2.vue), 通过 h() 函数的第二个参数声明 onXxx() 形式的函数完成 Children2.vue 的事件监听。
<template>
<button @click="openComponent2">事件</button>
<input type="text" v-model="numb" />
</template>
<script setup>
import { reactive, h, resolveComponent } from 'vue'
import { layer } from "../../../layer/src/index"
const prop = reactive({})
const numb = ref(1000)
const ChildrenTwo = resolveComponent('Children2')
const openComponent2 = () => {
layer.open({
title: '标题',
content: h(ChildrenTwo, {
prop,
onAdd(res){
numb.value = numb.value + 1;
}, onSub(res) {
numb.value = numb.value - 1;
}
}),
})
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>销毁</legend>
</fieldset>
::: demo 我们提供 layer.close(id) 与 layer.closeAll() 函数实现弹出层的主动销毁。
<template>
<button @click="open">打开</button>
<button @click="close">销毁</button>
<button @click="closeAll">销毁全部</button>
</template>
<script setup>
const open = function() {
const id = layer.open({
title: "标题",
content: "内容",
shade: false
})
return id;
}
const close = function() {
layer.close(open);
}
const closeAll = function() {
layer.closeAll();
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>组件</legend>
</fieldset>
::: demo 我们提供了一些核心函数来创建弹出层, 但在一些复杂的应用场景中, `lay-layer`是一个更好的选择。
<template>
<button @click="changeVisible">{{ visible ? '隐藏':'显示' }}</button>
<lay-layer title="标题" v-model="visible" :area="['300px','300px']">
content
</lay-layer>
</template>
<script setup>
import { ref, reactive, h } from 'vue'
import { LayLayer } from "../../../layer/src/index"
const visible = ref(false)
const changeVisible = () => {
visible.value = !visible.value;
}
</script>
:::
<fieldset class="layui-elem-field layui-field-title">
<legend>选项</legend>
</fieldset>
我们提供了丰富的 `options` 配置, 你可以通过配置来满足对 layer 的定制化, 需要注意的是有些属性仅适用部分组件。
| 属性 | 描述 | 类型 | 默认值 | 可选值 |
| -- | -- | -- | -- | -- |
| type | 类型 | string | `1` | `0` `1` `2` `3` |
| title | 标题 | string boolean | `信息` | -- |
| content | 内容 | string vnode | -- | -- |
| v-model | 显示 | boolean | `false` | `true` `false` |
| offset | 位置 | string array | `['50%','50%']` | -- |
| area | 尺寸 | string array | `auto` | -- |
| move | 拖拽 | boolean | `true` | `true` `false` |anim
| maxmin | 缩放 | boolean | `false` | `true` `false` |
| resize | 拉伸 | boolean | `false` | `true` `false` |
| anim | 入场动画 | number | `0` | `0` - `6` |
| isOutAnim | 出场动画 | boolean | `true` | `true` `false` |
| btnAlign | 按钮位置 | string | `r` | `l` `c` `r` |
| closeBtn | 关闭按钮 | boolean | `true` | `true` `false` |
| time | 关闭时间 | number | `0` | -- |
| shade | 遮盖层 | boolean | `true` | `true` `false` |
| shadeClose | 遮盖层关闭 | boolean | `true` | `true` `false` |
| shadeOpacity | 遮盖层透明度 | string | `0.1` | `0.1` - `1` |
| isHtmlFragment | 解析 html 字符 | boolean | `false` | `true` `false` |
| imgList | 图片数据数组 | array[{src:图片链接,alt:图片名字可选'}] | - | - |
<fieldset class="layui-elem-field layui-field-title">
<legend>动画</legend>
</fieldset>
animNumber默认0
我们的出场动画全部采用CSS3。这意味着除了ie6-9其它所有浏览器都是支持的。目前anim可支持的动画类型有0-6 如果不想显示动画,设置 anim: -1 即可。
另外需要注意的是3.0之前的版本用的是 shift 参数。
| 属性 | 描述 |
| -- | -- |
| anim:0 | 平滑放大 |
| anim:1 | 从上掉落 |
| anim:2 | 从最底部往上滑入 |
| anim:3 | 从左滑入 |
| anim:4 | 从左翻滚 |
| anim:5 | 渐显 |
| anim:5 | 抖动 |
<fieldset class="layui-elem-field layui-field-title">
<legend>问题</legend>
</fieldset>
直接调用 layer 的方法,组件会通过 Vue.render 动态创建新的 Vue 实体。其 context 与当前代码所在 context 并不相同,因而无法获取 context 信息。
当你需要 context 信息(例如使用全局注册的组件)时,可以通过 appContext 属性传递当前组件 context, 当你需要保留属性响应式时,你可以使用函数返回:
```
import { getCurrentInstance, ref } from 'vue';
import { layer } from "@layui/layer-vue";
const appContext = getCurrentInstance().appContext;
const title = ref("标题")
layer.open({
title: () => title.value,
content: h("children"),
appContext: appContext
})
```
<fieldset class="layui-elem-field layui-field-title">
<legend>结语</legend>
</fieldset>
::: demo 以写作为工具,为道途,先帮助自己一程,再以自己的领悟帮助他人一程, 这是一种服务 -- 庆山
<template></template>
<script setup></script>
:::

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 step() 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,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>layer-vue 弹层解决方案</title>
<!--preload-links-->
</head>
<body>
<div id="app">
<!--app-html-->
</div>
<script type="module" src="./entry-client.ts"></script>
</body>
</html>

View File

@@ -0,0 +1,24 @@
import Layout from "./App.vue";
import { App, createApp as _createApp } from "vue";
import { createRouter } from "./src/router/index";
import { Router } from "vue-router";
import LayCode from "./src/components/LayCode.vue";
import Children1 from "./src/components/Children1.vue";
import Children2 from "./src/components/Children2.vue";
import "./src/assets/css/index.css";
export function createApp(): {
app: App<Element>;
router: Router;
} {
const app = _createApp(Layout);
const router = createRouter();
app
.use(router)
.component("LayCode", LayCode)
.component("Children1", Children1)
.component("Children2", Children2);
return { app, router };
}

View File

@@ -0,0 +1,44 @@
{
"name": "@layui/layer-doc",
"version": "1.3.18",
"author": "就眠儀式",
"license": "MIT",
"description": "a component library for Vue 3 base on layui-vue",
"homepage": "http://www.layui-vue.com",
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"vue-router": "^4.0.15",
"vue-i18n": "^9.1.10",
"@vueuse/core": "^8.7.3",
"pinia": "^2.0.14",
"pinia-plugin-persist": "^1.0.0",
"axios": "^0.27.2"
},
"devDependencies": {
"@types/markdown-it": "^12.2.3",
"@types/markdown-it-container": "^2.0.4",
"@types/prettier": "^2.4.4",
"escape-html": "^1.0.3",
"markdown-it-container": "^3.0.0",
"prismjs": "^1.28.0",
"rimraf": "^3.0.2",
"rollup": "^2.70.1",
"typescript": "^4.6.3",
"vite-plugin-md": "^0.13.1",
"vite": "2.9.8"
},
"files": [
"lib",
"es",
"umd",
"types"
],
"browserslist": [
"current node",
"last 2 versions and > 2%",
"ie > 10"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,899 @@
.markdown-body {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
margin: 0;
color: #24292f;
background-color: #ffffff;
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";
font-size: 16px;
line-height: 1.5;
word-wrap: break-word;
}
.markdown-body .octicon {
display: inline-block;
fill: currentColor;
vertical-align: text-bottom;
}
.markdown-body h1:hover .anchor .octicon-link:before,
.markdown-body h2:hover .anchor .octicon-link:before,
.markdown-body h3:hover .anchor .octicon-link:before,
.markdown-body h4:hover .anchor .octicon-link:before,
.markdown-body h5:hover .anchor .octicon-link:before,
.markdown-body h6:hover .anchor .octicon-link:before {
width: 16px;
height: 16px;
content: ' ';
display: inline-block;
background-color: currentColor;
-webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");
mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' version='1.1' aria-hidden='true'><path fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z'></path></svg>");
}
.markdown-body details,
.markdown-body figcaption,
.markdown-body figure {
display: block;
}
.markdown-body summary {
display: list-item;
}
.markdown-body [hidden] {
display: none !important;
}
.markdown-body a {
background-color: transparent;
color: #0969da;
text-decoration: none;
}
.markdown-body a:active,
.markdown-body a:hover {
outline-width: 0;
}
.markdown-body abbr[title] {
border-bottom: none;
text-decoration: underline dotted;
}
.markdown-body b,
.markdown-body strong {
font-weight: 600;
}
.markdown-body dfn {
font-style: italic;
}
.markdown-body h1 {
margin: .67em 0;
font-weight: 600;
padding-bottom: .3em;
font-size: 2em;
border-bottom: 1px solid hsla(210,18%,87%,1);
}
.markdown-body mark {
background-color: #fff8c5;
color: #24292f;
}
.markdown-body small {
font-size: 90%;
}
.markdown-body sub,
.markdown-body sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
.markdown-body sub {
bottom: -0.25em;
}
.markdown-body sup {
top: -0.5em;
}
.markdown-body img {
border-style: none;
max-width: 100%;
box-sizing: content-box;
background-color: #ffffff;
}
.markdown-body code,
.markdown-body kbd,
.markdown-body pre,
.markdown-body samp {
font-family: monospace,monospace;
font-size: 1em;
}
.markdown-body figure {
margin: 1em 40px;
}
.markdown-body hr {
box-sizing: content-box;
overflow: hidden;
background: transparent;
border-bottom: 1px solid hsla(210,18%,87%,1);
height: .25em;
padding: 0;
margin: 24px 0;
background-color: #d0d7de;
border: 0;
}
.markdown-body [type=button],
.markdown-body [type=reset],
.markdown-body [type=submit] {
-webkit-appearance: button;
}
.markdown-body [type=button]::-moz-focus-inner,
.markdown-body [type=reset]::-moz-focus-inner,
.markdown-body [type=submit]::-moz-focus-inner {
border-style: none;
padding: 0;
}
.markdown-body [type=button]:-moz-focusring,
.markdown-body [type=reset]:-moz-focusring,
.markdown-body [type=submit]:-moz-focusring {
outline: 1px dotted ButtonText;
}
.markdown-body [type=checkbox],
.markdown-body [type=radio] {
box-sizing: border-box;
padding: 0;
}
.markdown-body [type=number]::-webkit-inner-spin-button,
.markdown-body [type=number]::-webkit-outer-spin-button {
height: auto;
}
.markdown-body [type=search] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
.markdown-body [type=search]::-webkit-search-cancel-button,
.markdown-body [type=search]::-webkit-search-decoration {
-webkit-appearance: none;
}
.markdown-body ::-webkit-input-placeholder {
color: inherit;
opacity: .54;
}
.markdown-body ::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
.markdown-body a:hover {
text-decoration: underline;
}
.markdown-body hr::before {
display: table;
content: "";
}
.markdown-body hr::after {
display: table;
clear: both;
content: "";
}
.markdown-body td,
.markdown-body th {
padding: 0;
}
.markdown-body details summary {
cursor: pointer;
}
.markdown-body details:not([open])>*:not(summary) {
display: none !important;
}
.markdown-body kbd {
display: inline-block;
padding: 3px 5px;
font: 11px ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
line-height: 10px;
color: #24292f;
vertical-align: middle;
background-color: #f6f8fa;
border: solid 1px rgba(175,184,193,0.2);
border-bottom-color: rgba(175,184,193,0.2);
border-radius: 6px;
box-shadow: inset 0 -1px 0 rgba(175,184,193,0.2);
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin-top: 24px;
margin-bottom: 16px;
font-weight: 600;
line-height: 1.25;
}
.markdown-body h2 {
font-weight: 600;
padding-bottom: .3em;
font-size: 1.5em;
border-bottom: 1px solid hsla(210,18%,87%,1);
}
.markdown-body h3 {
font-weight: 600;
font-size: 1.25em;
}
.markdown-body h4 {
font-weight: 600;
font-size: 1em;
}
.markdown-body h5 {
font-weight: 600;
font-size: .875em;
}
.markdown-body h6 {
font-weight: 600;
font-size: .85em;
color: #57606a;
}
.markdown-body p {
margin-top: 15;
margin-bottom: 15px;
font-size: 14px;
}
.markdown-body blockquote {
margin: 0;
padding: 0 1em;
color: #57606a;
border-left: .25em solid #d0d7de;
}
.markdown-body ul,
.markdown-body ol {
margin-top: 0;
margin-bottom: 0;
padding-left: 2em;
}
.markdown-body ol ol,
.markdown-body ul ol {
list-style-type: lower-roman;
}
.markdown-body ul ul ol,
.markdown-body ul ol ol,
.markdown-body ol ul ol,
.markdown-body ol ol ol {
list-style-type: lower-alpha;
}
.markdown-body dd {
margin-left: 0;
}
.markdown-body tt,
.markdown-body code {
font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
font-size: 12px;
}
.markdown-body pre {
margin-top: 0;
margin-bottom: 0;
font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
font-size: 12px;
word-wrap: normal;
}
.markdown-body .octicon {
display: inline-block;
overflow: visible !important;
vertical-align: text-bottom;
fill: currentColor;
}
.markdown-body ::placeholder {
color: #6e7781;
opacity: 1;
}
.markdown-body input::-webkit-outer-spin-button,
.markdown-body input::-webkit-inner-spin-button {
margin: 0;
-webkit-appearance: none;
appearance: none;
}
.markdown-body .pl-c {
color: #6e7781;
}
.markdown-body .pl-c1,
.markdown-body .pl-s .pl-v {
color: #0550ae;
}
.markdown-body .pl-e,
.markdown-body .pl-en {
color: #8250df;
}
.markdown-body .pl-smi,
.markdown-body .pl-s .pl-s1 {
color: #24292f;
}
.markdown-body .pl-ent {
color: #116329;
}
.markdown-body .pl-k {
color: #cf222e;
}
.markdown-body .pl-s,
.markdown-body .pl-pds,
.markdown-body .pl-s .pl-pse .pl-s1,
.markdown-body .pl-sr,
.markdown-body .pl-sr .pl-cce,
.markdown-body .pl-sr .pl-sre,
.markdown-body .pl-sr .pl-sra {
color: #0a3069;
}
.markdown-body .pl-v,
.markdown-body .pl-smw {
color: #953800;
}
.markdown-body .pl-bu {
color: #82071e;
}
.markdown-body .pl-ii {
color: #f6f8fa;
background-color: #82071e;
}
.markdown-body .pl-c2 {
color: #f6f8fa;
background-color: #cf222e;
}
.markdown-body .pl-sr .pl-cce {
font-weight: bold;
color: #116329;
}
.markdown-body .pl-ml {
color: #3b2300;
}
.markdown-body .pl-mh,
.markdown-body .pl-mh .pl-en,
.markdown-body .pl-ms {
font-weight: bold;
color: #0550ae;
}
.markdown-body .pl-mi {
font-style: italic;
color: #24292f;
}
.markdown-body .pl-mb {
font-weight: bold;
color: #24292f;
}
.markdown-body .pl-md {
color: #82071e;
background-color: #FFEBE9;
}
.markdown-body .pl-mi1 {
color: #116329;
background-color: #dafbe1;
}
.markdown-body .pl-mc {
color: #953800;
background-color: #ffd8b5;
}
.markdown-body .pl-mi2 {
color: #eaeef2;
background-color: #0550ae;
}
.markdown-body .pl-mdr {
font-weight: bold;
color: #8250df;
}
.markdown-body .pl-ba {
color: #57606a;
}
.markdown-body .pl-sg {
color: #8c959f;
}
.markdown-body .pl-corl {
text-decoration: underline;
color: #0a3069;
}
.markdown-body [data-catalyst] {
display: block;
}
.markdown-body g-emoji {
font-family: "Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
font-size: 1em;
font-style: normal !important;
font-weight: 400;
line-height: 1;
vertical-align: -0.075em;
}
.markdown-body g-emoji img {
width: 1em;
height: 1em;
}
.markdown-body::before {
display: table;
content: "";
}
.markdown-body::after {
display: table;
clear: both;
content: "";
}
.markdown-body>*:first-child {
margin-top: 0 !important;
}
.markdown-body>*:last-child {
margin-bottom: 0 !important;
}
.markdown-body a:not([href]) {
color: inherit;
text-decoration: none;
}
.markdown-body .absent {
color: #cf222e;
}
.markdown-body .anchor {
float: left;
padding-right: 4px;
margin-left: -20px;
line-height: 1;
}
.markdown-body .anchor:focus {
outline: none;
}
.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body pre,
.markdown-body details {
margin-top: 0;
margin-bottom: 16px;
}
.markdown-body blockquote>:first-child {
margin-top: 0;
}
.markdown-body blockquote>:last-child {
margin-bottom: 0;
}
.markdown-body sup>a::before {
content: "[";
}
.markdown-body sup>a::after {
content: "]";
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #24292f;
vertical-align: middle;
visibility: hidden;
}
.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
text-decoration: none;
}
.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
visibility: visible;
}
.markdown-body h1 tt,
.markdown-body h1 code,
.markdown-body h2 tt,
.markdown-body h2 code,
.markdown-body h3 tt,
.markdown-body h3 code,
.markdown-body h4 tt,
.markdown-body h4 code,
.markdown-body h5 tt,
.markdown-body h5 code,
.markdown-body h6 tt,
.markdown-body h6 code {
padding: 0 .2em;
font-size: inherit;
}
.markdown-body ul.no-list,
.markdown-body ol.no-list {
padding: 0;
list-style-type: none;
}
.markdown-body ol[type="1"] {
list-style-type: decimal;
}
.markdown-body ol[type=a] {
list-style-type: lower-alpha;
}
.markdown-body ol[type=i] {
list-style-type: lower-roman;
}
.markdown-body div>ol:not([type]) {
list-style-type: decimal;
}
.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body li>p {
margin-top: 16px;
}
.markdown-body li+li {
margin-top: .25em;
}
.markdown-body dl {
padding: 0;
}
.markdown-body dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: 600;
}
.markdown-body dl dd {
padding: 0 16px;
margin-bottom: 16px;
}
.markdown-body img[align=right] {
padding-left: 20px;
}
.markdown-body img[align=left] {
padding-right: 20px;
}
.markdown-body .emoji {
max-width: none;
vertical-align: text-top;
background-color: transparent;
}
.markdown-body span.frame {
display: block;
overflow: hidden;
}
.markdown-body span.frame>span {
display: block;
float: left;
width: auto;
padding: 7px;
margin: 13px 0 0;
overflow: hidden;
border: 1px solid #d0d7de;
}
.markdown-body span.frame span img {
display: block;
float: left;
}
.markdown-body span.frame span span {
display: block;
padding: 5px 0 0;
clear: both;
color: #24292f;
}
.markdown-body span.align-center {
display: block;
overflow: hidden;
clear: both;
}
.markdown-body span.align-center>span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: center;
}
.markdown-body span.align-center span img {
margin: 0 auto;
text-align: center;
}
.markdown-body span.align-right {
display: block;
overflow: hidden;
clear: both;
}
.markdown-body span.align-right>span {
display: block;
margin: 13px 0 0;
overflow: hidden;
text-align: right;
}
.markdown-body span.align-right span img {
margin: 0;
text-align: right;
}
.markdown-body span.float-left {
display: block;
float: left;
margin-right: 13px;
overflow: hidden;
}
.markdown-body span.float-left span {
margin: 13px 0 0;
}
.markdown-body span.float-right {
display: block;
float: right;
margin-left: 13px;
overflow: hidden;
}
.markdown-body span.float-right>span {
display: block;
margin: 13px auto 0;
overflow: hidden;
text-align: right;
}
.markdown-body code,
.markdown-body tt {
padding: .2em .4em;
margin: 0;
font-size: 85%;
background-color: rgba(175,184,193,0.2);
border-radius: 6px;
}
.markdown-body code br,
.markdown-body tt br {
display: none;
}
.markdown-body del code {
text-decoration: inherit;
}
.markdown-body pre code {
font-size: 100%;
}
.markdown-body pre>code {
padding: 0;
margin: 0;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}
.markdown-body .highlight {
margin-bottom: 16px;
}
.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}
.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f6f8fa;
border-radius: 6px;
}
.markdown-body pre code,
.markdown-body pre tt {
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}
.markdown-body .csv-data td,
.markdown-body .csv-data th {
padding: 5px;
overflow: hidden;
font-size: 12px;
line-height: 1;
text-align: left;
white-space: nowrap;
}
.markdown-body .csv-data .blob-num {
padding: 10px 8px 9px;
text-align: right;
background: #ffffff;
border: 0;
}
.markdown-body .csv-data tr {
border-top: 0;
}
.markdown-body .csv-data th {
font-weight: 600;
background: #f6f8fa;
border-top: 0;
}
.markdown-body .footnotes {
font-size: 12px;
color: #57606a;
border-top: 1px solid #d0d7de;
}
.markdown-body .footnotes ol {
padding-left: 16px;
}
.markdown-body .footnotes li {
position: relative;
}
.markdown-body .footnotes li:target::before {
position: absolute;
top: -8px;
right: -8px;
bottom: -8px;
left: -24px;
pointer-events: none;
content: "";
border: 2px solid #0969da;
border-radius: 6px;
}
.markdown-body .footnotes li:target {
color: #24292f;
}
.markdown-body .footnotes .data-footnote-backref g-emoji {
font-family: monospace;
}
.markdown-body .task-list-item {
list-style-type: none;
}
.markdown-body .task-list-item label {
font-weight: 400;
}
.markdown-body .task-list-item.enabled label {
cursor: pointer;
}
.markdown-body .task-list-item+.task-list-item {
margin-top: 3px;
}
.markdown-body .task-list-item .handle {
display: none;
}
.markdown-body .task-list-item-checkbox {
margin: 0 .2em .25em -1.6em;
vertical-align: middle;
}
.markdown-body .contains-task-list:dir(rtl) .task-list-item-checkbox {
margin: 0 -1.6em .25em .2em;
}
.markdown-body ::-webkit-calendar-picker-indicator {
filter: invert(50%);
}

View File

@@ -0,0 +1,71 @@
@import "./code.css";
button + button {
margin-left: 10px;
}
button {
height: 38px;
line-height: 36px;
padding: 0 18px;
color: #fff;
font-size: 14px;
text-align: center;
white-space: nowrap;
border: 1px solid #eee;
background-color: 0 0;
border-radius: 2px;
cursor: pointer;
background: 0 0;
color: #666;
}
input {
height: 34px;
margin-left: 10px;
line-height: 1.3;
line-height: 38px !important;
border-width: 1px;
border-style: solid;
background-color: #fff;
color: #000000d9;
border-radius: 2px;
border-color: #eee;
display: block;
width: 200px;
padding-left: 10px;
outline: none;
display: inline-block;
}
input + input {
margin-top: 10px;
margin-bottom: 10px;
}
table * {
font-size: 14px;
}
table {
width: 100% !important; /*表格宽度*/
border: 1px solid whitesmoke; /*表格外边框设置*/
border-spacing: 0;
}
table th,
table td {
height: 35px; /*统一每一行的默认高度*/
border: 1px solid whitesmoke; /*内部边框样式*/
padding: 0 10px; /*内边距*/
padding-left: 20px !important;
}
table th {
font-weight: 400;
}
table tr:hover {
background: #efefef;
}
table th {
text-align: left;
white-space: nowrap; /*表头内容强制在一行显示*/
}
table td {
text-align: left;
white-space: nowrap;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,18 @@
<template>
<form>
<input type="text" v-model="data.remark" />
</form>
</template>
<script setup>
const emit = defineEmits("called");
const props = defineProps({
data: Object,
});
</script>
<style scoped>
form {
padding: 10px;
}
</style>

View File

@@ -0,0 +1,23 @@
<template>
<form>
<button type="button" @click="add"></button>
<button type="button" @click="sub"></button>
</form>
</template>
<script setup>
const emit = defineEmits("add", "sub");
const add = () => {
emit("add");
};
const sub = () => {
emit("sub");
};
</script>
<style scoped>
form {
padding: 10px;
}
</style>

View File

@@ -0,0 +1,222 @@
<template>
<div class="lay-code">
<div id="source" class="source">
<slot />
<div v-if="$slots.description" class="description">
<slot name="description" />
</div>
</div>
<div ref="meta" class="meta">
<div class="language-html">
<slot name="code" />
</div>
</div>
<div :class="{ 'is-fixed': isFixContorl }" class="control">
<i class="layui-icon layui-icon-file btn" @click="copy"
><svg
t="1646244236057"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5505"
width="18"
height="18"
>
<path
d="M768 682.666667V170.666667a85.333333 85.333333 0 0 0-85.333333-85.333334H170.666667a85.333333 85.333333 0 0 0-85.333334 85.333334v512a85.333333 85.333333 0 0 0 85.333334 85.333333h512a85.333333 85.333333 0 0 0 85.333333-85.333333zM170.666667 170.666667h512v512H170.666667z m682.666666 85.333333v512a85.333333 85.333333 0 0 1-85.333333 85.333333H256a85.333333 85.333333 0 0 0 85.333333 85.333334h426.666667a170.666667 170.666667 0 0 0 170.666667-170.666667V341.333333a85.333333 85.333333 0 0 0-85.333334-85.333333z"
p-id="5506"
></path></svg
></i>
<i class="layui-icon layui-icon-fonts-code btn" @click="toggle"
><svg
t="1646244296040"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="7127"
width="18"
height="18"
>
<path
d="M217.301333 414.933333a21.333333 21.333333 0 0 1-1.066666-30.165333l29.098666-31.232a21.333333 21.333333 0 0 1 30.165334-1.024l236.117333 220.16 236.16-220.16a21.333333 21.333333 0 0 1 30.122667 1.024l29.098666 31.232a21.333333 21.333333 0 0 1-1.024 30.165333L541.738667 661.333333l-13.44 14.421334a21.290667 21.290667 0 0 1-16.725334 6.741333 21.290667 21.290667 0 0 1-16.64-6.741333l-13.44-14.506667z"
p-id="7128"
></path></svg
></i>
</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 () {
const foundCodes = meta.value.getElementsByClassName("language-html");
const foundCode = foundCodes[0];
let successful = false;
if (navigator.clipboard && document.hasFocus()) {
const text = foundCode.textContent || "";
navigator.clipboard.writeText(text);
successful = true;
} else if (window.getSelection()) {
var range = document.createRange();
let copyDiv;
if (show.value) {
range.selectNode(foundCode);
} else {
copyDiv = document.createElement("div");
copyDiv.innerHTML = foundCode.innerHTML;
copyDiv.style.position = "fixed";
copyDiv.style.left = "-9999px";
document.body.appendChild(copyDiv);
range.selectNode(copyDiv);
}
window.getSelection()?.addRange(range);
try {
successful = document.execCommand("copy");
} catch (err) {
successful = false;
console.error(err);
}
window.getSelection()?.removeAllRanges();
copyDiv?.remove();
}
if (successful) {
} else {
}
};
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;
padding-bottom: 15px;
}
.lay-code .meta {
padding: 0 10px;
height: 0;
background-color: var(--c-page-background);
overflow: hidden;
transition: height 0.2s;
}
.lay-code .source .description {
padding: 20px;
margin: 20px 0;
margin-bottom: 0px;
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 .source .description p {
margin: 0 !important;
line-height: 26px !important;
}
.lay-code .source .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 pre {
margin: 1rem 0.8rem 1rem 0.8rem;
}
.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;
}
.btn:hover::before {
color: #5fb878;
}
</style>

View File

@@ -0,0 +1,113 @@
<template>
<div class="markdown-body light-scheme">
<div class="alone-header">
<img class="alone-logo" src="../assets/logo.png" />
<a
style="
position: absolute;
right: 16%;
line-height: 60px;
color: white;
font-size: 15px;
"
>1.3.10</a
>
<a
href="https://gitee.com/layui-vue/layer-vue"
style="position: absolute; right: 10%; line-height: 75px"
>
<svg width="1.7em" height="1.7em" viewBox="0 0 24 24">
<path
fill="#fff"
d="M10.9,2.1c-4.6,0.5-8.3,4.2-8.8,8.7c-0.5,4.7,2.2,8.9,6.3,10.5C8.7,21.4,9,21.2,9,20.8v-1.6c0,0-0.4,0.1-0.9,0.1 c-1.4,0-2-1.2-2.1-1.9c-0.1-0.4-0.3-0.7-0.6-1C5.1,16.3,5,16.3,5,16.2C5,16,5.3,16,5.4,16c0.6,0,1.1,0.7,1.3,1c0.5,0.8,1.1,1,1.4,1 c0.4,0,0.7-0.1,0.9-0.2c0.1-0.7,0.4-1.4,1-1.8c-2.3-0.5-4-1.8-4-4c0-1.1,0.5-2.2,1.2-3C7.1,8.8,7,8.3,7,7.6C7,7.2,7,6.6,7.3,6 c0,0,1.4,0,2.8,1.3C10.6,7.1,11.3,7,12,7s1.4,0.1,2,0.3C15.3,6,16.8,6,16.8,6C17,6.6,17,7.2,17,7.6c0,0.8-0.1,1.2-0.2,1.4 c0.7,0.8,1.2,1.8,1.2,3c0,2.2-1.7,3.5-4,4c0.6,0.5,1,1.4,1,2.3v2.6c0,0.3,0.3,0.6,0.7,0.5c3.7-1.5,6.3-5.1,6.3-9.3 C22,6.1,16.9,1.4,10.9,2.1z"
></path>
</svg>
</a>
</div>
<div class="alone-banner layui-bg-black">
<div class="layui-main">
<img src="../assets/logo.jpg" />
<h1>layer vue</h1>
<p> </p>
</div>
</div>
<br />
<div class="layui-container" style="width: 80%; margin-left: 10%">
<router-view></router-view>
</div>
</div>
</template>
<style>
body {
margin: 0px;
}
.alone-header {
width: 100%;
height: 60px;
background: #393d49;
border-bottom: 1px solid #404553;
overflow: hidden;
}
.alone-header .alone-logo {
display: inline-block;
width: 82px;
height: 31px;
background: transparent;
margin-top: 16px;
margin-left: 10%;
}
.alone-banner {
height: 250px;
text-align: center;
font-weight: 300;
color: #fff;
background: #393d49;
}
.alone-banner img {
width: 100px;
}
.alone-banner h1 {
margin: 0px !important;
padding: 0px !important;
padding-top: 10px !important;
line-height: 32px !important;
font-size: 30px !important;
font-weight: 300 !important;
color: white !important;
border-bottom: none !important;
letter-spacing: 3px;
}
.alone-banner p {
padding-top: 40px;
color: #e2e2e2;
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
}
.alone-download {
width: 77.5%;
border-radius: 4px;
background: whitesmoke;
margin-left: 10%;
margin-top: 30px;
padding: 20px;
}
.layui-field-title {
margin: 10px 0 20px;
border-width: 1px 0 0;
}
.layui-elem-field {
padding: 0;
margin-top: 10px;
margin-bottom: 10px;
border-top: 1px solid #eee;
border-style: solid;
}
</style>

View File

@@ -0,0 +1,26 @@
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 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);
},
}),
] as any;
export default plugins;

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,
createWebHistory,
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: createWebHistory(baseUrl),
routes: routes,
});
}

View File

@@ -0,0 +1,20 @@
import BaseLayout from "../layouts/Layout.vue";
const zhCN = [
{
path: "/",
redirect: "/zh-CN/index",
component: BaseLayout,
meta: { title: "首页" },
children: [
{
path: "/zh-CN/index",
component: () => import("../../docs/zh-CN/index.md"),
meta: { title: "指南" },
},
],
},
];
export default zhCN;

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,
});