路由组件传参
我们通常把路由直接映射(绑定)的组件称为路由组件,也只有路由组件才能直接调用路由有关对象:$router
、$route
。
当我们想把一个组件既希望作为路由组件使用,有可能作为功能组件(某一页面中的一部分)去使用,这个时候用路由组件传参的方式来做到这点。
案例
我们对item.vue组件进行改造,当我们在home.vue的商品列表上移入移出,出现商品信息提示层
//Home.vue
<template>
<div class="home">
<h2>商品列表</h2>
<!--<select v-model="sort">
<option value="desc">从低到高</option>
<option value="asc">从高到低</option>
</select>-->
<select :value="sort" @change="geto">
<option value="desc">从低到高</option>
<option value="asc">从高到低</option>
</select>
<select :value="Id" @change="getoId">
<option value="0">id从低到高</option>
<option value="1">id从高到低</option>
</select>
<input type="text" v-model="msga" placeholder="id">
<input type="text" v-model="msgb" placeholder="name">
<input type="text" v-model="msgc" placeholder="price">
<button @click="add">添加</button>
<ul class="item-list">
<li>
<span>编号</span>
<span>名称</span>
<span>价格</span>
<span>操作</span>
</li>
<li v-for="item of items" :key="item.id">
<span>{{item.id}}</span>
<span>
<router-link :to="{name:'item',params:{'itemId':item.id}}"> {{item.name}}</router-link>
</span>
<span>
<router-link @mouseover.native="mouseover(item.id,$event)" @mouseout.native="mouseout(item.id,$event)" :to="{name:'item',params:{'itemId':item.id}}"> {{item.price | head}}</router-link>
</span>
<span><button @click="del(item)">删除</button></span>
</li>
</ul>
<div class="app" :style="{left:app.left,top:app.top}" v-if="app.isShow">
<Item :itemId="app.itemId"></Item>
</div>
</div>
</template>
<script>
import Item from './item'
export default {
name: 'Home',
data() {
return {
msga: '',
msgb: '',
msgc: '',
items: [],
sort: 'desc',
Id: 1,
basis: true,
app: {
itemId: 0,
isShow: false,
left: 0,
top: 0
}
}
},
components: {
Item,
},
created() {
this.getItems()
},
methods: {
mouseover(itemId, e) {
let pop = e.target.getBoundingClientRect();
this.app.itemId = itemId;
this.app.left = pop.left + pop.width + 10 + 'px';
this.app.top = pop.top + 'px';
this.app.isShow = true;
console.log(this.app);
},
mouseout(itemId, e) {
this.app.isShow = false
},
add() {
var reg = /\S/ig;
if (reg.test(this.msga) && reg.test(this.msgb) && reg.test(this.msg)) {
this.items.push({
id: this.msga,
name: this.msgb,
price: this.msgc,
})
} else {
alert('不能为空')
}
this.msga = ''
this.msgb = ''
this.msgc = ''
},
del(item) {
let index = this.items.indexOf(item);
this.items.splice(index, 1)
},
getItems() {
this.sort = this.$route.query.sort || this.sort;
this.axios({
url: '/api/items',
params: {
sort: this.sort,
id: this.Id,
basis: this.basis,
},
}).then(res => {
console.log(res);
this.items = res.data;
})
},
geto({
target: {
value
}
}) {
this.$router.push({
name: "Home",
query: {
sort: value
}
});
this.basis = true;
this.getItems();
},
getoId({
target: {
value
}
}) {
this.$router.push({
name: "Home",
query: {
id: value
}
});
this.Id = value;
this.basis = false;
this.getItems();
},
},
}
</script>
<style>
.item-list li {
list-style: none;
}
.item-list li span {
display: inline-block;
width: 22%;
font-size: 12px;
}
.app {
position: fixed;
left: 0;
top: 0;
border: 1px solid #000;
background: #fff;
padding: 10px;
}
</style>
因为原来的Item,vue组件是通过this.$route.params.itemId
来接收itemId
的,但是作为功能组件itemId
需要通过prop来传入,这个时候我们需要对Item.vue组件进行改造
<template>
<div class="item">
<template v-if="item">
<h2>商品详情--{{item.name}}</h2>
<h4>id:{{item.id}}</h4>
<h4>价格:{{item.price | head}}</h4>
</template>
<template v-else>
<h2>没有该商品信息</h2>
</template>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'item',
props: ['itemId'],
data() {
return {
item: [],
}
},
created() {
// 当一个视图,既是路由视图,又是功能组件的时候
// 我们传递参数需要两种方式 路由传参,组件通信
// vue-router 提供的props属性,可以将两个方式自动合并
// let itemId = Number(this.itemId || this.$route.params.itemId);
let itemId = this.itemId;
// console.log(this.itemId)
if (itemId) {
this.axios({
url: `/api/item/${itemId}`
}).then(res => {
this.item = res.data;
})
}
},
// 点击router-link=>修改url =>触发了路由守卫=>完成导航=>组件的生命周期
async beforeRouteEnter(to, from, next) {
// let itemId = Number(to.itemId || to.$route.params.itemId);
// let itemId = Number(to.itemId || to.$route.params.itemId);
let itemId = to.params.itemId;
// console.log(this.itemId)
if (itemId) {
try {
let res = await axios({
url: `/api/item/${itemId}`
});
next(vm => { // vm:组件实例
console.log(vm);
vm.item = res.data;
})
} catch (error) {
console.log(error)
}
}
}
}
</script>
但是这个时候,我们的Item.vue可以接收来自props的参数,却不可以处理来自路由的params参数。为了能让Item.vue既能接收props传递的参数
网友评论