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

发布于 2022-09-11 23:35:59 字数 267 浏览 35 评论 0

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

凉城已无爱 2022-09-18 23:36:00

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

美人如玉 2022-09-18 23:36:00

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

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

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

梦罢 2022-09-18 23:36:00

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

  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了。

寻找一个思念的角度 2022-09-18 23:36:00

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

终难遇 2022-09-18 23:36:00

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文