这是我的设置:
Vue 2.5.16 威克斯 Vue路由器
我已经设置了一个简单的路由器视图,该视图在父组件中查找子组件,并且url结构为
;/ folders / parent-uuid / child-uuid
我在下面为父母提供了一个组件:
<template lang="html">
<div>
<!-- Articles -->
<div class="flex-none w-100 mv3 gray"><p>Bookmarks({{ subFolders.contentDetails.articles.length }})</p></div>
<div class="flex flex-row flex-wrap justify-start items-start">
<div v-for="article in subFolders.contentDetails.articles" class="pointer article-item relative mb4">
<a v-on:click.stop.prevent="checkFolder(article.uuid)" :class="[{highlight:selectedItems.includes(article.uuid)}, 'absolute w-100 h-100 left-0 top-0 highlight-area z-3']" href="#"><div class="absolute top-2" style="width: 18px;height: 18px;right: 3.05rem;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path v-if="selectedItems.includes(article.uuid)" fill="#ea792e" d="M3 17.2V21h3.8l11-11.1L14 6.1 3 17.2zM20.7 7c.4-.4.4-1 0-1.4l-2.3-2.3c-.4-.4-1-.4-1.4 0l-1.8 1.8L19 8.9c-.1 0 1.7-1.9 1.7-1.9z"/><path v-else fill="#ffffff" d="M3 17.2V21h3.8l11-11.1L14 6.1 3 17.2zM20.7 7c.4-.4.4-1 0-1.4l-2.3-2.3c-.4-.4-1-.4-1.4 0l-1.8 1.8L19 8.9c-.1 0 1.7-1.9 1.7-1.9z"/></svg></div></a>
<a :class="[{active:selectedItems.includes(article.uuid)}, 'link']" v-bind:href="article.contentUrl">
<div :class="[{active:selectedItems.includes(article.uuid)}, 'contentImage br3 overflow-hidden']">
<img class="w-100" :src=article.titleImage data-flickity-lazyload="article.titleImage">
</div>
<div v-if="article.contentType == 'Behaviour'" class="black">
<h4 class="f3">{{article.contentTitle}}</h4>
</div>
<div v-else class="black">
<h4 class="f3">{{article.contentTitle}}</h4>
</div>
<div v-if="article.contentType == 'Behaviour'">
</div>
<div v-else class="content no-margin">
<p class="f3">{{article.savedDate | moment("D MMM YYYY")}}</p>
</div>
</a>
</div>
</div>
<!-- end v-if -->
<div class="flex-none w-100 mt3 gray folders"><div class="ph5"><p>Subfolders({{ subFolders.subFolders.length }})</p></div></div>
<div class="flex flex-row flex-wrap justify-start items-start">
<div class="folder-item folder z-0 pointer">
<div class="relative db h-100 bg-light-gray folder-new br3 mb4">
<div v-on:click="addFolder($event)" class="top aspect-ratio--object">
<div class="dt w-100 h-100 no-margin showText pv6">
<div class="dtc v-mid tc ">
<svg class="dib v-mid icon-sprite" viewBox="0 0 38.89 38.89" width="40" height="40">
<circle cx="19.45" cy="19.45" r="19.45" fill="#ea792e"/><path stroke="#ffffff" stroke-width="3" d="M19.45 12.26v14.37M12.26 19.45h14.37" />
</svg>
<p>Create new folder</p>
</div>
</div>
</div>
<div class="bottom aspect-ratio--object">
<div class="dt w-100 h-100 ">
<div class="dtc v-mid tc no-margin showText pv6">
<p>Explore the library and add to this folder</p>
<form id="submit-folder" @submit.prevent="sendForm" class="mv3">
<input type="text" name="folderName" value="" placeholder="Add folder name in here..." v-model="folderName">
<input class="db center input-reset bg-orange b--none br2 white mv3 f3 pv3 ph4" style="font-family:'Open Sans',Helvetica Neue,sans-serif;" type="submit" name="Submit">
</form>
</div>
</div>
</div>
<div style="visibility: hidden;" class="image-blocks br3 overflow-hidden relative flex flex-wrap">
<div><img src="http://***/static-assets/images/EMPTY-FOLDER-GREY-1.jpg" alt=""></div>
<div><img src="http://***/static-assets/images/EMPTY-FOLDER-GREY-2.jpg" alt=""></div>
<div><img src="http://***/static-assets/images/EMPTY-FOLDER-GREY-3.jpg" alt=""></div>
</div>
</div>
</div>
<div v-for="folder in subFolders['subFolders']" class="pointer folder folder-item relative">
<a v-on:click.stop.prevent="checkFolder(folder.uuid)" :class="[{highlight:selectedItems.includes(folder.uuid)}, 'absolute w-100 h-100 left-0 top-0 highlight-area z-3']" href="#"><div class="absolute top-2" style="width: 18px;height: 18px;right: 3.05rem;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path v-if="selectedItems.includes(folder.uuid)" fill="#ea792e" d="M3 17.2V21h3.8l11-11.1L14 6.1 3 17.2zM20.7 7c.4-.4.4-1 0-1.4l-2.3-2.3c-.4-.4-1-.4-1.4 0l-1.8 1.8L19 8.9c-.1 0 1.7-1.9 1.7-1.9z"/><path v-else fill="#ffffff" d="M3 17.2V21h3.8l11-11.1L14 6.1 3 17.2zM20.7 7c.4-.4.4-1 0-1.4l-2.3-2.3c-.4-.4-1-.4-1.4 0l-1.8 1.8L19 8.9c-.1 0 1.7-1.9 1.7-1.9z"/></svg></div></a>
<router-link :class="[{active:selectedItems.includes(folder.uuid)}, 'z-0 db relative link']" :to="`/folders/${folderUUID}/${folder.uuid}`">
<div class="image-blocks br3 overflow-hidden relative">
<div class="" v-for="image in folder.topThreeThumbnails">
<img class="" :src=image>
</div>
</div>
</router-link>
<div :class="[{active:selectedItems.includes(folder.uuid)}, 'content']">
<router-link :to="`/folders/${folder.uuid}`" :class="[{active:selectedItems.includes(folder.uuid)}, 'link black']">
<h3>{{folder.folderName}}</h3>
<p>{{folder.subFolderCount}} subfolders, {{folder.totalElements}} elements</p>
</router-link>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapGetters } from 'vuex'
export default {
name: 'subfolderListParent',
data() {
return {
selected: [],
selectedArticles: [],
folder: '',
folderName: '',
folderUUID: this.$route.params.uuid
}
},
mounted: function () {
this.$store.dispatch('LOAD_SUBFOLDERS_LIST',this.$route.params.uuid)
this.$store.dispatch('LOAD_FOLDERS_LIST')
this.$store.state.selectedItems = [];
this.$route.meta.title = this.$store.getters.openSubfolderTitle;
},
props: ['uuid','subfolderName'],
computed: {
...mapState([
'subFolders',
'allFolders',
'allArticles',
'selectedItems',
'selectedFolder'
]),
...mapGetters([
'openSubfolderTitle',
])
},
methods: {
checkFolder: function(item){
this.$store.dispatch('SELECT_FOLDER',item)
},
addFolder: function(event){
const target = event.currentTarget.parentNode,
top = target.children[0],
bottom = target.children[1];
if(bottom.classList.contains('active')){
top.classList.remove('hidden');
bottom.classList.remove('active');
} else {
top.classList.add('hidden');
bottom.classList.add('active');
}
},
sendForm: function(event){
this.$store.dispatch('CREATE_FOLDER',{'folder':this.folderName,'uuid':this.$route.params.uuid})
this.folderName = '';
},
setTitle: function(){
this.$route.meta.title = this.$store.getters.openSubfolderTitle;
}
},
watch: {
'$route': function(from, to) {
this.$route.meta.title = this.$store.getters.openSubfolderTitle;
}
}
}
</script>
这是一个非常简单的模板,可以在vuex等中查找一些数据并将其放入模板中。我遇到的问题是当我尝试从嵌套视图加载子组件时。
路由器代码如下:
{
path: '/folders/:uuid',
component: Folder,
name: 'subfolderListParent',
props: true,
meta: {
bcDynamic: true,
bcGetter: 'openSubfolderTitle', // <breadcrumb> will use this getter to get the user from vuex
bcLinkText: state => state, // once we have the user, we use this function to format the LinkText dnynamically,
bcLoadingText: 'Loading title...' // This will be shown while Data is loading
},
children: [
{
path: '/:parentUUID',
props: true,
components: {
child: FolderChild
},
meta: {
bcDynamic: true,
bcGetter: 'openSubfolderTitle', // <breadcrumb> will use this getter to get the user from vuex
bcLinkText: state => state, // once we have the user, we use this function to format the LinkText dnynamically,
bcLoadingText: 'Loading title...' // This will be shown while Data is loading
},
}
]
},
所有呈现的应用代码如下:
<template>
<div id="app" style="clear:both;min-height:100vh;" class="flex-l flex-row flex-wrap items-stretch">
<transition name="slide-fade">
<div class="fixed right-2 br2 ph4 pv3 bg-orange white z-3" v-on:click="$store.state.noteText.note = !$store.state.noteText.note" v-bind:key="$store.state.noteText.note" v-if="$store.state.noteText.note === true">
<p class="white ma0 pa0 dib v-mid">{{$store.state.noteText.note}}</p>
</div>
</transition>
<MainNav/>
<div v-if="$route.path === '/from-canvas8'"></div>
<div class="flex-none" v-else>
<FolderActions/>
</div>
<div class="dib w-75-l w-100 v-top ph5 appWrapper">
<router-view></router-view>
</div>
</div>
</template>
<script>
import MainNav from './components/MainNav.vue'
import FolderList from './components/FolderList.vue'
import FolderActions from './components/FolderActions.vue'
import ScrapbookHome from './components/ScrapbookHome.vue'
import { mapState } from 'vuex'
export default {
components: {
MainNav,
FolderList,
FolderActions,
ScrapbookHome
},
name: 'scrapbook',
data () {
return {
welcomeMessage: 'Story Navigation'
}
},
methods: {
updateScroll: function(){
const nav = document.querySelector('.scrapbook-actions');
const navTop = nav.offsetTop;
function stickyNavigation() {
if (window.scrollY >= navTop) {
// nav offsetHeight = height of nav
nav.classList.add('fixed');
} else {
nav.classList.remove('fixed');
}
}
window.addEventListener('scroll', stickyNavigation);
},
},
mounted: function () {
// this.$store.dispatch('LOAD_FOLDERS_LIST')
//this.setNavHeight()
this.$store.dispatch('GET_USER')
},
watch: {
'$route': function(from, to) {
//this.updateScroll()
//this.setNavHeight()
}
}
}
</script>
由于某些原因,<router-view />
将不会显示此子组件。
任何人都可以帮我指出为什么这行不通吗?
答案 0 :(得分:0)
嵌套路线时,每个路线零件都将安装在父路线的组件中。在您的情况下,$ stack exec duckling-example-exe
no port specified, defaulting to port 8000
Listening on http://0.0.0.0:8000
将安装在Folder
中,而App
将安装在FolderChild
中。据我所知,即使您没有为特定子路由定义组件,嵌套路由也总是如此。据我所知,没有像fallthrough选项那样将组件安装在适用祖先而不是直接父代中的东西。
有两种方法可以解决此问题。最简单的方法是不使用子路由,除非每个子路由周围都有一个共享的样板。您将获得类似以下内容的信息。您可以使用注释在某种程度上组织您的路线。
Folder
另一种方法是仍然使用嵌套路由,但在父路由中放置一个具有单个路由器视图的虚拟组件,而您无需渲染任何其他东西。
export default [
{
// some other routes
},
// Folder routes
{
path: '/folders/:uuid/:parentuuid',
component: FolderChild,
name: 'folderchild'
},
{
path: '/folders/:uuid',
component: Folder,
name: 'folders'
}
];
然后,将“默认”路由移动到具有空路径的子路由,并使用此虚拟视图渲染父路由,并在此虚拟视图中同时安装// DummyView.vue
<template>
<router-view />
</template>
<script>
// Used to fill parent routes that need to have children mounted in them
export default {
name: 'dummy-view'
}
</script>
和Folder
。 / p>
FolderChild
当您在一个组件中有多个(命名的)视图时,该解决方案将变得特别糟糕,所有视图都需要填充以用于子视图。令人高兴的是,如果您具有共享的逻辑,则可以使用这些步骤逐步构建所需的视图,而无需诉诸这些仅用于放置子组件的虚拟组件。