feat: demo Composition API (#2099)

* feat: demo Composition API

* chore: update

* chore: update

* chore: update
This commit is contained in:
0song 2021-05-31 14:31:01 +08:00 committed by GitHub
parent f29b188c84
commit f4c46c9b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 119 additions and 28 deletions

View File

@ -28,9 +28,20 @@
<transition name="text-slide"> <transition name="text-slide">
<span v-show="hovering">{{ controlText }}</span> <span v-show="hovering">{{ controlText }}</span>
</transition> </transition>
<div class="control-button-container control-button-container-left">
<el-button
v-show="isExpanded && hasSetup"
size="small"
type="text"
class="control-button"
@click.stop="onSwitchSyntax"
>
{{ showSetup ? langConfig['switch-button-option-text'] : langConfig['switch-button-setup-text'] }}
</el-button>
</div>
<div class="control-button-container"> <div class="control-button-container">
<el-button <el-button
v-show="hovering || isExpanded" v-show="isExpanded"
ref="copyButton" ref="copyButton"
size="small" size="small"
type="text" type="text"
@ -42,7 +53,7 @@
<el-tooltip effect="dark" :content="langConfig['tooltip-text']" placement="right"> <el-tooltip effect="dark" :content="langConfig['tooltip-text']" placement="right">
<transition name="text-slide"> <transition name="text-slide">
<el-button <el-button
v-show="hovering || isExpanded" v-show="isExpanded"
size="small" size="small"
type="text" type="text"
class="control-button run-online-button" class="control-button run-online-button"
@ -61,15 +72,20 @@ import { nextTick } from 'vue'
import hljs from 'highlight.js' import hljs from 'highlight.js'
import clipboardCopy from 'clipboard-copy' import clipboardCopy from 'clipboard-copy'
import compoLang from '../i18n/component.json' import compoLang from '../i18n/component.json'
import { stripScript, stripStyle, stripTemplate } from '../util' import { stripScript, stripStyle, stripTemplate, stripSetup, removeSetup } from '../util'
const version = '1.0.0' // element version const version = '1.0.0' // element version
const stripTemplateAndRemoveTemplate = code => { const stripTemplateAndRemoveTemplate = code => {
const result = stripTemplate(code) const result = removeSetup(stripTemplate(code))
if (result.indexOf('<template>') === 0) { if (result.indexOf('<template>') === 0) {
return result.replace(/^<template>/, '').replace(/<\/template>$/,'') return result.replace(/^<template>/, '').replace(/<\/template>$/,'')
} }
return result return result
} }
const sanitizeHTML = str => {
const temp = document.createElement('div')
temp.textContent = str
return temp.innerHTML
}
export default { export default {
data() { data() {
return { return {
@ -82,6 +98,8 @@ export default {
isExpanded: false, isExpanded: false,
fixedControl: false, fixedControl: false,
scrollParent: null, scrollParent: null,
showSetup: false,
hasSetup: false,
} }
}, },
@ -110,18 +128,14 @@ export default {
return this.$el.getElementsByClassName('meta')[0] return this.$el.getElementsByClassName('meta')[0]
}, },
codeAreaHeight() { displayDemoCode () {
if (this.$el.getElementsByClassName('description').length > 0) { return this.showSetup ? this.codepen.setup : this.codepen.script
return this.$el.getElementsByClassName('description')[0].clientHeight +
this.$el.getElementsByClassName('highlight')[0].clientHeight + 20
}
return this.$el.getElementsByClassName('highlight')[0].clientHeight
}, },
}, },
watch: { watch: {
isExpanded(val) { isExpanded(val) {
this.codeArea.style.height = val ? `${ this.codeAreaHeight + 1 }px` : '0' this.setCodeAreaHeight()
if (!val) { if (!val) {
this.fixedControl = false this.fixedControl = false
this.$refs.control.style.left = '0' this.$refs.control.style.left = '0'
@ -151,31 +165,62 @@ export default {
this.codepen.html = stripTemplateAndRemoveTemplate(code) this.codepen.html = stripTemplateAndRemoveTemplate(code)
this.codepen.script = stripScript(code) this.codepen.script = stripScript(code)
this.codepen.style = stripStyle(code) this.codepen.style = stripStyle(code)
this.codepen.setup = stripSetup(code)
if (this.codepen.setup) {
this.hasSetup = true
}
} }
} }
}, },
mounted() {
nextTick(() => {
let highlight = this.$el.getElementsByClassName('highlight')[0]
if (this.$el.getElementsByClassName('description').length === 0) {
highlight.style.width = '100%'
highlight.borderRight = 'none'
}
try {
hljs.highlightBlock(highlight.querySelector('code'))
} catch (error) {
console.log(error)
}
})
},
beforeUnmount() { beforeUnmount() {
this.removeScrollHandler() this.removeScrollHandler()
}, },
mounted () {
this.prettyCode()
},
methods: { methods: {
getCodeAreaHeight() {
if (this.$el.getElementsByClassName('description').length > 0) {
return this.$el.getElementsByClassName('description')[0].clientHeight +
this.$el.getElementsByClassName('highlight')[0].clientHeight + 20
}
return this.$el.getElementsByClassName('highlight')[0].clientHeight
},
setCodeAreaHeight () {
this.codeArea.style.height = this.isExpanded ? `${ this.getCodeAreaHeight() + 1 }px` : '0'
},
prettyCode () {
nextTick(() => {
const highlight = this.$el.querySelector('.highlight')
const hlcode = highlight.querySelector('pre code')
hlcode.innerHTML = sanitizeHTML(`<template>${this.codepen.html}</template>
<script>
${this.displayDemoCode}
${'</sc' + 'ript>'}
`)
nextTick(() => {
if (this.$el.getElementsByClassName('description').length === 0) {
highlight.style.width = '100%'
highlight.borderRight = 'none'
}
try {
hljs.highlightBlock(hlcode)
} catch (error) {
console.log(error)
}
})
})
},
onSwitchSyntax () {
this.showSetup = !this.showSetup
this.prettyCode()
this.$nextTick(this.setCodeAreaHeight)
},
copy() { copy() {
const res = clipboardCopy(` const res = clipboardCopy(`
<template> <template>
@ -387,6 +432,12 @@ ${this.codepen.style}
padding-right: 25px; padding-right: 25px;
} }
.control-button-container-left {
left: 0;
width: 100px;
padding-left: 14px; // 14 + 10 = 24px .hljs code padding left 24
}
.control-button { .control-button {
font-size: 14px; font-size: 14px;
margin: 0 10px; margin: 0 10px;

View File

@ -23,6 +23,18 @@
} }
} }
</script> </script>
<!--
<setup>
import { ref } from 'vue'
export default {
setup() {
const radio = ref('1');
return { radio }
}
}
</setup>
-->
``` ```
::: :::

View File

@ -5,6 +5,8 @@
"hide-text": "隐藏代码", "hide-text": "隐藏代码",
"show-text": "显示代码", "show-text": "显示代码",
"copy-button-text": "复制代码片段", "copy-button-text": "复制代码片段",
"switch-button-option-text": "切换成 Options API",
"switch-button-setup-text": "切换成 Composition API",
"copy-success": "已复制!", "copy-success": "已复制!",
"copy-error": "该浏览器不支持自动复制!", "copy-error": "该浏览器不支持自动复制!",
"run-online-button-text": "在线运行", "run-online-button-text": "在线运行",
@ -39,6 +41,8 @@
"hide-text": "Hide", "hide-text": "Hide",
"show-text": "Expand", "show-text": "Expand",
"copy-button-text": "Copy", "copy-button-text": "Copy",
"switch-button-option-text": "Switch to Options API",
"switch-button-setup-text": "Switch to Composition API",
"copy-success": "Copied", "copy-success": "Copied",
"copy-error": "This browser does not support automatic copy", "copy-error": "This browser does not support automatic copy",
"run-online-button-text": "Try it!", "run-online-button-text": "Try it!",
@ -73,6 +77,8 @@
"hide-text": "Ocultar", "hide-text": "Ocultar",
"show-text": "Mostrar", "show-text": "Mostrar",
"copy-button-text": "Copiar", "copy-button-text": "Copiar",
"switch-button-option-text": "Cambiar a Options API",
"switch-button-setup-text": "Cambiar a Composition API",
"copy-success": "Copiar correctamente!", "copy-success": "Copiar correctamente!",
"copy-error": "Este navegador no admite copia automática!", "copy-error": "Este navegador no admite copia automática!",
"run-online-button-text": "Probar", "run-online-button-text": "Probar",
@ -107,6 +113,8 @@
"hide-text": "Réduire", "hide-text": "Réduire",
"show-text": "Agrandir", "show-text": "Agrandir",
"copy-button-text": "Copie", "copy-button-text": "Copie",
"switch-button-option-text": "Passer au Options API",
"switch-button-setup-text": "Passer au Composition API",
"copy-success": "Copier avec succès!", "copy-success": "Copier avec succès!",
"copy-error": "Ce navigateur ne prend pas en charge la copie automatique!", "copy-error": "Ce navigateur ne prend pas en charge la copie automatique!",
"run-online-button-text": "Essayez!", "run-online-button-text": "Essayez!",
@ -141,6 +149,8 @@
"hide-text": "隠す", "hide-text": "隠す",
"show-text": "展開する", "show-text": "展開する",
"copy-button-text": "コピー", "copy-button-text": "コピー",
"switch-button-option-text": "Options API に切り替える",
"switch-button-setup-text": "Composition API に切り替える",
"copy-success": "正常にコピー!", "copy-success": "正常にコピー!",
"copy-error": "このブラウザは自動コピーをサポートしていません!", "copy-error": "このブラウザは自動コピーをサポートしていません!",
"run-online-button-text": "試してみる!", "run-online-button-text": "試してみる!",

View File

@ -13,5 +13,23 @@ export function stripTemplate(content) {
if (!content) { if (!content) {
return content return content
} }
return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim() return content
.replace(/<(script|style)[\s\S]+<\/\1>/g, '')
.trim()
}
const setupCommentGlobalRegx = /<!--[\r?\n|\r]?(<setup>[\s\S]+)-->/g
export function removeSetup (content) {
return content
.replace(setupCommentGlobalRegx, '')
.trim()
}
const setupCommentRegx = /<!--[\r?\n|\r]?(<setup>[\s\S]+)-->/
export function stripSetup(content) {
const result = content.match(setupCommentRegx)
const comment = result && result[1] ? result[1].trim() : ''
if (!comment) return comment
const result2 = comment.match(/<(setup)>([\s\S]+)<\/\1>/)
return result2 && result2[2] ? result2[2].trim() : ''
} }