update 组件
parent
2fffc12f5c
commit
423087ff59
@ -0,0 +1,228 @@
|
|||||||
|
<template>
|
||||||
|
<div class="w-code">
|
||||||
|
<w-icon icon-class="clipboard" @click="copy" />
|
||||||
|
<pre><code ref="codeRef" :class="props.language?['language-'+props.language]:[]"><slot></slot></code></pre>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import hljs from 'highlight.js';
|
||||||
|
import 'highlight.js/styles/github.css';
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
language: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const codeRef = ref(null);
|
||||||
|
|
||||||
|
const copy = () => {
|
||||||
|
navigator.clipboard.writeText(codeRef.value.textContent).then(() => {
|
||||||
|
ElMessage.success('复制成功');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
hljs.highlightElement(codeRef.value);
|
||||||
|
})
|
||||||
|
|
||||||
|
const getCode = () => {
|
||||||
|
return codeRef.value.textContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const setCode = (code) => {
|
||||||
|
if(props.language){
|
||||||
|
codeRef.value.innerHTML = hljs.highlight(code, { language: props.language }).value;
|
||||||
|
}else{
|
||||||
|
codeRef.value.innerHTML = hljs.highlightAuto(code).value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
copy,
|
||||||
|
getCode,
|
||||||
|
setCode,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.w-code {
|
||||||
|
|
||||||
|
background-color: #0001;
|
||||||
|
margin: 1em;
|
||||||
|
padding: 0em;
|
||||||
|
border: solid 1px #0002;
|
||||||
|
border-radius: .5em;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&>:first-child {
|
||||||
|
position: absolute;
|
||||||
|
right: .5em;
|
||||||
|
top: .5em;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all .3s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover>:first-child {
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
opacity: .85;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
background: #0000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
pre code.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 1em
|
||||||
|
}
|
||||||
|
|
||||||
|
code.hljs {
|
||||||
|
padding: 3px 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Theme: GitHub Dark
|
||||||
|
Description: Dark theme as seen on github.com
|
||||||
|
Author: github.com
|
||||||
|
Maintainer: @Hirse
|
||||||
|
Updated: 2021-05-15
|
||||||
|
|
||||||
|
Outdated base version: https://github.com/primer/github-syntax-dark
|
||||||
|
Current colors taken from GitHub's CSS
|
||||||
|
*/
|
||||||
|
.hljs {
|
||||||
|
color: #c9d1d9;
|
||||||
|
background: #0d1117
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-meta .hljs-keyword,
|
||||||
|
.hljs-template-tag,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-variable.language_ {
|
||||||
|
/* prettylights-syntax-keyword */
|
||||||
|
color: #ff7b72
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-title.class_,
|
||||||
|
.hljs-title.class_.inherited__,
|
||||||
|
.hljs-title.function_ {
|
||||||
|
/* prettylights-syntax-entity */
|
||||||
|
color: #d2a8ff
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-operator,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-id {
|
||||||
|
/* prettylights-syntax-constant */
|
||||||
|
color: #79c0ff
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-meta .hljs-string {
|
||||||
|
/* prettylights-syntax-string */
|
||||||
|
color: #a5d6ff
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-symbol {
|
||||||
|
/* prettylights-syntax-variable */
|
||||||
|
color: #ffa657
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-code,
|
||||||
|
.hljs-formula {
|
||||||
|
/* prettylights-syntax-comment */
|
||||||
|
color: #8b949e
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-selector-pseudo {
|
||||||
|
/* prettylights-syntax-entity-tag */
|
||||||
|
color: #7ee787
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-subst {
|
||||||
|
/* prettylights-syntax-storage-modifier-import */
|
||||||
|
color: #c9d1d9
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-section {
|
||||||
|
/* prettylights-syntax-markup-heading */
|
||||||
|
color: #1f6feb;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-bullet {
|
||||||
|
/* prettylights-syntax-markup-list */
|
||||||
|
color: #f2cc60
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
/* prettylights-syntax-markup-italic */
|
||||||
|
color: #c9d1d9;
|
||||||
|
font-style: italic
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
/* prettylights-syntax-markup-bold */
|
||||||
|
color: #c9d1d9;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
/* prettylights-syntax-markup-inserted */
|
||||||
|
color: #aff5b4;
|
||||||
|
background-color: #033a16
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
/* prettylights-syntax-markup-deleted */
|
||||||
|
color: #ffdcd7;
|
||||||
|
background-color: #67060c
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-char.escape_,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-params,
|
||||||
|
.hljs-property,
|
||||||
|
.hljs-punctuation,
|
||||||
|
.hljs-tag {
|
||||||
|
/* purposely ignored */
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<svg :class="svgClass" aria-hidden="true">
|
||||||
|
<use :xlink:href="iconName" :fill="color" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
iconClass: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return {
|
||||||
|
iconName: computed(() => `#icon-${props.iconClass}`),
|
||||||
|
svgClass: computed(() => {
|
||||||
|
if (props.className) {
|
||||||
|
return `svg-icon ${props.className}`
|
||||||
|
}
|
||||||
|
return 'svg-icon'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scope lang="scss">
|
||||||
|
.sub-el-icon,
|
||||||
|
.nav-icon {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 15px;
|
||||||
|
margin-right: 12px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
position: relative;
|
||||||
|
fill: currentColor;
|
||||||
|
vertical-align: -2px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<div class="w-tags-input">
|
||||||
|
<el-tag v-for="(tag, index) in model" :key="index" closable :disable-transitions="false" :type="props.type"
|
||||||
|
@close="handleClose(index)">
|
||||||
|
{{ index }} : {{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
<el-input v-if="inputVisible" ref="inputRef" v-model="inputValue" :style="{ width: props.placeholder.length * 2 + 1 + 'em' }"
|
||||||
|
size="small" placeholder="key : value" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" />
|
||||||
|
<el-button v-else class="button-new-tag" size="small" @click="showInput">
|
||||||
|
{{ props.placeholder }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { nextTick, ref } from 'vue'
|
||||||
|
const model = defineModel({
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
/**
|
||||||
|
* 输入提示
|
||||||
|
*/
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: "新增配置项",
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'primary'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const inputValue = ref('')
|
||||||
|
const inputVisible = ref(false);
|
||||||
|
const inputRef = ref(undefined);
|
||||||
|
const handleClose = (index) => {
|
||||||
|
delete model.value[index];
|
||||||
|
};
|
||||||
|
|
||||||
|
const showInput = () => {
|
||||||
|
inputVisible.value = true
|
||||||
|
nextTick(() => {
|
||||||
|
inputRef.value?.input?.focus();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const handleInputConfirm = () => {
|
||||||
|
if (inputValue.value) {
|
||||||
|
if (inputValue.value.indexOf(":")>0) {
|
||||||
|
model.value[inputValue.value.split(':')[0].trim()] = inputValue.value.split(':')[1].trim();
|
||||||
|
} else {
|
||||||
|
ElMessage.error('输入格式错误');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
inputVisible.value = false
|
||||||
|
inputValue.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.w-tags-input {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
&>* {
|
||||||
|
margin: 0 1em 1em 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue