feat: <Isolate />
This commit is contained in:
27
src/pages/Page/API.page.vue
Normal file
27
src/pages/Page/API.page.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
const baseURL = '/fake-api';
|
||||
|
||||
let fakeApiResult = $ref<null | Record<string, unknown>>(null);
|
||||
|
||||
onMounted(() => {
|
||||
fetch(`${baseURL}/mock/get-user-info`)
|
||||
.then((response) => response.json())
|
||||
.then((json) => (fakeApiResult = json));
|
||||
});
|
||||
|
||||
/* fetch('https://jsonplaceholder.typicode.com/posts/1')
|
||||
.then((response) => response.json())
|
||||
.then((json) => console.log(json)); */
|
||||
// let npmRegistryApiResult = $ref<Record<string, any> | null>(null);
|
||||
|
||||
// fetch('/npm-registry-api/@vue%2Fbabel-plugin-jsx')
|
||||
// .then((response) => response.json())
|
||||
// .then((json) => npmRegistryApiResult = json);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<pre>{{ JSON.stringify(fakeApiResult, null, 2) }}</pre>
|
||||
<!-- <div>{{ npmRegistryApiResult?.['_id'] }}</div> -->
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
32
src/pages/Page/Icons.page.vue
Normal file
32
src/pages/Page/Icons.page.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
// https://icon-sets.iconify.design
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SomeIcon from '~icons/svg/pacman';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div b="1px solid pink" mt-2 text-4 p-2 space-y-2>
|
||||
<!-- <div b="1px solid pink">
|
||||
<div>@iconify-json/carbon/icons.json</div>
|
||||
<div i-carbon-face-cool text-orange />
|
||||
</div> -->
|
||||
|
||||
<div b="1px solid pink">
|
||||
<div>Icons({ autoInstall: true })</div>
|
||||
<icon-carbon-face-cool class="text-yellow" w-8 h-8 />
|
||||
</div>
|
||||
|
||||
<!-- <div b="1px solid pink">
|
||||
<div>pacman.svg</div>
|
||||
<div class="icon:pacman text-(pink)" />
|
||||
</div> -->
|
||||
|
||||
<div b="1px solid pink">
|
||||
<div>pacman.svg</div>
|
||||
<icon-svg:pacman text-blue w-12 h-12 />
|
||||
<some-icon text-cyan w-12 h-12 />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
81
src/pages/Page/Style/StyleLayer.vue
Normal file
81
src/pages/Page/Style/StyleLayer.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div b="1px solid #ccc" p-4 mt-4>
|
||||
<div class="layer-demo">这是一个测试@layer的元素</div>
|
||||
<div class="layer-nested">这是测试嵌套layer的元素</div>
|
||||
|
||||
<div class="layer-explanation">
|
||||
<h3>@layer 优先级规则:</h3>
|
||||
<ol>
|
||||
<li>后定义的layer比先定义的layer优先级高</li>
|
||||
<li>在同一个layer中遵循正常的CSS优先级规则</li>
|
||||
<li>没有在任何layer中的样式优先级高于所有layer</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="css">
|
||||
/* 测试 @layer */
|
||||
|
||||
/* 声明layer的顺序决定了优先级 - 越后声明的优先级越高 */
|
||||
@layer base, components, utilities;
|
||||
|
||||
/* base layer 包含基础样式 */
|
||||
@layer base {
|
||||
.layer-demo {
|
||||
color: blue;
|
||||
font-size: 18px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.layer-nested {
|
||||
color: blue;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* components layer 包含组件样式 */
|
||||
@layer components {
|
||||
.layer-demo {
|
||||
color: red; /* 这个会覆盖base中的blue,因为components在base之后声明 */
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
/* utilities layer 包含工具类样式 */
|
||||
@layer utilities {
|
||||
.layer-demo {
|
||||
font-weight: bold;
|
||||
color: green; /* 这个会覆盖components中的red,因为utilities优先级更高 */
|
||||
}
|
||||
}
|
||||
|
||||
/* 嵌套layer的示例 */
|
||||
@layer components {
|
||||
@layer special {
|
||||
.layer-nested {
|
||||
color: purple;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
/* components.base 比 components.special 优先级低 */
|
||||
@layer base {
|
||||
.layer-nested {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 不在任何layer中的样式优先级最高 */
|
||||
.layer-explanation {
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
background-color: #f8f8f8;
|
||||
border-left: 4px solid #42b983;
|
||||
}
|
||||
</style>
|
13
src/pages/Page/Style/css-modules.vue
Normal file
13
src/pages/Page/Style/css-modules.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div :class="$style.hero" mt-2>
|
||||
<div>CSS Modules:</div>
|
||||
<div>https://cn.vuejs.org/api/sfc-css-features#css-modules</div>
|
||||
<pre>{{ JSON.stringify({ $style }, null, 2) }}</pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
.hero {
|
||||
border: 1px solid #42b983;
|
||||
}
|
||||
</style>
|
11
src/pages/Page/Style/index.page.vue
Normal file
11
src/pages/Page/Style/index.page.vue
Normal file
@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import CSSModules from './css-modules.vue';
|
||||
import Isolate from './isolate.vue';
|
||||
import StyleLayer from './StyleLayer.vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CSSModules />
|
||||
<StyleLayer />
|
||||
<Isolate />
|
||||
</template>
|
73
src/pages/Page/Style/isolate.vue
Normal file
73
src/pages/Page/Style/isolate.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<script setup lang="ts">
|
||||
const description =
|
||||
'CSS isolation: isolate 用于创建独立的层叠上下文,使元素内部的 z-index 值只在内部比较,不会影响外部元素的堆叠顺序';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-8 space-y-8" b="1px solid #e5e7eb" mt-4>
|
||||
<h1 class="text-2xl font-bold">CSS Isolation 演示</h1>
|
||||
<p class="mb-6">{{ description }}</p>
|
||||
|
||||
<!-- 实际应用场景示例 -->
|
||||
<div class="mt-10 border rounded p-4 bg-gray-50">
|
||||
<h2 class="text-lg font-semibold mb-4">实际应用:模态框和下拉菜单</h2>
|
||||
|
||||
<div class="grid grid-cols-2 gap-8">
|
||||
<!-- 左侧:问题演示 -->
|
||||
<div>
|
||||
<h3 class="font-medium mb-2">没有使用 isolate 的问题</h3>
|
||||
<div class="relative h-60 border border-dashed border-gray-300 bg-gray-100">
|
||||
<!-- 网站内容 -->
|
||||
<div class="p-2">
|
||||
<div class="bg-white p-2 mb-2">网站内容</div>
|
||||
|
||||
<!-- 假设这是导航栏的下拉菜单 -->
|
||||
<div class="relative">
|
||||
<button class="bg-blue-500 text-white px-2 py-1 rounded">导航 ▼</button>
|
||||
<div class="absolute mt-1 bg-white shadow rounded p-2 border border-gray-200 z-50">下拉菜单 (z-50)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 假设这是模态框 -->
|
||||
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center z-40">
|
||||
<div class="bg-white p-4 rounded shadow-lg w-36">
|
||||
模态框 (z-40)<br />
|
||||
<span class="text-red-500 text-xs">被下拉菜单覆盖了!</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:解决方案 -->
|
||||
<div>
|
||||
<h3 class="font-medium mb-2">使用 isolate 解决问题</h3>
|
||||
<div class="relative h-60 border border-dashed border-gray-300 bg-gray-100">
|
||||
<!-- 网站内容 -->
|
||||
<div class="p-2">
|
||||
<div class="bg-white p-2 mb-2">网站内容</div>
|
||||
|
||||
<!-- 使用 isolate 的下拉菜单 -->
|
||||
<div class="relative isolate">
|
||||
<button class="bg-blue-500 text-white px-2 py-1 rounded">导航 ▼</button>
|
||||
<div class="absolute mt-1 bg-white shadow rounded p-2 border border-gray-200 z-50">下拉菜单 (z-50)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模态框 -->
|
||||
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center z-40">
|
||||
<div class="bg-white p-4 rounded shadow-lg w-36">
|
||||
模态框 (z-40)<br />
|
||||
<span class="text-green-500 text-xs">正确显示在顶层!</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mt-4 text-sm">
|
||||
使用 isolate 后,导航菜单的 z-index 只在其容器内部起作用,
|
||||
不再与页面上的模态框比较。这样模态框可以正确显示在最上层, 而不需要使用极大的 z-index 值。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
33
src/pages/Page/fonts.page.vue
Normal file
33
src/pages/Page/fonts.page.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<ul>
|
||||
<li>https://juejin.cn/post/7118700280136335396</li>
|
||||
<li>https://juejin.cn/post/7106556068007772174</li>
|
||||
<li>cn-font-split</li>
|
||||
</ul>
|
||||
|
||||
<p class="mt-2" b="1px solid pink">
|
||||
unocss-preset-chinese 中文<span class="chinese">排版</span
|
||||
><br />https://unocss-preset-chinese-playground.vercel.app/
|
||||
</p>
|
||||
|
||||
<div mt-2 b="1px solid pink">
|
||||
<h1><i>🔌</i> Vite Plugin Webfont DL <i>⚡</i></h1>
|
||||
<h2>Fonts are downloaded directly from Google Fonts</h2>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
h1 {
|
||||
font-family: 'Press Start 2P', cursive;
|
||||
color: #646cff;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: 'Fira Code', monospace;
|
||||
background-color: #42b983;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user