个人自学前端32-Vue9-路由组件通信,动态路由
一.路由组件通信
路由组件间通信,用bus通信会变得和麻烦
因为目标路由组件默认情况下没有创建
路由组件通信 => 路由参数.
- 通过params传参.只能通过name跳转. 获取参数: $route.params.参数名
- 通过query传参.可以是name或者path跳转. 获取参数: $route.query.参数名
params传参和query传参区别
- query传参通过url传递,params不是.
- query只应该传递字符串和数字的参数,params可以传递任何类型的参数.
- query的参数长度不能超过2000字符.(受url长度限制).params没有长度限制.
- query传递的参数刷新后还存在.params的参数刷新后丢失.
<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',
// // query书写需要通信的数据
// query: {
// msg: this.msg
// }
// });
// this.$router.push({
// path: '/news',
// // query书写需要通信的数据
// 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>
1. $route对象
this.$route => 任何组件都可以访问.可以获取路由路径,路由参数等数据
区别:
$route => 路由选项对象.(每次路由切换时,它内部的属性都会改变)
$router => 路由实例.(跳转路由时用这个对象)
routes => 路由配置表 (实例化路由时写的)
2.params刷新丢失
$route.params.msg => 刷新后变成undefined
只有在Home跳到News时.$route.params.msg才是我们希望传递的参数.
只要不是Home到News的路由跳转,都无法获取这个msg数据
刷新相对于是从News到News.因此无法获取msg.
缓存组件时,刷新网页,也会导致组件重新创建的.
二. 动态路由
基本路由 => 一个路径对应一个组件(页面有限).
动态路由 => 多个路径对应一个组件(重复页面)(组件根据不同的路径显示不同的内容).
动态路由 => 切换视图时,组件的updated触发,created不触发.
动态路由 => 切换视图时,created不会重复触发.就算缓存后,activated也不会重复触发.
如何实现组件根据不同的路径显示不同的内容?
工作中是通过不同的接口来完成的.例如根据不同的路径请求不同接口,请求到数据后渲染即可.
动态路径 => 意味着所有的路径都匹配.
path: '/:path' => path => 是一个变量,是一个动态的路径.
path的值如何确定? => 当前的路径是什么,它就会自动变成什么.
如何获取这个参数?
$route.params.动态路径名获取.(不带/)
如果用了动态路径,一定需要注意路由选项的顺序问题.
每次路径变化,都会遍历routes数组,看当前的路径和routes内的那个路径一致,
如果有匹配的路径,就显示对应的组件.
从上往下匹配,如果前面的path匹配了,后面的path就不检查了.
多个动态的路径字段,都可以通过params来获取.
<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>
三. 路由选项的props
路由选项的props => 用于进行组件和路由的解耦
props 的作用 => $route.params.abc 映射成组件的 props数据abc
props的三种模式:
1. 布尔模式 (值是布尔值)
布尔模式 => 把$route.params.msg 映射成 组件的props
<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 router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
name: 'home'
}, {
path: '/news',
component: News,
name: 'news',
// 布尔模式
props: true
}, {
path: '/',
redirect: '/home'
}
]
});
2. 对象模式 (值是纯对象)
对象模式 => 把对象是属性映射成组件的props.
如果props是一个对象,
则可以把对象内的属性,映射成组件的props数据
<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>
`
}
</script>
3. 函数模式 (值是函数)
函数模式 => 万能模式.可以映射任何的数据.
函数模式 => 函数需要return一个对象.这个对象的属性就是组件props的数据
函数的参数就是当前路由选项的$route对象.
<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>
`
}
</script>
函数模式映射query
<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>
`
}
</script>
四. 路由选项meta
meta => 可以用于定义一些路由组件的视图表现字段.(自定义字段)
<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>
`
}
</script>
五. 总结
1.路由传参,接收
$router.push({
name: 'home',
params: { 数据1, 数据2,..... }
});
$router.push({
name: 'home',
query: { 数据1, 数据2,..... }
})
$router.push({
path: '/home',
query: { 数据1, 数据2,..... }
})
接收:
$route.params.数据名
$route.query.数据名
2.params和query的区别
- query是通过url传递的参数.params不是
- query可以用name和path,params只能用name
- query只能传递字符串和数字,最多2000字符.params传递的数据类型和长度没有限制.
- query刷新还在.params刷新数据丢失.
3.props
props => 让组件和路由解耦.
- 布尔模式 => 让$route.params映射成组件的props.
- 对象模式 => 让指定对象的属性映射成组件的props.
props: {
数据1,
数据2,
数据3,
}
props: [数据1, 数据2, 数据3] - 函数模式 => 可以指定任何的映射形式
函数模式映射query => props: (route) => ({ msg: route.query.msg });
4.动态路由
动态路由 => 多个路径对应一个组件,组件根据不同的路径渲染不同的内容.
:path => 动态路径(路由参数) => 会自动变成当前url的路径.
routes匹配顺序是自上而下的,上面的选项匹配了,后面的就不匹配了.
routes:[
{
path: '/:path',
component: Home
}
];
本文来自博客园,作者:暗鸦08,转载请注明原文链接:https://www.cnblogs.com/DarkCrow/p/15359333.html

浙公网安备 33010602011771号