Here is my setup:
Vue 2.5.16 Veux Vue router
I have setup a simple router view that looks for a child component inside a parent one and the url structure is;
/folders/parent-uuid/child-uuid
I have a component for the parent below:
<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>
This is a pretty straight forward template that looks for some data in vuex etc and puts it into the template. Where I am coming into issues is when I try to get the child component loaded from a nested view.
The router code is as follows:
{
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
},
}
]
},
And the app code where it all gets rendered is as follows:
<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>
For some reason the <router-view />
will not show this child component.
Can anyone help at all point me as to why this won't work?
FolderChild
in theFolder
component. I am pretty sure this even fails if you move the current parent component to its own child route with route''
(aka the empty string). I am going to try to see if I can reproduce how I solved it for a previous project. – Sumurai8path: '/:parentUUID'
bepath: ':parentUUID'
– Bennett Dams