剑轩

vue路由实现一个二级菜单。vue页面切换,vue子页面切换。vue菜单选中

电脑版发表于:2020/6/26 17:41

效果如下:

这种二级菜单或者三级菜单如果我们使用.net 的mvc来实现就很简单,整两个布局页可以轻松搞定来试试使用vue的路由实现其实也不难,就是一个熟练度问题。


创建一个news文件夹,然后创建一个新闻菜单下面的页面

我这里为了测试就创建两个即可

然后他们引用的组件就不在是最外层的那个Main.vue,而是News.vue,News.vue就可以理解成net mvc中的二级布局页。

<template>
    <NewsLayout>
        <p>我是军事新闻</p>
    </NewsLayout>
</template>

<script>
    //引用News.vue组件
    import NewsLayout from '../../pages/News.vue'

    export default {
        components: {
            NewsLayout
        }
    }
</script>

然后我们可以把各个新闻页面中不变的地方都放到News.vue中,我们这里也就是菜单嘛

<template>
  <Main-Layout>
      <div class="submenu">
        <ul>
          <li><SubVLink href="/news/itnews">技术新闻</SubVLink></li>
          <li><SubVLink href="/news/militarynews">军事新闻</SubVLink></li>
          <li><SubVLink href="#">娱乐新闻</SubVLink></li>  
        </ul>
     </div>   
    <div class="nwescontent">
      <slot></slot>
    </div> 
  </Main-Layout>
</template>

<script>
import MainLayout from "../layouts/Main.vue";
//二级菜单也需要引入一下链接的组件
import SubVLink from "../components/VLink.vue";

export default {
  components: {
    MainLayout,
    SubVLink
  },
  mounted:function(){
    //alert("加载完成");
  }
};

</script>

<style scoped>
  li {
    display: inline;
  }

  a{
    color: blue;
  }

  .submenu{
    margin-left: 10px;
  }
   
  .nwescontent{
     margin-left: 60px;
  }

</style>

因为二级菜单也用了链接的选中效果,所以在这里也需要引入一下链接的组件


还有一点就是二级菜单中,子页面需要填充的位置也是用<slot></slot>来决定的

所以我们可以看到我们有句

<div class="nwescontent">
  <slot></slot>
</div>

如果不写的话它是填充不到任何内容的,就相当于先在父组件挖一个坑,在由子组件去填这个坑,如果坑都没有自然也填不了。


然后把新添加的页面在routes.js中把路由配一下

export default {
  '/': 'Home',
  '/about': 'About',
  '/news': 'News',
  //配置一下新添加页面的路由
  '/news/itnews':"news/ITNews",
  '/news/militarynews':"news/MilitaryNews"
}

就可以实现二级菜单的切换效果了


最后说一下二级菜单的选中效果,两级菜单都变红的写法

如果那个链接组件不修改的话,他切换的时候只能一级变红,比如切换到技术新闻或军事新闻下面的时候一级菜单新闻是不会选中的。

哈哈哈,说到这里超级想用jquery来实现,因为jquery在熟悉了,实现这个功能完全是毫无压力不过居然用了vue还是用vue的思路来实现。

最开始链接组件VLink.vue中实现点击菜单变红的写法就是这样

判断一下当前路由和href属性即可。


现在我们改成如下即可同时选中满足条件的二级菜单

也就是多加了一种情况,如果是二级菜单的时候把地址栏取出来然后拆分来比较。当然这样可能不是太好理解,看看没有简写的情况

当然我觉得这样判断的写法并不友好,逻辑耦合度有点高。这里至少还有两种方案可以解决这个问题

1:在News.vue加载事件中使用vue的dom操作直接去给新闻添加一个样式(哈哈哈,典型的jquery思维)

2:重新写一个二级菜单的组件,让他们之间相互独立


好了好了,写到这里了该下班了



-----------------------------------------------2020-6-27更新-----------------------------------------------

我们把使用dom操作直接去给新闻添加一个样式这种做法说一下

要用dom操作需要在html中加一个ref属性方便我们对dom进行操作,在main.vue中添加一个ref="header"

<ul ref="header">
    <li>
    <v-link href="/">首页</v-link>
    <v-link href="/about">关于</v-link>
    <v-link href="/news/itnews">新闻</v-link>
    </li>
</ul>

然后在添加一个选中菜单的方法choiseMenu,传递一个下标可以选择一级菜单的:

  export default {
    components: {
      VLink
    },
    data() {
      return {
        data:"xj"
      }
    },
    methods: {
      //选中菜单的方法
      choiseMenu(index) {
         var aarrays = vuecontent.$refs.header.getElementsByTagName("a");
         aarrays[index].className="active";
      }
    }
  };

然后我们在二级布局页(哈哈哈.net mvc的叫法)也就是放新闻菜单的组件中加载的时候去调用一下choiseMenu这个方法即可

import MainLayout from "../layouts/Main.vue";
//二级菜单也需要引入一下连接的组件
import SubVLink from "../components/VLink.vue";

export default {
  components: {
    MainLayout,
    SubVLink
  },
  //加载事件中去做一个菜单选中
  mounted:function(){
    // MainLayout.methods.choiseMenu();
    this.$refs.myChild.choiseMenu();
  }
};

这里调用方法也借助了ref这个属性

当然可以使用引入组件的对象直接调用:MainLayout.methods.choiseMenu();

但是这样在main.vue的choiseMenu方法中的this就不能拿到当前的vue对象了,这样调用方法的话choiseMenu方法中的this就表示那个函数而不是vue对象了,所以我们使用ref这样的方式调用。


下面给一个demo例子,需要的可以看一下:

https://download.tnblog.net/resource/index/21ad97c6a3ac490381d52e39bdeeda39







关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢