路由组件传参

2020-11-04  本文已影响0人  lucky_yao

路由组件传参

我们通常把路由直接映射(绑定)的组件称为路由组件,也只有路由组件才能直接调用路由有关对象:$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传递的参数

上一篇 下一篇

猜你喜欢

热点阅读