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">
<span v-show="hovering">{{ controlText }}</span>
</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">
<el-button
v-show="hovering || isExpanded"
v-show="isExpanded"
ref="copyButton"
size="small"
type="text"
@ -42,7 +53,7 @@
<el-tooltip effect="dark" :content="langConfig['tooltip-text']" placement="right">
<transition name="text-slide">
<el-button
v-show="hovering || isExpanded"
v-show="isExpanded"
size="small"
type="text"
class="control-button run-online-button"
@ -61,15 +72,20 @@ import { nextTick } from 'vue'
import hljs from 'highlight.js'
import clipboardCopy from 'clipboard-copy'
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 stripTemplateAndRemoveTemplate = code => {
const result = stripTemplate(code)
const result = removeSetup(stripTemplate(code))
if (result.indexOf('<template>') === 0) {
return result.replace(/^<template>/, '').replace(/<\/template>$/,'')
}
return result
}
const sanitizeHTML = str => {
const temp = document.createElement('div')
temp.textContent = str
return temp.innerHTML
}
export default {
data() {
return {
@ -82,6 +98,8 @@ export default {
isExpanded: false,
fixedControl: false,
scrollParent: null,
showSetup: false,
hasSetup: false,
}
},
@ -110,18 +128,14 @@ export default {
return this.$el.getElementsByClassName('meta')[0]
},
codeAreaHeight() {
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
displayDemoCode () {
return this.showSetup ? this.codepen.setup : this.codepen.script
},
},
watch: {
isExpanded(val) {
this.codeArea.style.height = val ? `${ this.codeAreaHeight + 1 }px` : '0'
this.setCodeAreaHeight()
if (!val) {
this.fixedControl = false
this.$refs.control.style.left = '0'
@ -151,31 +165,62 @@ export default {
this.codepen.html = stripTemplateAndRemoveTemplate(code)
this.codepen.script = stripScript(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() {
this.removeScrollHandler()
},
mounted () {
this.prettyCode()
},
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() {
const res = clipboardCopy(`
<template>
@ -387,6 +432,12 @@ ${this.codepen.style}
padding-right: 25px;
}
.control-button-container-left {
left: 0;
width: 100px;
padding-left: 14px; // 14 + 10 = 24px .hljs code padding left 24
}
.control-button {
font-size: 14px;
margin: 0 10px;

View File

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

View File

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

View File

@ -13,5 +13,23 @@ export function stripTemplate(content) {
if (!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() : ''
}