vue 页面路由切换时传参的方式有如下几种:
动态路由参数
- 它隐藏字段信息,相对于来说较安全,同时地址栏中的地址也相对较短
- 它必须是先定义后使用,一般用于根据固定参数,返回对应的数据所用
query字符串 ?id=1
通过search字符串的方式来在地址栏中传递数据,相对于来说地址栏会暴露字段信息安全性较低,一般用于搜索相关,它可以不定义就可以直接用
props 隐式传递
隐式传递,它一般用于敏感数据的传递,可以不用
cookie/storage来完成对于页面传参
1. 通过动态路由参数传递
描述:
当我们确定了某一个页面需要根据唯一标识来获取详情的时候,我们一般使用动态路由传递参数。
要注意,通过这种方式传递数据,动态路由必须先定义后使用,并且获取数据时需要唯一标识。
使用:
news.js(这个文件是从 index.js 文件中抽取拆分出来的,最终要被引入到 insex.js 文件中):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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 数据):
1
2
3
4
5
|
[
{ "id": 1000, "title": "新闻1" },
{ "id": 2000, "title": "新闻2" },
{ "id": 3000, "title": "新闻3" }
]
|
new.vue(新闻页):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<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(新闻详情页):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<template>
<div>
</div>
</template>
<script>
export default {
mounted() {
// 获取动态路由参数数据
console.log(this.$route.params)
}
}
</script>
<style lang="scss" scoped></style>
|
2. 通过query字符串传递
new.vue(新闻页):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<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(新闻详情页):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<template>
<div>
</div>
</template>
<script>
export default {
mounted() {
// 获取query字符串
console.log(this.$route.query)
}
}
</script>
<style lang="scss" scoped></style>
|
3. props 隐式传递
news.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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(新闻页):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<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(新闻详情页):
1
2
3
4
5
6
7
8
9
10
11
|
<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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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(新闻详情页):
1
2
3
4
5
6
7
8
9
10
11
12
|
<template>
<div>
<!-- 直接通过 props 获取动态路由参数 -->
<h3>props: {{ $route.params }} -- {{ id }}</h3>
</div>
</template>
<script>
export default {
props: ["id"],
};
</script>
<style lang="scss" scoped></style>
|
|