feat: use live editor on desktop
This commit is contained in:
parent
54393e41bc
commit
6fd9a5a4f4
26
common/transform.js
Normal file
26
common/transform.js
Normal file
@ -0,0 +1,26 @@
|
||||
import less from 'less/dist/less'
|
||||
|
||||
const lessRE = /<style([^>]* lang="less")?[^>]*>([\s\S]*?)<\/style>/gi
|
||||
|
||||
export function transformLessCode (sfcCode) {
|
||||
return sfcCode.replace(lessRE, (_, p1, p2) => {
|
||||
const lessCode = p2.trim()
|
||||
const cssCode = render(lessCode)
|
||||
return `<style${p1}>${cssCode}</style>`
|
||||
})
|
||||
}
|
||||
|
||||
function render (code) {
|
||||
let css = null
|
||||
|
||||
less.render(code, {
|
||||
syncImport: true
|
||||
}, (err, output) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
css = output.css
|
||||
})
|
||||
|
||||
return css
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<article
|
||||
class="one-demo"
|
||||
:class="{ expanded: localExpanded }"
|
||||
:class="{ expanded }"
|
||||
>
|
||||
<section class="demo">
|
||||
<browser-window
|
||||
@ -26,27 +26,35 @@
|
||||
ui="icon"
|
||||
@click="play('CodeSandbox')"
|
||||
>
|
||||
<veui-icon
|
||||
name="one-demo-codesandbox"
|
||||
/>
|
||||
<veui-icon name="one-demo-codesandbox"/>
|
||||
</veui-button>
|
||||
<veui-button
|
||||
v-tooltip="t('playInStackBlitz')"
|
||||
ui="icon"
|
||||
@click="play('StackBlitz')"
|
||||
>
|
||||
<veui-icon
|
||||
name="one-demo-stackblitz"
|
||||
/>
|
||||
<veui-icon name="one-demo-stackblitz"/>
|
||||
</veui-button>
|
||||
<veui-button
|
||||
v-tooltip="t(localExpanded ? 'hideCode' : 'showCode')"
|
||||
v-tooltip="t('expandEditor')"
|
||||
class="toggle-editor"
|
||||
ui="icon"
|
||||
@click="localExpanded = !localExpanded"
|
||||
@click="editing = true"
|
||||
>
|
||||
<veui-icon
|
||||
scale="1.2"
|
||||
:name="localExpanded ? 'one-demo-code-off' : 'one-demo-code'"
|
||||
:name="expanded ? 'one-demo-code-off' : 'one-demo-code'"
|
||||
/>
|
||||
</veui-button>
|
||||
<veui-button
|
||||
v-tooltip="t(expanded ? 'hideCode' : 'showCode')"
|
||||
class="toggle-source"
|
||||
ui="icon"
|
||||
@click="expanded = !expanded"
|
||||
>
|
||||
<veui-icon
|
||||
scale="1.2"
|
||||
:name="expanded ? 'one-demo-code-off' : 'one-demo-code'"
|
||||
/>
|
||||
</veui-button>
|
||||
<one-edit-link
|
||||
@ -59,16 +67,25 @@
|
||||
v-if="$slots.source"
|
||||
ref="source"
|
||||
class="source"
|
||||
:style="{ height: localExpanded ? `${sourceHeight || 0}px` : '0' }"
|
||||
:style="{ height: expanded ? `${sourceHeight || 0}px` : '0' }"
|
||||
>
|
||||
<slot name="source"/>
|
||||
</section>
|
||||
<transition name="editor">
|
||||
<one-repl
|
||||
v-if="editing"
|
||||
class="one-demo-editor"
|
||||
:code="code"
|
||||
@close="editing = false"
|
||||
/>
|
||||
</transition>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Button, Icon } from 'veui'
|
||||
import tooltip from 'veui/directives/tooltip'
|
||||
import modal from 'veui/managers/modal'
|
||||
import i18n from 'veui/mixins/i18n'
|
||||
import { BrowserWindow } from 'vue-windows'
|
||||
import { getLocale } from '../common/i18n'
|
||||
@ -84,26 +101,29 @@ export default {
|
||||
'veui-button': Button,
|
||||
'veui-icon': Icon,
|
||||
BrowserWindow,
|
||||
OneEditLink
|
||||
OneEditLink,
|
||||
OneRepl: () => import('./OneRepl')
|
||||
},
|
||||
mixins: [i18n],
|
||||
props: {
|
||||
expanded: Boolean,
|
||||
browser: String,
|
||||
path: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
code: '',
|
||||
sourceHeight: 0,
|
||||
localExpanded: this.expanded
|
||||
expanded: false,
|
||||
editing: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
expanded (val) {
|
||||
this.localExpanded = val
|
||||
},
|
||||
localExpanded (val) {
|
||||
this.$emit('update:expanded', val)
|
||||
editing (value) {
|
||||
if (value) {
|
||||
modal.open()
|
||||
} else {
|
||||
modal.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
@ -113,6 +133,8 @@ export default {
|
||||
style.height = source.offsetHeight
|
||||
this.sourceHeight = source.offsetHeight
|
||||
style.height = '0'
|
||||
|
||||
this.code = this.$refs.source?.textContent
|
||||
},
|
||||
methods: {
|
||||
play (vendor) {
|
||||
@ -126,22 +148,26 @@ Icon.register({
|
||||
'one-demo-code': {
|
||||
width: 24,
|
||||
height: 24,
|
||||
d: 'M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6l6 6l1.4-1.4zm5.2 0l4.6-4.6l-4.6-4.6L16 6l6 6l-6 6l-1.4-1.4z'
|
||||
d:
|
||||
'M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6l6 6l1.4-1.4zm5.2 0l4.6-4.6l-4.6-4.6L16 6l6 6l-6 6l-1.4-1.4z'
|
||||
},
|
||||
'one-demo-code-off': {
|
||||
width: 24,
|
||||
height: 24,
|
||||
d: 'M19.17 12l-4.58-4.59L16 6l6 6l-3.59 3.59L17 14.17L19.17 12zM1.39 4.22l4.19 4.19L2 12l6 6l1.41-1.41L4.83 12L7 9.83l12.78 12.78l1.41-1.41L2.81 2.81L1.39 4.22z'
|
||||
d:
|
||||
'M19.17 12l-4.58-4.59L16 6l6 6l-3.59 3.59L17 14.17L19.17 12zM1.39 4.22l4.19 4.19L2 12l6 6l1.41-1.41L4.83 12L7 9.83l12.78 12.78l1.41-1.41L2.81 2.81L1.39 4.22z'
|
||||
},
|
||||
'one-demo-codesandbox': {
|
||||
width: 32,
|
||||
height: 32,
|
||||
d: 'M2.667 8l13.938-8l13.943 8l.12 15.932L16.605 32L2.667 24zm2.786 3.307v6.344l4.458 2.479v4.688l5.297 3.063V16.85zm22.318 0l-9.755 5.542V27.88l5.292-3.063v-4.682l4.464-2.484zM6.844 8.802l9.74 5.526l9.76-5.573l-5.161-2.932l-4.547 2.594l-4.573-2.625z'
|
||||
d:
|
||||
'M2.667 8l13.938-8l13.943 8l.12 15.932L16.605 32L2.667 24zm2.786 3.307v6.344l4.458 2.479v4.688l5.297 3.063V16.85zm22.318 0l-9.755 5.542V27.88l5.292-3.063v-4.682l4.464-2.484zM6.844 8.802l9.74 5.526l9.76-5.573l-5.161-2.932l-4.547 2.594l-4.573-2.625z'
|
||||
},
|
||||
'one-demo-stackblitz': {
|
||||
width: 28,
|
||||
height: 28,
|
||||
d: 'M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z'
|
||||
d:
|
||||
'M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -208,4 +234,33 @@ Icon.register({
|
||||
top 50%
|
||||
transform translateY(-50%)
|
||||
font-size 12px
|
||||
|
||||
.one-demo-editor
|
||||
position fixed
|
||||
top 0
|
||||
left 0
|
||||
right 0
|
||||
bottom 0
|
||||
z-index 10
|
||||
background-color #fff
|
||||
|
||||
.editor-enter-active
|
||||
.editor-leave-active
|
||||
transform-origin 50% 50%
|
||||
transition all 0.3s
|
||||
|
||||
.editor-enter
|
||||
.editor-leave-to
|
||||
opacity 0
|
||||
transform scale(0.99) translateY(3px)
|
||||
|
||||
.toggle-source
|
||||
display none
|
||||
|
||||
@media (max-width 480px)
|
||||
.toggle-source
|
||||
display inline-block
|
||||
|
||||
.toggle-editor
|
||||
display none
|
||||
</style>
|
||||
|
262
components/OneLive.vue
Normal file
262
components/OneLive.vue
Normal file
@ -0,0 +1,262 @@
|
||||
<template>
|
||||
<v-splitpanes class="one-live">
|
||||
<v-pane
|
||||
min-size="30"
|
||||
class="live-editor"
|
||||
>
|
||||
<v-live-editor
|
||||
:code="localCode"
|
||||
line-numbers
|
||||
@change="handleChange"
|
||||
/>
|
||||
<div class="editor-toolbar">
|
||||
<veui-button
|
||||
v-tooltip="t('@onedemo.playInCodeSandbox')"
|
||||
ui="s translucent square"
|
||||
@click="play('CodeSandbox')"
|
||||
>
|
||||
<veui-icon name="one-demo-codesandbox"/>
|
||||
</veui-button>
|
||||
<veui-button
|
||||
v-tooltip="t('@onedemo.playInStackBlitz')"
|
||||
ui="s translucent square"
|
||||
@click="play('StackBlitz')"
|
||||
>
|
||||
<veui-icon name="one-demo-stackblitz"/>
|
||||
</veui-button>
|
||||
<veui-button
|
||||
v-tooltip="t('reset')"
|
||||
ui="s translucent square"
|
||||
@click="reset"
|
||||
>
|
||||
<veui-icon name="anticlockwise"/>
|
||||
</veui-button>
|
||||
<veui-button
|
||||
v-tooltip="t('copyCode')"
|
||||
ui="s translucent square"
|
||||
@click="copy"
|
||||
>
|
||||
<veui-icon name="copy"/>
|
||||
</veui-button>
|
||||
<div class="editor-live-badge">
|
||||
<span>Live</span>
|
||||
</div>
|
||||
</div>
|
||||
</v-pane>
|
||||
<v-pane
|
||||
min-size="40"
|
||||
class="live-preview"
|
||||
>
|
||||
<v-live-preview
|
||||
:code="transformedCode"
|
||||
:requires="imports"
|
||||
:check-variable-availability="false"
|
||||
@success="dismissError"
|
||||
@error="handleError"
|
||||
/>
|
||||
<transition name="editor-error">
|
||||
<veui-alert
|
||||
v-if="error"
|
||||
v-tooltip="t('dismiss')"
|
||||
ui="s"
|
||||
type="error"
|
||||
class="editor-error"
|
||||
@click.native="dismissError"
|
||||
>
|
||||
<code>{{ errorMessage }}</code>
|
||||
</veui-alert>
|
||||
</transition>
|
||||
</v-pane>
|
||||
</v-splitpanes>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { VueLiveEditor, VueLivePreview } from 'vue-live'
|
||||
import 'vue-live/lib/vue-live.esm.css'
|
||||
import 'prism-theme-night-owl/build/no-italics.css'
|
||||
import { Button, Icon, Alert } from 'veui'
|
||||
import * as veui from 'veui'
|
||||
import lodash from 'lodash'
|
||||
import 'veui-theme-dls-icons'
|
||||
import tooltip from 'veui/directives/tooltip'
|
||||
import i18n from 'veui/mixins/i18n'
|
||||
import toast from 'veui/plugins/toast'
|
||||
import 'veui-theme-dls-icons/copy'
|
||||
import 'veui-theme-dls-icons/anticlockwise'
|
||||
import { Splitpanes, Pane } from 'splitpanes'
|
||||
import 'splitpanes/dist/splitpanes.css'
|
||||
import { getLocale } from '../common/i18n'
|
||||
import { play } from '../common/play'
|
||||
import { transformLessCode } from '../common/transform'
|
||||
|
||||
Vue.use(toast)
|
||||
|
||||
export default {
|
||||
name: 'one-live',
|
||||
components: {
|
||||
'veui-button': Button,
|
||||
'veui-icon': Icon,
|
||||
'veui-alert': Alert,
|
||||
'v-splitpanes': Splitpanes,
|
||||
'v-pane': Pane,
|
||||
'v-live-editor': VueLiveEditor,
|
||||
'v-live-preview': VueLivePreview
|
||||
},
|
||||
directives: {
|
||||
tooltip
|
||||
},
|
||||
mixins: [i18n],
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
code: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
localCode: this.code,
|
||||
transformedCode: '',
|
||||
error: null,
|
||||
imports: {
|
||||
veui,
|
||||
lodash,
|
||||
'veui-theme-dls-icons': {}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
errorMessage () {
|
||||
const { error } = this
|
||||
|
||||
if (!error) {
|
||||
return null
|
||||
}
|
||||
|
||||
return error.name ? `${error.name}: ${error.message}` : error.message
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
localCode: {
|
||||
immediate: true,
|
||||
handler (code) {
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
this.transformedCode = transformLessCode(code)
|
||||
} catch (e) {
|
||||
this.error = e
|
||||
return
|
||||
}
|
||||
this.error = null
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
play (vendor) {
|
||||
let locale = getLocale(this.$route.path)
|
||||
play(this.code, { locale, vendor })
|
||||
},
|
||||
async copy () {
|
||||
try {
|
||||
await navigator.clipboard.writeText(this.code)
|
||||
this.$toast.success(this.t('copySuccess'))
|
||||
} catch (e) {
|
||||
this.$toast.error(this.t('copyFailed'))
|
||||
}
|
||||
},
|
||||
reset () {
|
||||
this.localCode = this.code
|
||||
},
|
||||
handleChange (code) {
|
||||
this.localCode = code
|
||||
},
|
||||
handleError (error) {
|
||||
this.error = error
|
||||
},
|
||||
dismissError () {
|
||||
this.error = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.one-live
|
||||
& >>> .splitpanes__pane
|
||||
position relative
|
||||
|
||||
& >>> .splitpanes__splitter
|
||||
width 6px
|
||||
background #eee
|
||||
transition all 0.3s
|
||||
|
||||
&:hover
|
||||
background #ccc
|
||||
transform scaleX(2)
|
||||
|
||||
.editor-toolbar
|
||||
position absolute
|
||||
top 12px
|
||||
right 20px
|
||||
display flex
|
||||
align-items center
|
||||
|
||||
.editor-live-badge
|
||||
display flex
|
||||
align-items center
|
||||
position relative
|
||||
margin-left 8px
|
||||
padding 0 4px 0 20px
|
||||
border-radius 2px
|
||||
font-size 12px
|
||||
background-color #00bf5c
|
||||
color #fff
|
||||
height 18px
|
||||
|
||||
span
|
||||
position relative
|
||||
top -1px
|
||||
|
||||
&::before
|
||||
content ""
|
||||
position absolute
|
||||
left 7px
|
||||
top 6px
|
||||
width 6px
|
||||
height 6px
|
||||
border-radius 50%
|
||||
background-color #fff
|
||||
box-shadow 0 0 0 0 rgba(255, 255, 255, 1)
|
||||
animation pulse 2s infinite
|
||||
|
||||
.editor-error
|
||||
position absolute
|
||||
bottom 16px
|
||||
right 16px
|
||||
left 16px
|
||||
cursor pointer
|
||||
transition all 0.3s
|
||||
|
||||
&:hover
|
||||
opacity 0.8
|
||||
|
||||
.editor-error-enter
|
||||
.editor-error-leave-to
|
||||
opacity 0
|
||||
transform translateY(10px)
|
||||
|
||||
@keyframes pulse
|
||||
0%
|
||||
transform scale(0.95)
|
||||
box-shadow 0 0 0 0 rgba(255, 255, 255, 0.9)
|
||||
|
||||
70%
|
||||
transform scale(1)
|
||||
box-shadow 0 0 0 12px rgba(255, 255, 255, 0)
|
||||
|
||||
100%
|
||||
transform scale(0.95)
|
||||
box-shadow 0 0 0 0 rgba(255, 255, 255, 0)
|
||||
</style>
|
104
components/OneRepl.vue
Normal file
104
components/OneRepl.vue
Normal file
@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<article class="repl">
|
||||
<header class="header">
|
||||
<h1>{{ t('liveEdit') }}</h1>
|
||||
<section class="actions">
|
||||
<veui-button
|
||||
ui="strong text"
|
||||
@click="handleClose"
|
||||
>
|
||||
{{ t('exit') }}
|
||||
</veui-button>
|
||||
</section>
|
||||
</header>
|
||||
<one-live
|
||||
class="editor"
|
||||
:code="code"
|
||||
/>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Button } from 'veui'
|
||||
import i18n from 'veui/mixins/i18n'
|
||||
import OneLive from './OneLive.vue'
|
||||
|
||||
export default {
|
||||
name: 'one-repl',
|
||||
components: {
|
||||
'veui-button': Button,
|
||||
'one-live': OneLive
|
||||
},
|
||||
mixins: [i18n],
|
||||
props: {
|
||||
code: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClose () {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.repl
|
||||
display flex
|
||||
flex-direction column
|
||||
|
||||
.header
|
||||
display flex
|
||||
align-items center
|
||||
flex none
|
||||
height 48px
|
||||
padding 0 24px
|
||||
box-shadow 0 0 4px #0006
|
||||
position relative
|
||||
|
||||
h1
|
||||
flex none
|
||||
margin 0
|
||||
font-size 16px
|
||||
|
||||
.actions
|
||||
display flex
|
||||
justify-content flex-end
|
||||
flex 1 1 auto
|
||||
|
||||
.editor
|
||||
flex 1 1 auto
|
||||
height calc(100vh - 48px)
|
||||
|
||||
& >>> .prism-editor-wrapper
|
||||
padding 8px 12px
|
||||
font-size 12px
|
||||
color #eee
|
||||
background-color #0a0b0d
|
||||
line-height 1.5
|
||||
font-family Menlo, consolas, monospace
|
||||
-webkit-font-smoothing auto
|
||||
|
||||
&::-webkit-scrollbar
|
||||
width 8px
|
||||
background transparent
|
||||
transition all 0.3s
|
||||
|
||||
&-thumb
|
||||
border-radius 4px
|
||||
background-color #282c33
|
||||
|
||||
&:hover::-webkit-scrollbar-thumb
|
||||
background-color #545b66
|
||||
|
||||
textarea
|
||||
outline none
|
||||
|
||||
& >>> .live-preview
|
||||
padding 24px 36px
|
||||
|
||||
& >>> .VueLive-error
|
||||
display none
|
||||
</style>
|
@ -58,7 +58,7 @@ module.exports = {
|
||||
transpile: ['veui', 'vue-awesome', 'resize-detector', 'less-plugin-dls', 'dls-graphics'],
|
||||
|
||||
babel: {
|
||||
plugins: ['veui', 'lodash']
|
||||
plugins: ['veui']
|
||||
},
|
||||
|
||||
loaders: {
|
||||
@ -104,6 +104,34 @@ module.exports = {
|
||||
expr: "process.env.VUE_ENV === 'server'"
|
||||
}
|
||||
})
|
||||
|
||||
config.resolve.alias.vue$ = 'vue/dist/vue.esm.js'
|
||||
config.resolve.alias['vue-inbrowser-compiler-utils'] = '@justfork/vue-inbrowser-compiler-utils'
|
||||
},
|
||||
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
veui: {
|
||||
test: /node_modules[\\/]veui/,
|
||||
chunks: 'all',
|
||||
priority: 20,
|
||||
name: true
|
||||
},
|
||||
'veui-theme-dls-icons': {
|
||||
test: /node_modules[\\/]veui-theme-dls-icons/,
|
||||
chunks: 'all',
|
||||
priority: 20,
|
||||
name: true
|
||||
},
|
||||
'vue-live': {
|
||||
test: /node_modules[\\/]vue-live/,
|
||||
chunks: 'all',
|
||||
priority: 20,
|
||||
name: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@
|
||||
| ``readonly`` | `boolean=` | `false` | 是否为只读状态。 |
|
||||
| ``overlay-class`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-class`](./overlay#props-overlay-class) 属性。 |
|
||||
| ``overlay-style`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-style`](./overlay#props-overlay-style) 属性。 |
|
||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | [number, number] | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
|
||||
^^^ui
|
||||
|
@ -57,7 +57,7 @@
|
||||
| ``disabled`` | `boolean=` | `false` | 是否为禁用状态。 |
|
||||
| ``overlay-class`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-class`](./overlay#props-overlay-class) 属性。 |
|
||||
| ``overlay-style`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-style`](./overlay#props-overlay-style) 属性。 |
|
||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | [number, number] | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
|
||||
^^^ui
|
||||
|
@ -41,7 +41,7 @@
|
||||
| ``expanded`` | `boolean=` | `false` | [^expanded] |
|
||||
| ``disabled`` | `boolean=` | `false` | 是否为禁用状态。 |
|
||||
| ``readonly`` | `boolean=` | `false` | 是否为只读状态。 |
|
||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | [number, number] | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||
|
||||
^^^ui
|
||||
|
@ -6,9 +6,13 @@
|
||||
message="恭喜你,你的请求已成功处理"
|
||||
closable
|
||||
>
|
||||
<template slot="title">恭喜你</template>
|
||||
<template slot="title">
|
||||
恭喜你
|
||||
</template>
|
||||
<template slot="extra">
|
||||
<veui-button ui="text">查看详情</veui-button>
|
||||
<veui-button ui="text">
|
||||
查看详情
|
||||
</veui-button>
|
||||
</template>
|
||||
恭喜你,你的请求已成功处理
|
||||
</veui-alert>
|
||||
|
@ -10,7 +10,9 @@
|
||||
type="success"
|
||||
>
|
||||
Your profile has been updated.
|
||||
<template slot="title">消息标题</template>
|
||||
<template slot="title">
|
||||
消息标题
|
||||
</template>
|
||||
</veui-alert>
|
||||
</article>
|
||||
</template>
|
||||
|
@ -101,7 +101,6 @@ export default {
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<docs>
|
||||
|
@ -132,7 +132,6 @@ export default {
|
||||
top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<docs>
|
||||
|
@ -108,7 +108,6 @@ export default {
|
||||
top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<docs>
|
||||
|
@ -46,7 +46,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped docs>
|
||||
<style lang="less" scoped>
|
||||
h4 {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
@ -1,22 +1,28 @@
|
||||
<template>
|
||||
<article>
|
||||
<veui-pagination
|
||||
:page="page"
|
||||
:total="total"
|
||||
:to="to"
|
||||
/>
|
||||
<veui-pagination
|
||||
:page="page"
|
||||
:total="total"
|
||||
:to="to"
|
||||
ui="s"
|
||||
/>
|
||||
<veui-pagination
|
||||
:page="page"
|
||||
:total="total"
|
||||
:to="to"
|
||||
ui="xs"
|
||||
/>
|
||||
<section>
|
||||
<veui-pagination
|
||||
:page="page"
|
||||
:total="total"
|
||||
:to="to"
|
||||
/>
|
||||
</section>
|
||||
<section>
|
||||
<veui-pagination
|
||||
:page="page"
|
||||
:total="total"
|
||||
:to="to"
|
||||
ui="s"
|
||||
/>
|
||||
</section>
|
||||
<section>
|
||||
<veui-pagination
|
||||
:page="page"
|
||||
:total="total"
|
||||
:to="to"
|
||||
ui="xs"
|
||||
/>
|
||||
</section>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<article>
|
||||
<section>
|
||||
<p>loading:<veui-switch v-model="loading"/></p>
|
||||
<div>loading:<veui-switch v-model="loading"/></div>
|
||||
<veui-table
|
||||
:data="data"
|
||||
:loading="loading"
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<article>
|
||||
<section>
|
||||
<p>
|
||||
<div>
|
||||
允许不排序:<veui-switch
|
||||
v-model="allowFalse"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<veui-table
|
||||
:data="sorted"
|
||||
key-field="id"
|
||||
|
1642
package-lock.json
generated
1642
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@docsearch/css": "^3.0.0-alpha.39",
|
||||
"@docsearch/js": "^3.0.0-alpha.39",
|
||||
"@justfork/vue-inbrowser-compiler-utils": "^4.42.0",
|
||||
"@stackblitz/sdk": "^1.5.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
@ -45,10 +46,10 @@
|
||||
"hastscript": "^3.1.0",
|
||||
"highlight.js": "^10.7.3",
|
||||
"js-yaml": "^3.13.1",
|
||||
"less": "3.9.0",
|
||||
"less": "^3.13.1",
|
||||
"less-loader": "^4.1.0",
|
||||
"less-plugin-est": "^3.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lowlight": "^1.9.2",
|
||||
"mdast-util-to-string": "^2.0.0",
|
||||
"mkdirp": "^0.5.5",
|
||||
@ -58,6 +59,7 @@
|
||||
"preact": "^10.5.14",
|
||||
"prettier": "^1.16.4",
|
||||
"prettier-eslint": "^8.8.2",
|
||||
"prism-theme-night-owl": "^1.4.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"recursive-readdir-sync": "^1.0.6",
|
||||
@ -71,6 +73,7 @@
|
||||
"remark-shortcodes": "^0.1.5",
|
||||
"remark-slug": "^4.2.3",
|
||||
"short-circuit-loader": "0.0.1-alpha.2",
|
||||
"splitpanes": "^2.3.8",
|
||||
"stringify-object": "^3.3.0",
|
||||
"stylelint": "^13.6.1",
|
||||
"stylelint-plugin-stylus": "^0.9.0",
|
||||
@ -84,6 +87,7 @@
|
||||
"veui-theme-dls-icons": "^2.2.1",
|
||||
"vue-awesome": "^4.1.0",
|
||||
"vue-i18n": "^8.16.0",
|
||||
"vue-live": "^1.17.1",
|
||||
"vue-windows": "^0.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -5,6 +5,7 @@ i18n.register(
|
||||
{
|
||||
showCode: '显示代码',
|
||||
hideCode: '隐藏代码',
|
||||
expandEditor: '展开实时编辑',
|
||||
playInCodeSandbox: '在 CodeSandbox 中打开',
|
||||
playInStackBlitz: '在 StackBlitz 中打开'
|
||||
},
|
||||
@ -18,6 +19,7 @@ i18n.register(
|
||||
{
|
||||
showCode: 'Show code',
|
||||
hideCode: 'Hide code',
|
||||
expandEditor: 'Expand Live Editor',
|
||||
playInCodeSandbox: 'Open in CodeSandbox',
|
||||
playInStackBlitz: 'Open in StackBlitz'
|
||||
},
|
||||
@ -26,6 +28,56 @@ i18n.register(
|
||||
}
|
||||
)
|
||||
|
||||
i18n.register(
|
||||
'zh-Hans',
|
||||
{
|
||||
copyCode: '复制代码',
|
||||
copySuccess: '复制成功!',
|
||||
copyFailed: '复制失败!',
|
||||
reset: '重置',
|
||||
dismiss: '关闭'
|
||||
},
|
||||
{
|
||||
ns: 'onelive'
|
||||
}
|
||||
)
|
||||
|
||||
i18n.register(
|
||||
'en-US',
|
||||
{
|
||||
copyCode: 'Copy code',
|
||||
copySuccess: 'Copy success!',
|
||||
copyFailed: 'Copy failed!',
|
||||
reset: 'Reset',
|
||||
dismiss: 'Dismiss'
|
||||
},
|
||||
{
|
||||
ns: 'onelive'
|
||||
}
|
||||
)
|
||||
|
||||
i18n.register(
|
||||
'zh-Hans',
|
||||
{
|
||||
exit: '退出',
|
||||
liveEdit: '实时编辑'
|
||||
},
|
||||
{
|
||||
ns: 'onerepl'
|
||||
}
|
||||
)
|
||||
|
||||
i18n.register(
|
||||
'en-US',
|
||||
{
|
||||
exit: 'Exit',
|
||||
liveEdit: 'Live Edit'
|
||||
},
|
||||
{
|
||||
ns: 'onerepl'
|
||||
}
|
||||
)
|
||||
|
||||
i18n.register(
|
||||
'zh-Hans',
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user