目录
- 前言
- 1. 通过动态路由参数传递
- 2. 通过query字符串传递
- 3. props 隐式传递
前言
vue 页面路由切换时传参的方式有如下几种:
动态路由参数
- 它隐藏字段信息,相对于来说较安全,同时地址栏中的地址也相对较短
- 它必须是先定义后使用,一般用于根据固定参数,返回对应的数据所用
query字符串 ?id=1
通过search字符串的方式来在地址栏中传递数据,相对于来说地址栏会暴露字段信息安全性较低,一般用于搜索相关,它可以不定义就可以直接用
props 隐式传递
隐式传递,它一般用于敏感数据的传递,可以不用
cookie/storage来完成对于页面传参
1. 通过动态路由参数传递
描述:
当我们确定了某一个页面需要根据唯一标识来获取详情的时候,我们一般使用动态路由传递参数。
要注意,通过这种方式传递数据,动态路由必须先定义后使用,并且获取数据时需要唯一标识。
使用:
news.js(这个文件是从 index.js 文件中抽取拆分出来的,最终要被引入到 insex.js 文件中):
import News from '@/views/News' | |
import Detail from '@/views/Detail' | |
const routes = [ | |
{ | |
path: '/news', | |
component: News, | |
}, | |
{ | |
// 通过动态路由参数来完成页面数据的传递 | |
path: '/news/:id', | |
component: Detail, | |
}, | |
] | |
export default routes |
index.js:
import Vue from 'vue' | |
import VueRouter from 'vue-router' | |
import news from './routes/news' | |
// 以插件的方式添加 | |
Vue.use(VueRouter) | |
// 实例化路由对象及配置路由表 | |
const routes = [...news] | |
const router = new VueRouter({ | |
// 路由模式 | |
mode: 'history', | |
// 路由规则表 | |
routes | |
}) | |
export default router |
new.json(虚拟新闻 mooc 数据):
[ | |
{ "id": 1000, "title": "新闻1" }, | |
{ "id": 2000, "title": "新闻2" }, | |
{ "id": 3000, "title": "新闻3" } | |
] |
new.vue(新闻页):
<template> | |
<div> | |
<ul> | |
<template v-if="news == null"> | |
<li>加载中...</li> | |
</template> | |
<template v-else> | |
<li @click="godetail(item.id)" v-for="item in news" :key="item.id">{{ item.title }}</li> | |
</template> | |
</ul> | |
</div> | |
</template> | |
<script> | |
import { get } from '@/utils/http' | |
export default { | |
data() { | |
return { | |
news: null | |
} | |
}, | |
async created() { | |
let ret = await get('/mock/news.json') | |
this.news = ret | |
}, | |
methods: { | |
godetail(id) { | |
this.$router.push(`/news/${id}`) | |
} | |
} | |
} | |
</script> | |
<style lang="scss" scoped></style> |
detail.vue(新闻详情页):
<template> | |
<div> | |
</div> | |
</template> | |
<script> | |
export default { | |
mounted() { | |
// 获取动态路由参数数据 | |
console.log(this.$route.params) | |
} | |
} | |
</script> | |
<style lang="scss" scoped></style> |
2. 通过query字符串传递
new.vue(新闻页):
<template> | |
<div> | |
<ul> | |
<template v-if="news == null"> | |
<li>加载中...</li> | |
</template> | |
<template v-else> | |
<li @click="godetail(item.id)" v-for="item in news" :key="item.id">{{ item.title }}</li> | |
</template> | |
</ul> | |
</div> | |
</template> | |
<script> | |
import { get } from '@/utils/http' | |
export default { | |
data() { | |
return { | |
news: null | |
} | |
}, | |
async created() { | |
let ret = await get('/mock/news.json') | |
this.news = ret | |
}, | |
methods: { | |
godetail(id) { | |
this.$router.push(`/news/${id}?kw=abc`) | |
} | |
} | |
} | |
</script> | |
<style lang="scss" scoped></style> |
detail.vue(新闻详情页):
<template> | |
<div> | |
</div> | |
</template> | |
<script> | |
export default { | |
mounted() { | |
// 获取query字符串 | |
console.log(this.$route.query) | |
} | |
} | |
</script> | |
<style lang="scss" scoped></style> |
3. props 隐式传递
news.js:
import News from '@/views/News' | |
import Detail from '@/views/Detail' | |
const routes = [ | |
{ | |
path: '/news', | |
component: News, | |
}, | |
{ | |
// 通过动态路由参数来完成页面数据的传递 | |
path: '/news/:id', | |
component: Detail, | |
// 写法1:回调函数写法,可以书写业务逻辑 | |
// router它就是一个路由对象 | |
props: router => { | |
let title = router.params.id == '1000' ? '爆炸新闻' : '一般新闻' | |
return { | |
state: 2000, | |
title | |
} | |
}, | |
// 写法2:这是一种没什么用的写法,没有业务逻辑 | |
// props: { title: '1', state: 2 } | |
} | |
] | |
export default routes |
new.vue(新闻页):
<template> | |
<div> | |
<ul> | |
<template v-if="news == null"> | |
<li>加载中...</li> | |
</template> | |
<template v-else> | |
<li @click="godetail(item.id)" v-for="item in news" :key="item.id">{{ item.title }}</li> | |
</template> | |
</ul> | |
</div> | |
</template> | |
<script> | |
import { get } from '@/utils/http' | |
export default { | |
data() { | |
return { | |
news: null | |
} | |
}, | |
async created() { | |
let ret = await get('/mock/news.json') | |
this.news = ret | |
}, | |
methods: { | |
godetail(id) { | |
this.$router.push(`/news/${id}?kw=abc`) | |
} | |
} | |
} | |
</script> | |
<style lang="scss" scoped></style> |
detail.vue(新闻详情页):
<template> | |
<div> | |
<h3>props: {{ state }} -- {{ title }}</h3> | |
</div> | |
</template> | |
<script> | |
export default { | |
props: ['state','title'], | |
} | |
</script> | |
<style lang="scss" scoped></style> |
这种传递方式,可以敏感字段从地址栏中隐藏,不会暴露数据,而且回调函数的写法可以书写业务逻辑。
这种方式可以做数据埋点(也叫用户指纹),即隐蔽地收集用户数据。用户每次跳转页面都会触发 props 隐式传递,从而做到用户数据的收集。收集到数据后,通过python、大数据等技术,为用户建模,生成人物画像,由此可以进行大数据推荐。
除了上面两种写法以外,还有第三种写法
news.js:
import News from '@/views/News' | |
import Detail from '@/views/Detail' | |
const routes = [ | |
{ | |
path: '/news', | |
component: News, | |
}, | |
{ | |
// 通过动态路由参数来完成页面数据的传递 | |
path: '/news/:id', | |
component: Detail, | |
// 写法3:布尔类型 | |
// 布尔类型,一但使用,params动态路由参数传的数据,可以通过props来获取 | |
// 设置为布尔类型,可以简化,动态路由参数的数据获取 | |
props: true, | |
} | |
] | |
export default routes |
detail.vue(新闻详情页):
<template> | |
<div> | |
<!-- 直接通过 props 获取动态路由参数 --> | |
<h3>props: {{ $route.params }} -- {{ id }}</h3> | |
</div> | |
</template> | |
<script> | |
export default { | |
props: ["id"], | |
}; | |
</script> | |
<style lang="scss" scoped></style> |