2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-11 16:52:25 +03:00

More reliable strategy for getting deepmost component + addition of refresh() method + example & documentation on asynchronous updates

This commit is contained in:
Declan de Wet
2016-11-09 07:26:38 +02:00
parent fa290273df
commit 076832cbd6
18 changed files with 268 additions and 45 deletions
+1
View File
@@ -11,6 +11,7 @@
<li><a href="basic-render">Basic Render</a></li>
<li><a href="vue-router">Usage with vue-router</a></li>
<li><a href="vuex">Usage with vuex</a></li>
<li><a href="vuex-async">Usage with vuex + async actions</a></li>
</ul>
</body>
</html>
+7
View File
@@ -0,0 +1,7 @@
<template>
<div id="app">
<h1>vuex-async</h1>
<router-view></router-view>
<p>Inspect Element to see the meta info</p>
</div>
</template>
+9
View File
@@ -0,0 +1,9 @@
import assign from 'object-assign'
import Vue from 'vue'
import store from './store'
import router from './router'
import App from './App.vue'
const app = new Vue(assign(App, { router, store }))
app.$mount('#app')
+5
View File
@@ -0,0 +1,5 @@
<!DOCTYPE html>
<link rel="stylesheet" href="/global.css">
<a href="/">&larr; Examples index</a>
<div id="app"></div>
<script src="/__build__/vuex-async.js"></script>
+17
View File
@@ -0,0 +1,17 @@
import Vue from 'vue'
import Router from 'vue-router'
import Meta from 'vue-meta'
import Home from './views/Home.vue'
import Post from './views/Post.vue'
Vue.use(Router)
Vue.use(Meta)
export default new Router({
mode: 'history',
base: '/vuex-async',
routes: [
{ path: '/', component: Home },
{ path: '/posts/:slug', component: Post }
]
})
+77
View File
@@ -0,0 +1,77 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// STATE
state: {
isLoading: false,
// its important that we set some defaults for the current post
// otherwise Vue will complain that properties are `null`
post: {
title: '',
content: '',
slug: '',
published: false
},
posts: [{
slug: 'a-sample-blog-post',
title: 'A Sample Blog Post',
content: 'This is the blog post content',
published: true
}, {
slug: 'an-unpublished-blog-post',
title: 'An Unpublished Blog Post',
content: 'This is the blog post content',
published: false
}, {
slug: 'another-blog-post',
title: 'Another Blog Post',
content: 'This is the blog post content',
published: true
}]
},
// GETTERS
getters: {
isLoading (state) {
return state.isLoading
},
post (state) {
return state.post
},
publishedPosts (state) {
return state.posts.filter((post) => post.published)
},
publishedPostsCount (state, getters) {
return getters.publishedPosts.length
}
},
// MUTATIONS
mutations: {
loadingState (state, { isLoading }) {
state.isLoading = isLoading
},
getPost (state, { slug }) {
state.post = state.posts.find((post) => post.slug === slug)
}
},
// ACTIONS
actions: {
getPost ({ commit }, payload) {
commit('loadingState', { isLoading: true })
// we have to return a promise from this action so we know
// when it is finished
return new Promise((resolve) => {
setTimeout(() => {
commit('getPost', payload)
resolve()
}, 2000)
})
.then(() => commit('loadingState', { isLoading: false }))
}
}
})
+26
View File
@@ -0,0 +1,26 @@
<template>
<div>
<h3>This is the homepage</h3>
<h4>There are <u>{{ postsCount }}</u> published posts</h4>
<ul>
<li v-for="post in posts">
<router-link :to="'posts/' + post.slug">{{ post.title }}</router-link>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'home',
computed: mapGetters({
posts: 'publishedPosts',
postsCount: 'publishedPostsCount'
}),
metaInfo: {
title: 'Home'
}
}
</script>
+37
View File
@@ -0,0 +1,37 @@
<template>
<div>
<template v-if="isLoading">
<h3>Loading...</h3>
</template>
<template v-else>
<h3>{{ post.title }}</h3>
<p>{{ post.content}}<p>
<router-link to="/">Go back home</router-link>
</template>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: 'post',
beforeMount () {
const { slug } = this.$route.params
// since fetching a post is asynchronous,
// we need to call `this.$meta().refresh()`
// to update the meta info
this.$store.dispatch('getPost', { slug })
.then(() => this.$meta().refresh())
},
computed: mapGetters([
'isLoading',
'post'
]),
metaInfo: {
title () {
return this.isLoading ? 'Loading...' : this.post.title
}
}
}
</script>
+9 -1
View File
@@ -6,7 +6,15 @@ Vue.use(Vuex)
export default new Vuex.Store({
// STATE
state: {
post: null,
isLoading: false,
// its important that we set some defaults for the current post
// otherwise Vue will complain that properties are `null`
post: {
title: '',
content: '',
slug: '',
published: false
},
posts: [{
slug: 'a-sample-blog-post',
title: 'A Sample Blog Post',
+1 -1
View File
@@ -10,7 +10,7 @@
import { mapGetters } from 'vuex'
export default {
name: 'blog-post',
name: 'post',
beforeMount () {
const { slug } = this.$route.params
this.$store.dispatch('getPost', { slug })