首页 > 其他分享 >Vue3 动态子页面和菜单栏同步

Vue3 动态子页面和菜单栏同步

时间:2024-09-04 15:14:16浏览次数:10  
标签:-- watch selectedKeys nbsp Vue3 import 菜单栏 ref 页面

动态子页面

<router-view></router-view>显示子页面的内容

main.vue
<template>
  <a-layout id="components-layout-demo-top-side">
    <the-header-view></the-header-view>
    <a-layout style="padding: 24px 0; background: #fff">
      <the-sider-view></the-sider-view>
      <a-layout-content :style="{ padding: '0 24px', minHeight: '280px' }">
<!--        <p>会员总数: {{ count }}</p>-->
<!--        <button @click="handleCount">Refresh Count</button>-->
        <router-view></router-view>
      </a-layout-content>
    </a-layout>
<!--    <a-layout-content style="padding: 0 50px">-->
<!--      <a-breadcrumb style="margin: 16px 0">-->
<!--        <a-breadcrumb-item>Home</a-breadcrumb-item>-->
<!--        <a-breadcrumb-item>List</a-breadcrumb-item>-->
<!--        <a-breadcrumb-item>App</a-breadcrumb-item>-->
<!--      </a-breadcrumb>-->
<!--      -->
<!--    </a-layout-content>-->
<!--    <a-layout-footer style="text-align: center">-->
<!--      Ant Design ©2018 Created by Ant UED-->
<!--    </a-layout-footer>-->
  </a-layout>
</template>

<script>
import { defineComponent } from 'vue';
import TheHeaderView from "@/components/the-header";
import TheSiderView from "@/components/the-sider";

export default defineComponent({
  components: {
    TheSiderView,
    TheHeaderView,
  },
  setup() {
    return {
    };
  },
});
</script>

<style>
#components-layout-demo-top-side .logo {
  float: left;
  width: 120px;
  height: 31px;
  margin: 16px 24px 16px 0;
  background: rgba(255, 255, 255, 0.3);
}

.ant-row-rtl #components-layout-demo-top-side .logo {
  float: right;
  margin: 16px 0 16px 24px;
}

.site-layout-background {
  background: #fff;
}
</style>

实现效果:
image
其中header和sider是先前封装的组件
router中显示的就是子页面http://localhost:9001/welcome的内容

给header和sider组件添加menu

menu
<a-menu-item key="/welcome">
        <router-link to="/welcome">
          <coffee-outlined /> &nbsp; 欢迎
        </router-link>
      </a-menu-item>
      <a-menu-item key="/passenger">
        <router-link to="/passenger">
          <user-outlined /> &nbsp; 乘车人管理
        </router-link>
      </a-menu-item>
header
<template>
  <a-layout-header class="header">
    <div class="logo" />
    <div style="float: right; color: white;">
      您好:{{member.mobile}} &nbsp;&nbsp;
      <router-link to="/login" style="color: white;">
        退出登录
      </router-link>
    </div>
    <a-menu
        v-model:selectedKeys="selectedKeys1"
        theme="dark"
        mode="horizontal"
        :style="{ lineHeight: '64px' }"
    >
      <a-menu-item key="/welcome">
        <router-link to="/welcome">
          <coffee-outlined /> &nbsp; 欢迎
        </router-link>
      </a-menu-item>
      <a-menu-item key="/passenger">
        <router-link to="/passenger">
          <user-outlined /> &nbsp; 乘车人管理
        </router-link>
      </a-menu-item>
    </a-menu>
<!--    <div>{{member.mobile}}</div>-->
  </a-layout-header>
</template>

<script>
import {defineComponent, ref} from 'vue';
import store from "@/store";


export default defineComponent({
  name: "the-header-view",
  setup() {
    let member = store.state.member;
    return {
      selectedKeys1: ref(['2']),
      member
    };
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

sider
<template>
  <a-layout-sider width="200" style="background: #fff">
    <a-menu
        v-model:selectedKeys="selectedKeys2"
        v-model:openKeys="openKeys"
        mode="inline"
        style="height: 100%"
    >
      <a-menu-item key="/welcome">
        <router-link to="/welcome">
          <coffee-outlined /> &nbsp; 欢迎
        </router-link>
      </a-menu-item>
      <a-menu-item key="/passenger">
        <router-link to="/passenger">
          <user-outlined /> &nbsp; 乘车人管理
        </router-link>
      </a-menu-item>
      <a-sub-menu key="sub1">
        <template #title>
                <span>
                  <user-outlined />
                  subnav 11
                </span>
        </template>

      </a-sub-menu>
      <a-sub-menu key="sub2">
        <template #title>
                <span>
                  <laptop-outlined />
                  subnav 2
                </span>
        </template>
        <a-menu-item key="5">option5</a-menu-item>
        <a-menu-item key="6">option6</a-menu-item>
        <a-menu-item key="7">option7</a-menu-item>
        <a-menu-item key="8">option8</a-menu-item>
      </a-sub-menu>
      <a-sub-menu key="sub3">
        <template #title>
                <span>
                  <notification-outlined />
                  subnav 3
                </span>
        </template>
        <a-menu-item key="9">option9</a-menu-item>
        <a-menu-item key="10">option10</a-menu-item>
        <a-menu-item key="11">option11</a-menu-item>
        <a-menu-item key="12">option12</a-menu-item>
      </a-sub-menu>
    </a-menu>
  </a-layout-sider>
</template>

<script>
import {defineComponent, ref} from 'vue';


export default defineComponent({
  name: "the-sider-view",
  setup() {

    return {
      selectedKeys2: ref(['1']),
      openKeys:ref(['sub1'])
    };
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

实现效果:
image
image
但是,这时的header和sider的菜单显示并不同步,还会出现菜单与内容不符的问题
image

为解决这个问题,在header和sider中分别编写watch,监视地址的router地址的变化

watch
const selectedKeys = ref([]);

    watch(() => router.currentRoute.value.path, (newValue) => {
      console.log('watch', newValue);
      selectedKeys.value = [];
      selectedKeys.value.push(newValue);
    }, {immediate: true});
header
<template>
  <a-layout-header class="header">
    <div class="logo" />
    <div style="float: right; color: white;">
      您好:{{member.mobile}} &nbsp;&nbsp;
      <router-link to="/login" style="color: white;">
        退出登录
      </router-link>
    </div>
    <a-menu
        v-model:selectedKeys="selectedKeys"
        theme="dark"
        mode="horizontal"
        :style="{ lineHeight: '64px' }"
    >
      <a-menu-item key="/welcome">
        <router-link to="/welcome">
          <coffee-outlined /> &nbsp; 欢迎
        </router-link>
      </a-menu-item>
      <a-menu-item key="/passenger">
        <router-link to="/passenger">
          <user-outlined /> &nbsp; 乘车人管理
        </router-link>
      </a-menu-item>
    </a-menu>
<!--    <div>{{member.mobile}}</div>-->
  </a-layout-header>
</template>

<script>
import {defineComponent, ref, watch} from 'vue';
import store from "@/store";
import router from "@/router";

export default defineComponent({
  name: "the-header-view",
  setup() {
    let member = store.state.member;
    const selectedKeys = ref([]);

    watch(() => router.currentRoute.value.path, (newValue) => {
      console.log('watch', newValue);
      selectedKeys.value = [];
      selectedKeys.value.push(newValue);
    }, {immediate: true});

    return {
      selectedKeys,
      member
    };
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

sider
<template>
  <a-layout-sider width="200" style="background: #fff">
    <a-menu
        v-model:selectedKeys="selectedKeys"
        v-model:openKeys="openKeys"
        mode="inline"
        style="height: 100%"
    >
      <a-menu-item key="/welcome">
        <router-link to="/welcome">
          <coffee-outlined /> &nbsp; 欢迎
        </router-link>
      </a-menu-item>
      <a-menu-item key="/passenger">
        <router-link to="/passenger">
          <user-outlined /> &nbsp; 乘车人管理
        </router-link>
      </a-menu-item>
      <a-sub-menu key="sub1">
        <template #title>
                <span>
                  <user-outlined />
                  subnav 11
                </span>
        </template>

      </a-sub-menu>
      <a-sub-menu key="sub2">
        <template #title>
                <span>
                  <laptop-outlined />
                  subnav 2
                </span>
        </template>
        <a-menu-item key="5">option5</a-menu-item>
        <a-menu-item key="6">option6</a-menu-item>
        <a-menu-item key="7">option7</a-menu-item>
        <a-menu-item key="8">option8</a-menu-item>
      </a-sub-menu>
      <a-sub-menu key="sub3">
        <template #title>
                <span>
                  <notification-outlined />
                  subnav 3
                </span>
        </template>
        <a-menu-item key="9">option9</a-menu-item>
        <a-menu-item key="10">option10</a-menu-item>
        <a-menu-item key="11">option11</a-menu-item>
        <a-menu-item key="12">option12</a-menu-item>
      </a-sub-menu>
    </a-menu>
  </a-layout-sider>
</template>

<script>
import {defineComponent, ref, watch} from 'vue';
import router from "@/router";


export default defineComponent({
  name: "the-sider-view",
  setup() {
    const selectedKeys = ref([]);

    watch(() => router.currentRoute.value.path, (newValue) => {
      console.log('watch', newValue);
      selectedKeys.value = [];
      selectedKeys.value.push(newValue);
    }, {immediate: true});

    return {
      selectedKeys,
      openKeys:ref(['welcome'])
    };
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

效果:
image
image

标签:--,watch,selectedKeys,nbsp,Vue3,import,菜单栏,ref,页面
From: https://www.cnblogs.com/yubaibaibubai/p/18396500

相关文章

  • pbootcms模板如何调用当前站点网址和当前页面网址
    在PbootCMS中,可以使用特定的标签来获取当前站点的网址和当前页面的URL。这对于需要使用网站路径前缀或者获取当前页面地址的场景非常有用。1.当前站点网址标签: {pboot:httpurl}功能:自适应获取当前访问的网址。2.当前页面标签: {pboot:pageurl}功能:获取当前访......
  • React18+TypeScript4+Vue3:‌入门到实战,‌灵活技术选型指南
    React18+TypeScript4+Vue3:‌入门到实战,‌灵活技术选型指南在当今的前端开发领域,‌React、‌TypeScript和Vue是三大热门技术,‌它们各自拥有独特的优势和广泛的应用场景。‌掌握这些技术,‌不仅能够提升你的开发效率,‌还能帮助你在不同项目中做出更加合适的技术选型。‌本文将带......
  • html+css+js网页设计 商城移动27个页面
    html+css+js网页设计商城移动27个页面网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode、Sublime、Webstorm、Text、Notepad++等任意html编辑软件进行运行及修改编辑等操作)。获取源码1,访问该网站https://download.csdn.net/download/qq_424......
  • html+css+js网页设计 翘珠宝微商城移动端20个页面
    html+css+js网页设计翘珠宝微商城移动端20个页面网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode、Sublime、Webstorm、Text、Notepad++等任意html编辑软件进行运行及修改编辑等操作)。获取源码1,访问该网站https://download.csdn.net/downl......
  • html+css+js网页设计 博物馆 亚历山大美术馆6个页面
    html+css+js网页设计博物馆亚历山大美术馆6个页面网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode、Sublime、Webstorm、Text、Notepad++等任意html编辑软件进行运行及修改编辑等操作)。获取源码1,访问该网站https://download.csdn.net/dow......
  • pbootcms模板如何输出当前页面的完整url地址
    在PbootCMS中,如果你需要在模板的内容页中调用当前页面的完整URL,可以结合使用 {pboot:httpurl} 和 {content:link} 来实现。这样可以确保生成的URL是完整的,并且包含了当前页面的路径。示例代码假设你需要在模板的内容页中调用当前页面的完整URL,可以使用以下代码:html......
  • vue3 地图(天地图,百度地图,腾讯地图,高德地图)封装组件调用 带地图搜索功能common_tencent
    废话不多说直接上组件代码:<template><!--地图--><divclass="containerw"><divid="map"class="mapradius-md":style="{width:width,height:height}"></div></div><......
  • 牛逼!Vue3.5的useTemplateRef让ref操作DOM更加丝滑
    前言vue3中想要访问DOM和子组件可以使用ref进行模版引用,但是这个ref有一些让人迷惑的地方。比如定义的ref变量到底是一个响应式数据还是DOM元素?还有template中ref属性的值明明是一个字符串,比如ref="inputEl",怎么就和script中同名的inputEl变量绑到一块了呢?所以Vue3.5推出了一个us......
  • 二开PHP泛目录生成源码 可生成新闻页面和关键词页面——码山侠
    PS本资源提供给大家学习及参考研究借鉴美工之用,请勿用于商业和非法用途,无任何技术支持!下载i5i.net泛目录可以用来提升网站收录和排名合理运用目录可以达到快速出词和出权重的效果程序小基本的服务器都带的得动 打开i5i.net——码山侠推荐二开为广告位丶增加页面跳转......
  • Vue3打造前台+中台通用开发提效解决方案-42种前台业务模型
    Vue3打造前台+中台通用开发提效解决方案:‌42种前台业务模型引言随着前端技术的飞速发展,‌Vue.js作为主流前端框架之一,‌凭借其易用性和高性能,‌在开发领域占据了一席之地。‌特别是Vue3的发布,‌带来了CompositionAPI、‌Teleport等新特性,‌进一步提升了开发效率和用户体验。‌......