mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-18 12:34:25 +08:00
feat(app): add app component to support detached components' namespace
This commit is contained in:
parent
d3d7667546
commit
92eb23a951
32
demo/components/appDemo/index.vue
Normal file
32
demo/components/appDemo/index.vue
Normal 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>
|
136
demo/components/appDemo/scaffold.demo.vue
Normal file
136
demo/components/appDemo/scaffold.demo.vue
Normal 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>
|
@ -63,6 +63,10 @@ export default {
|
||||
name: 'Anchor',
|
||||
path: '/n-anchor'
|
||||
},
|
||||
{
|
||||
name: 'App',
|
||||
path: '/n-app'
|
||||
},
|
||||
{
|
||||
name: 'BackTop',
|
||||
path: '/n-back-top'
|
||||
|
@ -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 }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
2
index.js
2
index.js
@ -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 {
|
||||
|
8
packages/common/App/index.js
Normal file
8
packages/common/App/index.js
Normal 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
|
22
packages/common/App/src/main.vue
Normal file
22
packages/common/App/src/main.vue
Normal 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>
|
@ -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
6
styles/App.scss
Normal file
@ -0,0 +1,6 @@
|
||||
@import './mixins/mixins.scss';
|
||||
@import './theme/default.scss';
|
||||
|
||||
@include b(app) {
|
||||
position: relative;
|
||||
}
|
Loading…
Reference in New Issue
Block a user