《vue-router》

324 阅读3分钟

当前需求:在Labels.vue页面里,有许多标签,点进每一个标签,应该会跳转到一个可以编辑标签的页面,EditLabel.vue

做法

1.

首先,我们应该在router/index.ts里再添加一个路由

{
      path:'/labels/edit',
      component:EditLabel
},

因为Labels页面的path是'/labels',编辑标签的页面应该是标签页面的子页面,所以路径在/labels后边加。

如果写的路径是'/label/edit'之类的和labels路径无关的,观察到编辑标签的页面下方的标签图标没有高亮。这样就体现不出它是由标签页面跳转过来的关系了。

添加完路由后,再创建相应的组件:EditLabel.vue

2. 添加标签id

可是我怎么知道编辑的是哪个标签呢?因为以前我们保存在localStorage里的TagList是一个字符串数组,只有标签的名字。我们需要知道每个标签的id,才能获取id。

但是id一般是由数据库分配的,我们现在没有数据库。不过创建标签时我们设定了标签名name不能重复,所以每个标签是独特的。所以我们先把标签名当成id。把每个标签的存储形式改成一个对象,{id:'衣服',name:'衣服'},如果后边有了数据库,就把id改了。

3.

标签有了id后,我们怎么在EditLabel.vue页面获取id呢?

首先在路由里把之前的path在后边再添加一个/,

{
      path:'/labels/edit/:id',
      component:EditLabel
},

:id 表示我这里会有一个字符串,但是现在是什么还不知道,所以我只能先占位。

接下来,EditLabel.vue页面怎么知道路径edit后边的字符串是什么呢?

在vue router文档里的数据获取功能里,有一个$route.params.id,this.$route可以获取这个路由的所有信息。它一般放在钩子函数里。

EditLabel.vue的ts里:

export default class EditLabel extends Vue {
        created(){
            console.log(this.$route.params);
        }
    }

把它打印出来,发现是一个对象{id:2}

如果我把path改成:path:'/labels/edit/:xxx',,也就是把id改成xxx,发现打印出来的是{xxx:2}。所以,:后边的就是一个名字,如图所示,我访问的路径是/edit/2,所以打印出来的对象就是key为xxx,value为2.

所以,通过this.$route.params.id就能在编辑标签页面里拿到路径edit/后边的名字。然后就可以从localStorage里的tagList中找到是哪个标签(找到id能对上的)。

export default class EditLabel extends Vue {
        created(){
            const id=this.$route.params.id   //拿到当前路径edit/后边的东西
            tagListModel.fetch()
            const tags=tagListModel.data
            const tag=tags.filter(tag=>tag.id===id)[0]  //找到对应id的标签
            if(tag){
                console.log(tag);
            }else{
                this.$router.replace('/404')
            }
        }
}

此前我们先创建一个衣服标签。如果访问了http://localhost:8080/#/labels/edit/衣服,因为衣服这个标签是存在的,所以会打印出:

如果我访问了不存在的标签id,如:/edit/零食,就重定向到404页面。this.$router.replace返回一次就能返回到上次页面。如果使用.push方法,就一直回不去。因为路径错了就又重定向到404页面。

4. 把Labels.vueEditLabel.vue联系起来

现在我们只实现了自己手动输入路径,EditLabel.vue里能拿到路由信息里的id,并且从标签列表里根据id找到对应的tag。

可是我们应该让用户从Labels页面里点击一个标签,再跳转到相应的编辑标签页面。

原来Labels页面里的标签是用li元素实现的。我们想用<router-link>元素,这样才能实现点击,就跳转。通过to属性指定跳转到哪个页面的路由。

<template>
   <Layout>
       <div class="tags">
           <router-link class="tag" v-for="tag in tags" :key="tag.id"
           :to=" `/labels/edit/${tag.id}` ">
               <span>{{tag.name}}</span>
               <Icon name="right"/>
           </router-link>

       </div>
       <div class="button-wrapper"><button class="create" @click="createTag">新建标签</button></div>

   </Layout>
</template>

所以我们把li改成router-link。根据tag.id导向不同的路径。

和前边的联系起来,在路由文件里通过/edit/:id 先占位,用户在标签页面里点击了某个标签后,通过to,字符串id就拿到了tag.id,比如衣服,房租。然后跳转到EditLabel.vue页面后,在里边通过this.$route.params.id拿到tag.id,也就是从哪个标签上跳转过来的。然后拿着这个id去localStorage里的tagList里找一样id的tag。 我们就在编辑标签组件里拿到了要编辑的标签。