vue怎么在一个单页面中实现多开功能,类似浏览器打开网页一样的页签功能?

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>),好了下面开始说正事:


图1.png图2.png图3.png图4.png图5.png

###

可以参照iviewUI中的 tags-nav.vue 文件 以及使用方法

###

iview-admin 封装了这个组件,叫 tag-nav

你也可以单纯的基于 iview / element-ui 的 tabs 组件来做封装,通过其 closable 属性来控制。

至于怎么和 vue-router 配合,那就是你自己业务上的事儿了。

###

说下我的理解,我把这个东西当作浏览历史,那么我们要做的就有如下几点

  1. 监听$route对象,每次进新路由,把路由的必要属性包括路由地址,参数等作为一个记录 push到数组中,记作history
  2. 在顶部v-for遍历history
  3. 给每个item分别绑定点击以及点击关闭事件,传入当前路由.单击事件,即路由跳转,直接$router.push即可,关闭的话就是先去history里删除这条记录,随即跳转到上一个(index-1)路由位置。

伪代码如下:

<template>
    <div class="history">
        <div class="item" 
             :class="{active:$route.path === his.path}"
             v-for="his in history" :key="his.path" 
             @click.stop="goHistory(his)">
                  <span>{{his.title}}</span>
          <img src="../assets/img/close.png" title="关闭" @click.stop="delHistory(his)">
        </div>
    </div>
</template>
<script>
//history存在vuex中,
import {mapMutations, mapState} from 'vuex';
export default {  
    watch: {
        $route() {
            this.rememberHistory();
        },
    },
    computed: {
        // 取出history
        ...mapState(['history']),
    },
    methods: {
        // 拿到mutation其实就是state.history = history;
        ...mapMutations(['SET_HISTORY']), 
        rememberHistory() {
            // 从路由实例中取出必要的信息
            let route = this.$route;
            let {meta: {title}, path, query, name} = route;
            if (name === 'notFound') return;          
            let history = this.$store.state.history;
            // 历史记录,如果大于7个,移除第一个,这个根据你的需求来
            if (history.length > 7) {
                history.shift();
            }
            
            let index = history.findIndex(item => item.path === path);
            // 如果查询到已存在的历史记录
            if (index > -1) {
                // 替换原来的
                history[index] = {title, path, query};
            } else {
                // 否则新增一个
                history = [
                    ...history,
                    {title, path, query},
                ];
            }
            // 更新到vuex中
            this.SET_HISTORY(history);

        },
        // 删除某条历史记录
        delHistory({path}) {
            // 取出历史记录
            let history = [...this.history];
            // 获取当前要删除得index
            let index = history.findIndex(item => item.path === path);
            let currentPathIndex = history.findIndex(item => item.path === this.$route.path);

            //如果删除得记录是当前页面
            if (currentPathIndex === index) {
                let nextPath = null;
                //如果是小于,则向下一个路由跳转
                if (index < history.length - 1) {
                    nextPath = history[index + 1];
                } else {
                    // 如果大于,就跳转上一个
                    nextPath = history[index - 1];
                }
                // 如果是最后一个,返回首页
                if (history.length === 1) {
                    nextPath = {path: '/'};
                }
                //跳转路由
                this.goHistory(nextPath);
            }

            // 删除
            history.splice(index, 1);
            // commit mutations  更新到vuex中
            this.SET_HISTORY(history);

        },
        // 跳转到某个历史记录
        goHistory({path, query}) {
            this.$router.push({path, query});
        }
        
};
</script>

vuex伪代码

state: {
        // 访问历史记录
        history: [],     
    },
    mutations: {
        SET_HISTORY(state, history) {
            state.history = history;
        },
    },
可能你发现了一个问题,就是切换的时候路由重新加载了,那么这个问题你就得在router-view上使用keep-alive了。
###

熟悉的风格,是用了 vue-element-admin 吧,官方提供的demo和api文档中有相关介绍啊
https://panjiachen.github.io/...
https://panjiachen.github.io/...

###

想问一下 解决了吗 这个问题

郑重声明:本站部分内容转载自网络,版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们(QQ/微信153890879)修改或删除,多谢。