导航栏总结

这次所做的导航栏是为了练习components(组件)layout(布局)responsive(响应式)下拉框(collapse)

导航栏的特点是:根据导航数据结构渲染,三层目录不定量选项卡,web端与mobile端自适应变化,mobile端导航栏特殊设计。

重点学习的技术包含:组件获取数据的方法和不定项的渲染方法,响应式布局动画设计手风琴导航栏

组件数据获取和渲染

  • 组件数据获取

目前项目broading阶段,使用的数据是与后端沟通后的mock数据。组件获取数据的方法是创建时fetch获取,利用cms提供的获取方法,返回具体的Navigation数据。

  async fetch(): Promise<void> {
    this.navigationList = (await getNavigations()).data
  },
  • 内层组件数据获取

在需要不定项获取时,利用v-for中传入列表数据来实现。通常列表中需要重新定义格式时,就在每一行li中加入一个代入数据的新的组件。

<ul class="navbar-nav">
   <li v-for="item in navigationList.navigation" :key="item.id" class="alert-second-nav pl-5 nav-item active">
        <a :href="item.link.href" class="nav-link text-black-50">{{ item.link.label }}</a>
        <DropDown class="second-nav border-top border-bottom border-dark-50" :data="item.sections" />
        <div class="mask-bg w-100 h-100 m-0 p-0"></div>
    </li>
</ul>

其中DropDown就是新组件用于接收数据。

具体的接收方法为:

props: {
    data: {
      type: Array as PropType<NaviSectionEntity[]>,
      default(): NaviSectionEntity[] {
        return [] as NaviSectionEntity[]
      },
    },
  },
  • 数据渲染

数据得到后的渲染中主要就是直接使用$props原型数据。

特殊的需要注意,区分data数据与$props.data的区别。data数据可以方便的随时更改再获取,但原型不能更改。

响应式布局

这里说到的响应式主要是web端和mobile端的区别。

响应式最重要的几个内容是1.不同端的具体布局2.屏幕大小的监听3.不同端内容的控制。

  • 屏幕大小的监听
mounted() {
    window.onresize = () => {
      // 监听屏幕变化
      this.page_width()
    }
    this.page_width()
  }

监听后对屏幕大小做一个规定,判定mobile端与web端的屏幕大小分界,根据分解转化为一个bool值。

page_width() {
      // 获取屏幕宽度
      const screenWidth = document.body.clientWidth
      this.fullWidth = screenWidth >= 1000
    }
  • 内容显示的控制

在不同端的布局上都加上v-show这个标签属性,该属性用于控制这个标签的内容是否显示。用屏幕的bool值来控制内容是否显示。

<div v-show="fullWidth" id="navbarSupportedContent" class="collapse navbar-collapse">
  <ul class="navbar-nav">
  </ul>
</div>

特殊的:项目中移动端还会出现点击出现或显示的功能。

<div v-show="!fullWidth && !disMenu" class="collapse navbar-collapse mobile-menu-open">
        <ul class="navbar-nav">
  </ul>
</div>

动画设计

项目中暂时用到的动画设计只有从右边划入,向右边划出这种。

设计方案就是针对需要使用动画的div外包裹一层transition标签。

<transition name="mobile-menu-slide-fade">
  <div>
  </div>
</transition>

具体设计这个动画transition时,即在style中对该nameenter,leave属性进行修改。

.mobile-menu-slide-fade-enter-active {
  transition: all 0.5s ease;
}

.mobile-menu-slide-fade-leave-active {
  transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}

.mobile-menu-slide-fade-enter,
.mobile-menu-slide-fade-leave-to {
  transform: translateX(300px);
  opacity: 0;
}

手风琴导航栏

手风琴指的是列表中点击一行时,行内的下级列表内容全部显示,此时点击另一行时,会把之前全部内容隐藏,显示当前行下的下级列表内容。

项目中用到的手风琴导航栏主要是在移动端的第二层菜单时,希望不再继续往下跳转。

具体实现时的难点是:数据的传递和显示与隐藏的控制。

数据传递和控制上需要注意的是v-for是可以获得index值的,通过index的值可以完成对具体某一行内容的操作与获取。

具体的控制方法有两种实现:

  1. 对每一项数据内容中加入一个是否显示的字段,该字段中保证在一组同级数据下仅有一个true,代表为显示,每次点击事件发生时都会判断全部内容下的该字段,保证字段准确性。
  2. 在全局data中添加一个showIndex字段,初始值为-1,用于记录当前可以显示的某行,如果为-1则为都不显示。每次点击事件发生时都对showIndex字段进行更新。

本项目因为原数据已经确定,所以使用的第二种实现方法。

<template>
  <div>
    <ul class="list-unstyled">
      <li v-for="(item, index) in $props.data" :key="item.id" :class="[{ active: isShowing(index) }]">
        <div class="nav-link text-black-50">
          <p class="mb-0" @click="changeShowingIndex(index)">{{ item.title }}</p>
        </div>
        <ul v-show="isShowing(index)" class="list-unstyled pl-3">
          <li v-for="subItem in item.links" :key="subItem.id">
            <div class="nav-link text-black-50">
              <p class="mb-0">{{ subItem.label }}</p>
            </div>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue'
import { NaviSectionEntity } from '~/apis/cms'

type NaviData = {
  showingIndex: number
}

export default Vue.extend({
  name: 'MobileSecondNavi',
  props: {
    data: {
      type: Array as PropType<NaviSectionEntity[]>,
      default(): NaviSectionEntity[] {
        return [] as NaviSectionEntity[]
      },
    },
  },
  data(): NaviData {
    return {
      showingIndex: -1,
    }
  },
  methods: {
    changeShowingIndex(index) {
      if (this.showingIndex === index) {
        this.showingIndex = -1
      } else {
        this.showingIndex = index
      }
    },
    isShowing(index) {
      return this.showingIndex === index
    },
  },
})
</script>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容