美文网首页
路由组件传参

路由组件传参

作者: lucky_yao | 来源:发表于2020-11-04 08:32 被阅读0次

    路由组件传参

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

    相关文章

      网友评论

          本文标题:路由组件传参

          本文链接:https://www.haomeiwen.com/subject/blbnuktx.html