一、路由组件通信
1.0
<body>
<div id='app'>
</div>
</body>
路由组件间通信,用bus通信会变得和麻烦
因我目标路由组件默认情况下没有创建
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const bus = new Vue();
const Home = {
template: `
<div>
<h3>首页--{{msg}}</h3>
<input type='text' v-model='msg' />
<button @click='toNews'>到新闻页</button>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return { msg: '' }
},
methods: {
toNews() {
this.$router.push('/news');
bus.$emit('getmsg', this.msg);
console.log('$emit');
}
}
}
const News = {
template: `
<div>
<h3>新闻---{{msg}}</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
data() {
return { msg: '' }
},
created() {
console.log('$on');
bus.$on('getmsg', (msg) => {
this.msg = msg
})
}
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/guide',
component: Guide
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<keep-alive>
<router-view />
</keep-alive>
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
1.1
路由组件通信 => 路由参数.
1:通过params传参.只能通过name跳转. 获取参数: $route.params.参数名
2:通过query传参.可以是name或者path跳转. 获取参数: $route.query.参数名params传参和query传参
1:query传参通过url传递,params不是.
2:query只应该传递字符串和数字的参数,params可以传递任何类型的参数.
3:query的参数长度不能超过2000字符.(受url长度限制).params没有长度限制.
4:query传递的参数刷新后还存在.params的参数刷新后丢失.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页--{{msg}}</h3>
<input type='text' v-model='msg' />
<button @click='toNews'>到新闻页</button>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return { msg: '' }
},
methods: {
toNews() {
this.$router.push({
name: 'news',
// params书写需要通信的数据
params: {
msg: this.msg
}
});
// this.$router.push({
// name: 'news',
// // params书写需要通信的数据
// query: {
// msg: this.msg
// }
// });
// this.$router.push({
// path: '/news',
// // params书写需要通信的数据
// query: {
// msg: this.msg,
// abc: 'wwwww'
// }
// });
}
}
}
const News = {
template: `
<div>
<!--<h3>新闻---{{ $route.params.msg }}</h3>-->
<h3>新闻---{{ $route.params.msg }}</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
data() {
return { msg: '' }
},
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: News,
name: 'news'
}, {
path: '/guide',
component: Guide,
name: 'guide'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<keep-alive>
<router-view />
</keep-alive>
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
二、$route对象
<body>
<div id='app'>
</div>
</body>
$router => 路由实例.(跳转路由时用这个对象)
$route => 路由选项对象.(每次路由切换时,它内部的属性都会改变)
routes => 路由配置表 (实例化路由时写的)this.$route => 任何组件都可以访问.可以获取路由路径,路由参数等数据
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页</h3>
<input type='text' />
<button @click='toNews'>到新闻页</button>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
created() {
// console.log(this.$route);
},
methods: {
toNews() {
this.$router.push({
name: 'news',
query: {
msg: '你好'
}
})
console.log('跳转后',this.$route);
}
}
}
const News = {
template: `
<div>
<h3>新闻</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
data() {
return { msg: '' }
},
created() {
console.log('news',this.$route);
}
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: News,
name: 'news'
}, {
path: '/guide',
component: Guide,
name: 'guide'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<keep-alive>
<router-view />
</keep-alive>
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
三、 params刷新丢失
<body>
<div id='app'>
</div>
</body>
$route.params.msg => 刷新后变成undefined
- 只有在Home跳到News时.$route.params.msg才是我们希望传递的参数.
- 只要不是Home到News的路由跳转,都无法获取这个msg数据
- 刷新相对于是从News到News.因此无法获取msg.
- 缓存组件时,刷新网页,也会导致组件重新创建的.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页</h3>
<input type='text' />
<button @click='toNews'>到新闻页</button>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
methods: {
toNews() {
this.$router.push({
name: 'news',
params: {
msg: '你好'
}
})
}
}
}
const News = {
template: `
<div>
<h3>新闻---{{$route.params.msg}}</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
data() {
return { msg: '' }
}
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`,
created() {
console.log(this.$route);
}
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: News,
name: 'news'
}, {
path: '/guide',
component: Guide,
name: 'guide'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<keep-alive>
<router-view />
</keep-alive>
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
四、 动态路由
4.0
<body>
<div id='app'>
</div>
</body>
基本路由 => 一个路径对应一个组件(页面有限).
- 动态路由 => 多个路径对应一个组件(重复页面)(组件根据不同的路径显示不同的内容).
- 动态路由 => 切换视图时,组件的updated触发,created不触发.
- 动态路由 => 切换视图时,created不会重复触发.就算缓存后,activated也不会重复触发.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页--{{$route.path}}</h3>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
updated() {
console.log('Home组件刷新')
},
created() {
console.log('Home组件创建')
}
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: Home,
name: 'news'
}, {
path: '/guide',
component: Home,
name: 'guide'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/guide'>攻略</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
4.1
如何实现组件根据不同的路径显示不同的内容?
- 工作中是通过不同的接口来完成的.例如根据不同的路径请求不同接口,请求到数据后渲染即可.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>{{data[$route.path]}}--{{$route.path}}</h3>
<p>{{data[$route.path]}}的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return {
data: {
'/home': '首页',
'/news': '新闻',
'/sport': '体育'
}
}
}
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: Home,
name: 'news'
}, {
path: '/sport',
component: Home,
name: 'sport'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/sport'>体育</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
4.2
path: '/:path' => path => 是一个变量,是一个动态的路径.
path的值如何确定? => 当前的路径是什么,它就会自动变成什么.
如何获取这个参数?
$route.params.动态路径名获取.(不带/)
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>{{data[$route.params.path]}}--{{$route.params.path}}</h3>
<p>{{data[$route.params.path]}}的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return {
data: {
'home': '首页',
'news': '新闻',
'sport': '体育'
}
}
},
updated() {
console.log(this.$route)
}
}
const router = new VueRouter({
routes: [
{
path: '/:path',
component: Home,
name: 'home'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/sport'>体育</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
五、动态路由选项
<body>
<div id='app'>
</div>
</body>
如果用了动态路径,一定需要注意路由选项的顺序问题.
每次路径变化,都会遍历routes数组,看当前的路径和routes内的那个路径一致,
如果有匹配的路径,就显示对应的组件.
从上往下匹配,如果前面的path匹配了,后面的path就不检查了.动态路径 => 意味着所有的路径都匹配.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Login = {
template: `
<div>
<input type='text' />
<input type='password' />
<button @click='$router.push("/home")'>登录</button>
</div>
`
}
const Home = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/sport'>体育</router-link>
<h3>{{data[$route.params.path]}}--{{$route.params.path}}</h3>
<p>{{data[$route.params.path]}}的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return {
data: {
'home': '首页',
'news': '新闻',
'sport': '体育'
}
}
},
updated() {
console.log(this.$route)
}
}
const router = new VueRouter({
routes: [
{
path: '/login',
component: Login,
}, {
path: '/:path',
component: Home,
name: 'home'
}, {
path: '/',
redirect: '/login'
}
]
});
const App = {
template: `
<div>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
六、动态路径
<body>
<div id='app'>
</div>
</body>
/:abc/:path => 路径必须有两个/
这两个/后面的内容任意./:abc/home/:path => 路径必须有3个/ 中间的路径必须是home
多个动态的路径字段,都可以通过params来获取.
$route.params.abc.
$route.params.path.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>{{data[$route.params.path]}}--{{$route.params.path}}</h3>
<p>{{data[$route.params.path]}}的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return {
data: {
'home': '首页',
'news': '新闻',
'sport': '体育'
}
}
},
updated() {
console.log(this.$route)
}
}
const router = new VueRouter({
routes: [
{
path: '/:abc/home/:path',
component: Home,
name: 'home'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/sport'>体育</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
七、props属性的布尔模式
<body>
<div id='app'>
</div>
</body>
路由选项的props => 用于进行组件和路由的解耦
props 的作用 => $route.params.abc 映射成组件的 props数据abc
props的三种模式
1:布尔模式 (值是布尔值)
2:对象模式 (值是纯对象)
3:函数模式 (值是函数)
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页--{{msg}}</h3>
<input type='text' v-model='msg' />
<button @click='toNews'>到新闻页</button>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return { msg: '' }
},
methods: {
toNews() {
this.$router.push({
name: 'news',
// params书写需要通信的数据
params: {
msg: this.msg
}
});
}
}
}
const News = {
template: `
<div>
<h3>新闻---{{ msg }}</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
props: ['msg']
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: News,
name: 'news',
// 布尔模式
props: true
}, {
path: '/guide',
component: Guide,
name: 'guide'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<keep-alive>
<router-view />
</keep-alive>
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
八、对象模式
<body>
<div id='app'>
</div>
</body>
如果props是一个对象,
则可以把对象内的属性,映射成组件的props数据
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>{{data}}</h3>
<p>{{data}}的内容..<span>2018-07-22</span></p>
</div>
`,
props: ['data']
}
const router = new VueRouter({
routes: [
{
path: '/:path',
component: Home,
name: 'home',
props: {
data: {
home: '首页',
news: '新闻',
sport: '体育'
}
}
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/sport'>体育</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
九、函数模式
<body>
<div id='app'>
</div>
</body>
布尔模式 => 把$route.params.msg 映射成 组件的props
- 对象模式 => 把对象是属性映射成组件的props.
- 函数模式 => 万能模式.可以映射任何的数据.
- 函数模式 => 函数需要return一个对象.这个对象的属性就是组件props的数据
- 函数的参数就是当前路由选项的$route对象.
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>{{data[path]}}</h3>
<p>{{data[path]}}的内容..<span>2018-07-22</span></p>
</div>
`,
props: ['data', 'path']
}
const router = new VueRouter({
routes: [
{
path: '/:path',
component: Home,
name: 'home',
props: (route) => {
return {
path: route.params.path,
data: {
home: '首页',
news: '新闻',
sport: '体育'
}
}
}
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/sport'>体育</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
十、函数模式映射query
<body>
<div id='app'>
</div>
</body>
路由选项的props => 用于进行组件和路由的解耦
props 的作用 => $route.params.abc 映射成组件的 props数据abc
props的三种模式
1:布尔模式 (值是布尔值)
2:对象模式 (值是纯对象)
3:函数模式 (值是函数)
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页--{{msg}}</h3>
<input type='text' v-model='msg' />
<button @click='toNews'>到新闻页</button>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
data() {
return { msg: '' }
},
methods: {
toNews() {
this.$router.push({
name: 'news',
query: {
msg: this.msg
}
});
}
}
}
const News = {
template: `
<div>
<h3>新闻---{{ msg }}</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
props: ['msg']
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`
}
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: News,
name: 'news',
// 函数模式,手动让msg等于route.query.msg
props: (route) => ({ msg: route.query.msg })
}, {
path: '/guide',
component: Guide,
name: 'guide'
}, {
path: '/',
redirect: '/home'
}
]
});
const App = {
template: `
<div>
<keep-alive>
<router-view />
</keep-alive>
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
十一、meta选项
11.0
<body>
<div id='app'>
</div>
</body>
meta => 可以用于定义一些路由组件的视图表现字段.(自定义字段)
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页</h3>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
created() {
// console.log(this.$route)
document.title = this.$route.meta;
}
}
const News = {
template: `
<div>
<h3>新闻</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
created() {
// console.log(this.$route)
document.title = this.$route.meta;
}
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`,
created() {
// console.log(this.$route)
document.title = this.$route.meta;
}
}
const router = new VueRouter({
routes: [
{
path: '/news',
component: News,
meta: '新闻'
}, {
path: '/home',
component: Home,
meta: '首页'
}, {
path: '/guide',
component: Guide,
meta: '攻略'
}, {
path: '/',
redirect: '/home',
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/guide'>攻略</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>
11.1
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script>
const Home = {
template: `
<div>
<h3>首页</h3>
<p>首页的内容..<span>2018-07-22</span></p>
</div>
`,
created() {
// 设置网页标题
document.title = this.$route.meta.title;
}
}
const News = {
template: `
<div>
<h3>新闻</h3>
<p>新闻的内容..<span>2018-07-23</span></p>
</div>
`,
created() {
// 设置网页的标题。
document.title =this.$route.meta.title;
// 获取link标签设置图片。
const [oLink] = document.querySelectorAll('link');
oLink.href = this.$route.meta.icon;
}
}
const Guide = {
template: `
<div>
<h3>攻略</h3>
<p>攻略的内容..<span>2018-07-24</span></p>
</div>
`,
created() {
document.title = this.$route.meta.title;
}
}
const router = new VueRouter({
routes: [
{
path: '/news',
component: News,
meta: {
title: '新闻',
icon: '222.jpg',
}
}, {
path: '/home',
component: Home,
meta: {
title: '首页'
}
}, {
path: '/guide',
component: Guide,
meta: {
title: '攻略'
}
}, {
path: '/',
redirect: '/home',
}
]
});
const App = {
template: `
<div>
<router-link to='/home'>首页</router-link>
<router-link to='/news'>新闻</router-link>
<router-link to='/guide'>攻略</router-link>
<router-view />
</div>
`
}
new Vue({
render: h => h(App),
router
}).$mount('#app');
</script>