vue-router 导航守卫
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <script type="text/javascript" src="../vue.min.js"></script> <script type="text/javascript" src="../js/node_modules/vue-router/dist/vue-router.min.js"></script> <script src="../node_modules/axios/dist/axios.js"></script> <script type="text/javascript"> // 导航完成后获取数据,这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。 var Index = { template: ` <div>我是首页</div> ` }; var Post = { data() { return { loading: false, error: null, post: null } }, template: ` <div> <div class = 'loading' v-if = 'loading'> loading..... </div> <div v-if="error" class = 'error'> {{error}} </div> <div class = 'content' v-if = 'post'> <h2>{{post.title}}</h2> <p>{{post.body}}</p> </div> </div> `, created() { // 组件创建完成后获取数据 // 此时data已经被监听了 this.fetchData(); }, watch: { '$route': 'fetchData' }, methods: { fetchData() { this.error = null; this.post = null; this.loading = true; this.$axios.get('http://127.0.0.1:8888/post') .then(res => { this.loading = false; console.log(res.data); this.post = res.data; }) .catch(err => { this.error = err.toString(); }) } } } var router = new VueRouter({ routes: [{ path: '/index', name: 'index', component: Index }, { path: '/post', name: 'post', component: Post } ] }); var App = { template: ` <div> <router-link :to = "{name:'index'}">首页</router-link> <router-link :to = "{name:'post'}">我的博客</router-link> <router-view></router-view> </div> ` }; Vue.prototype.$axios = axios; new Vue({ el: "#app", data: { }, components: { App }, template: `<App />`, router }); </script> </body> </html>
导航完成之前获取参数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"></div> <script src="vue.js"></script> <script type="text/javascript" src="vue-router.js"></script> <script type="text/javascript" src="axios.js"></script> <script> Vue.use(VueRouter) var User = { data() { return { user: '', error: null, timer: null, num: 0, msg: '', //输入框中输入的内容 msg1: '', //页面中展示的数据 confir: true } }, template: ` <div> <div>{{num}}</div> <input type="text" v-model = 'msg' /> <p>{{msg1}}</p> <button @click='save'>保存</button> <div v-if="error" class = 'error'> {{error}} </div> <div class='user' v-if = 'user'> <h2>{{user}}</h2> </div> </div> `, methods: { setDatas(user) { this.user = user; }, setError(err) { this.err = err; }, save() { this.msg1 = this.msg; this.msg = ''; this.confir = true; } }, created() { this.timer = setInterval(() => { console.log(this.num) this.num += 1; }, 1000) }, beforeRouteEnter(to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 console.log(to); axios.get(`http://127.0.0.1:8888/user/${to.params.id}`) .then(res => { next(vm => vm.setDatas(res.data)); }) .catch(err => { next(vm => vm.setError(err)) }) }, beforeRouteUpdate(to, from, next) { console.log(to) // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` this.user = null; this.$axios.get(`http://127.0.0.1:8888/user/${to.params.id}`) .then(res => { this.setDatas(res.data); next(); }) .catch(err => { this.setError(err); next(); }) }, beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` clearInterval(this.timer); console.log('离开了'); if (this.confir == true && this.msg) { //证明用户输入了内容 需要提示用户 保存重要信息 this.confir = confirm('请保存重要信息'); //用户点击了取消按钮 返回值为false next(false); } else if (this.confir == false) { alert('请保存次信息后退出'); next(false); } else { next(); //放行路由 } } } //我是测试组件 var Test = { template: ` <div>我是测试组件</div> ` } // 路由的配置 var router = new VueRouter({ routes: [{ path: '/user/:id', name: 'user', component: User, }, { path: '/test', name: 'test', component: Test }] }); //入口组件 var App = { template: ` <div> <router-link :to = "{name:'test'}">测试</router-link> <router-link :to = "{name:'user',params:{id:1}}">我的用户1</router-link> <router-link :to = "{name:'user',params:{id:2}}">我的用户2</router-link> <router-view></router-view> </div> ` }; Vue.prototype.$axios = axios; new Vue({ el: "#app", data: { }, components: { App }, template: `<App />`, router }); </script> </body> </html>