feat(app): add app component to support detached components' namespace

This commit is contained in:
07akioni 2019-08-20 16:47:51 +08:00
parent d3d7667546
commit 92eb23a951
9 changed files with 252 additions and 1 deletions

View File

@ -0,0 +1,32 @@
<template>
<div
ref="doc"
class="n-doc"
>
<div class="n-doc-header">
<n-gradient-text :font-size="20">
scaffold
</n-gradient-text>
</div>
<div class="n-doc-body">
<scaffold />
</div>
</div>
</template>
<script>
import scaffold from './scaffold.demo.vue'
export default {
components: {
scaffold
},
data () {
return {
}
},
methods: {
}
}
</script>

View File

@ -0,0 +1,136 @@
<template>
<div class="n-doc-section">
<div class="n-doc-section__header">
Scaffold
</div>
<div
class="n-doc-section__view"
style="flex-wrap: nowrap;"
>
<!--EXAMPLE_START-->
<n-app :namespace="ns">
<n-modal v-model="isActive">
<template v-slot:activator>
<n-button
size="small"
@click="isActive = true"
>
Parklife
</n-button>
</template>
<n-nimbus-form-card
width="1032"
title="Parklife"
:deactivate="() => isActive = false"
>
<template v-slot:header>
v-slot:header
</template>
<template v-slot:footer>
v-slot:footer
</template>
<template v-slot:content>
<n-date-picker
v-model="time"
type="datetime"
/>
<n-select
v-model="selectedValue"
size="small"
placeholder="Please Select Type"
:items="items"
style="flex-grow: 1;"
/>
<n-tooltip
placement="bottom"
trigger="click"
style="margin-right: 12px;"
>
<template v-slot:activator>
<n-button style="margin: 0;">
California Girls(Click)
</n-button>
</template>
<span>
I wish they all could be California girls
</span>
</n-tooltip>
</template>
</n-nimbus-form-card>
</n-modal>
</n-app>
<!--EXAMPLE_END-->
</div>
<pre class="n-doc-section__inspect"><n-button @click="ns='custom-app-namespace1'">custom-app-namespace1</n-button><n-button @click="ns='custom-app-namespace2'">custom-app-namespace2</n-button></pre>
<n-doc-source-block>
<!--SOURCE-->
</n-doc-source-block>
</div>
</template>
<script>
export default {
data () {
return {
ns: 'custom-app-namespace1',
isActive: false,
time: null,
selectedValue: null,
items: [
{
label: "Everybody's Got Something to Hide Except Me and My Monkey",
value: 'song0'
},
{
label: 'Drive My Car',
value: 'song1'
},
{
label: 'Norwegian Wood',
value: 'song2'
},
{
label: "You Won't See",
value: 'song3'
},
{
label: 'Nowhere Man',
value: 'song4'
},
{
label: 'Think For Yourseld',
value: 'song5'
},
{
label: 'The Word',
value: 'song6'
},
{
label: 'Michelle',
value: 'song7'
},
{
label: 'What goes on',
value: 'song8'
},
{
label: 'Girl',
value: 'song9'
},
{
label: "I'm looking through you",
value: 'song10'
},
{
label: 'In My Life',
value: 'song11'
},
{
label: 'Wait',
value: 'song12'
}
]
}
}
}
</script>

View File

@ -63,6 +63,10 @@ export default {
name: 'Anchor',
path: '/n-anchor'
},
{
name: 'App',
path: '/n-app'
},
{
name: 'BackTop',
path: '/n-back-top'

View File

@ -50,6 +50,7 @@ import dividerDemo from './components/dividerDemo'
import popconfirmDemo from './components/popconfirmDemo'
import anchorDemo from './components/anchorDemo'
import popselectDemo from './components/popselectDemo'
import appDemo from './components/appDemo'
import demo from './demo'
import popoverDebug from './debugComponents/popoverDebug'
@ -127,7 +128,8 @@ const routes = [
{ path: '/n-popconfirm', component: popconfirmDemo },
{ path: '/n-anchor', component: anchorDemo },
{ path: '/n-dropdown', component: dropdownDemo },
{ path: '/n-popselect', component: popselectDemo }
{ path: '/n-popselect', component: popselectDemo },
{ path: '/n-app', component: appDemo }
]
},
{

View File

@ -49,6 +49,7 @@ import Popconfirm from './packages/common/Popconfirm'
import Anchor from './packages/common/Anchor'
import Dropdown from './packages/common/Dropdown'
import Popselect from './packages/common/Popselect'
import App from './packages/common/App'
function install (Vue) {
Card.install(Vue)
@ -102,6 +103,7 @@ function install (Vue) {
Anchor.install(Vue)
Dropdown.install(Vue)
Popselect.install(Vue)
App.install(Vue)
}
export default {

View File

@ -0,0 +1,8 @@
/* istanbul ignore file */
import Scaffold from './src/main.vue'
Scaffold.install = function (Vue) {
Vue.component(Scaffold.name, Scaffold)
}
export default Scaffold

View File

@ -0,0 +1,22 @@
<template>
<div class="n-app">
<slot />
</div>
</template>
<script>
export default {
name: 'NApp',
provide () {
return {
NApp: this
}
},
props: {
namespace: {
type: String,
default: null
}
}
}
</script>

View File

@ -7,6 +7,12 @@
* @prop {HTMLElement} detachTarget determine where should $refs.contentContainer to be detached
*/
export default {
inject: [ 'NApp' ],
computed: {
namespace () {
return (this.NApp && this.NApp.namespace) || null
}
},
props: {
detachTarget: {
validator () {
@ -19,10 +25,30 @@ export default {
default: false
}
},
watch: {
'NApp.namespace': function (newNamespace, oldNamespace) {
this.removeNamespace(oldNamespace)
this.setNamespace(newNamespace)
}
},
methods: {
detachContent () {
this.$refs.contentContainer.parentNode.removeChild(this.$refs.contentContainer)
this.detachTarget.append(this.$refs.contentContainer)
},
removeNamespace (namespace) {
if (!namespace) return
const contentContainer = this.$refs.contentContainer
if (contentContainer) {
contentContainer.classList.remove(namespace)
}
},
setNamespace (namespace) {
if (!namespace) return
const contentContainer = this.$refs.contentContainer
if (contentContainer) {
contentContainer.classList.add(namespace)
}
}
},
beforeMount () {
@ -30,10 +56,23 @@ export default {
console.warn(this.$options.name, ' will be mounted to', this.detachTarget, ', but it doesn\'t exist! Modal component won\'t work!')
}
},
/**
* There might be some potential problem, it may exists some moment that namespace is removed
*/
mounted () {
this.detachTarget = document.body // getScrollParent(this.$refs.self)
if (this.namespace) {
this.setNamespace(this.namespace)
}
this.detachContent()
},
updated () {
if (this.namespace) {
this.$nextTick().then(() => {
this.setNamespace(this.namespace)
})
}
},
beforeDestroy () {
if (!this.cleanManually) {
this.detachTarget.removeChild(this.$refs.contentContainer)

6
styles/App.scss Normal file
View File

@ -0,0 +1,6 @@
@import './mixins/mixins.scss';
@import './theme/default.scss';
@include b(app) {
position: relative;
}