<!-- 高级布局 license by http://eleadmin.com -->
<template>
  <div :class="layoutClass">
    <!-- 顶栏 -->
    <ele-pro-header
      :levels="levelData"
      :use-deep="useDeep"
      :collapse="collapse"
      :menus="headMenuData"
      :head-style="headStyle"
      :active="headMenuActive"
      :project-name="projectName"
      :show-refresh="showRefresh"
      :show-left-tool="showHeadLeftTool"
      :breadcrumb-separator="breadcrumbSeparator"
      :show-collapse="showCollapse && showSideMenu"
      :show-breadcrumb="showBreadcrumb && layoutStyle === 'side'"
      @toggle-collapse="toggleCollapse"
      @reload-page="reloadPage"
      @logo-click="onLogoClick">
      <template #logo>
        <slot name="logo"/>
      </template>
      <template #left>
        <slot name="left"/>
      </template>
      <template #center>
        <slot name="center"/>
      </template>
      <template #right>
        <slot name="right"/>
      </template>
    </ele-pro-header>
    <div class="ele-admin-main">
      <!-- 侧栏一级导航 -->
      <ele-pro-sidebar-nav
        v-if="showSideNav"
        :data="sideNavData"
        :use-deep="useDeep"
        :theme="sideNavTheme"
        :collapse="navIsCollapse"
        :menu-collapse="collapse"
        :inline-indent="inlineIndent"
        :show-nav-collapse="showNavCollapse"
        :active="collapse ? sideMenuActive : sideNavActive"
        @toggle-collapse="toggleNavCollapse">
        <template #top>
          <slot name="nav-top"/>
        </template>
        <template #bottom>
          <slot name="nav-bottom"/>
        </template>
      </ele-pro-sidebar-nav>
      <!-- 侧栏 -->
      <ele-pro-sidebar
        v-if="showSideMenu"
        :use-deep="useDeep"
        :data="sideMenuData"
        :theme="sideMenuTheme"
        :active="sideMenuActive"
        :menu-opens="sideMenuOpen"
        :collapse="sideMenuCollapse"
        :unique-open="sideUniqueOpen"
        :inline-indent="inlineIndent">
        <template #top>
          <slot name="top"/>
        </template>
        <template #bottom>
          <slot name="bottom"/>
        </template>
      </ele-pro-sidebar>
      <!-- 主体 -->
      <div class="ele-admin-body">
        <!-- 多页签 -->
        <ele-pro-tabs
          v-if="showTabs"
          :tabs="tabData"
          :active="tabActive"
          :click-reload="clickReload"
          :home-title="homeRouteTitle"
          :show-refresh="showTabRefresh"
          :body-fullscreen="bodyFullscreen"
          @tab-change="tabChange"
          @tab-remove="tabRemove"
          @tab-remove-all="tabRemoveAll"
          @tab-remove-left="tabRemoveLeft"
          @tab-remove-right="tabRemoveRight"
          @tab-remove-other="tabRemoveOther"
          @fullscreen-body="toggleBodyFullscreen"
          @reload-page="reloadPage">
          <template #dropdown>
            <slot name="dropdown"/>
          </template>
        </ele-pro-tabs>
        <!-- 内容区域 -->
        <div class="ele-admin-content">
          <div v-if="showContent" class="ele-admin-content-view">
            <slot name="content">
              <ele-empty-layout/>
            </slot>
          </div>
          <template v-if="showContent && showFooter && !hideFooter">
            <slot name="footer"/>
          </template>
        </div>
      </div>
    </div>
    <!-- 小屏幕遮罩层 -->
    <div class="ele-admin-shade" @click="toggleCollapse"></div>
    <!-- 自定义内容 -->
    <slot/>
    <!-- 返回顶部 -->
    <a-back-top
      v-if="showBackTop && !fixedBody"
      :visibility-height="backTopVisibilityHeight"/>
    <a-back-top
      v-else-if="showBackTop"
      :target="getContentElem"
      :visibility-height="backTopVisibilityHeight"/>
    <!-- 主题设置抽屉 -->
    <ele-pro-setting
      v-if="needSetting"
      :tips="tips"
      :color="color"
      :themes="themes"
      :dark-mode="darkMode"
      :weak-mode="weakMode"
      :show-tabs="showTabs"
      :tab-style="tabStyle"
      :body-full="bodyFull"
      :visible="showSetting"
      :head-style="headStyle"
      :side-style="sideStyle"
      :fixed-body="fixedBody"
      :show-footer="showFooter"
      :color-picker="colorPicker"
      :fixed-header="fixedHeader"
      :layout-style="layoutStyle"
      :fixed-sidebar="fixedSidebar"
      :colorful-icon="colorfulIcon"
      :logo-auto-size="logoAutoSize"
      :side-menu-style="sideMenuStyle"
      :side-unique-open="sideUniqueOpen"
      :predefine-colors="predefineColors"
      @change-style="changeStyle"
      @change-color="changeColor"
      @change-dark-mode="changeDarkMode"
      @change-weak-mode="changeWeakMode"
      @update:visible="updateShowSetting"/>
  </div>
</template>

<script>
import debounce from 'lodash-es/debounce';
import EleProHeader from '../../ele-pro-header';
import EleProSidebar from '../../ele-pro-sidebar';
import EleProSidebarNav from '../../ele-pro-sidebar-nav';
import EleProTabs from '../../ele-pro-tabs';
import EleProSetting from '../../ele-pro-setting';
import EleEmptyLayout from '../../ele-empty-layout';
import {eachTreeData, formatTreeData} from '../../util.js';
// 用于刷新路由的path
const REDIRECT_PATH = '/redirect/';
// 默认主页标题
const DEFAULT_HOME_TITLE = '主页';

export default {
  name: 'EleProLayout',
  components: {
    EleProHeader,
    EleProSidebar,
    EleProSidebarNav,
    EleProTabs,
    EleProSetting,
    EleEmptyLayout
  },
  emits: [
    'logo-click',
    'reload-page',
    'update-screen',
    'update-collapse',
    'tab-add',
    'tab-remove',
    'tab-remove-all',
    'tab-remove-left',
    'tab-remove-right',
    'tab-remove-other',
    'change-color',
    'change-style',
    'change-dark-mode',
    'change-weak-mode',
    'set-home-components',
    'body-fullscreen-change',
    'update:side-nav-collapse',
    'update:show-setting'
  ],
  props: {
    // 全部菜单数据
    menus: {
      type: Array,
      default() {
        return [];
      }
    },
    // 标签页数据
    tabs: {
      type: Array,
      default() {
        return [];
      }
    },
    // 项目名
    projectName: String,
    // 主页标题
    homeTitle: String,
    // 是否显示侧栏折叠按钮
    showCollapse: {
      type: Boolean,
      default: true
    },
    // 是否显示一级侧栏折叠按钮
    showNavCollapse: {
      type: Boolean,
      default: true
    },
    // 是否显示刷新按钮
    showRefresh: {
      type: Boolean,
      default: true
    },
    // 是否显示面包屑导航
    showBreadcrumb: {
      type: Boolean,
      default: true
    },
    // 面包屑导航分隔符
    breadcrumbSeparator: {
      type: String,
      default: '/'
    },
    // 是否折叠侧栏
    collapse: {
      type: Boolean,
      default: false
    },
    // 是否折叠侧栏一级菜单
    sideNavCollapse: {
      type: Boolean,
      default: false
    },
    // 顶栏风格, light | dark
    headStyle: {
      type: String,
      default: 'light'
    },
    // 侧边栏风格, light | dark
    sideStyle: {
      type: String,
      default: 'dark'
    },
    // 布局风格, default | top | mix
    layoutStyle: {
      type: String,
      default: 'default'
    },
    // 侧边栏菜单模式, default | mix
    sideMenuStyle: {
      type: String,
      default: 'default'
    },
    // 是否固定顶栏
    fixedHeader: {
      type: Boolean,
      default: false
    },
    // 是否固定侧栏
    fixedSidebar: {
      type: Boolean,
      default: true
    },
    // 是否固定主体
    fixedBody: {
      type: Boolean,
      default: false
    },
    // 内容区域宽度是否铺满
    bodyFull: {
      type: Boolean,
      default: true
    },
    // logo宽度是否自适应
    logoAutoSize: Boolean,
    // 是否显示全局页脚
    showFooter: Boolean,
    // 侧栏菜单是否彩色图标
    colorfulIcon: Boolean,
    // 侧栏是否只保持一个子菜单展开
    sideUniqueOpen: {
      type: Boolean,
      default: true
    },
    // 是否开启多页签
    showTabs: {
      type: Boolean,
      default: true
    },
    // 标签页风格, default | dot | card
    tabStyle: {
      type: String,
      default: 'dot'
    },
    // 是否色弱模式
    weakMode: Boolean,
    // 是否暗黑模式
    darkMode: Boolean,
    // 当前主题色
    color: String,
    // 是否需要主题设置抽屉
    needSetting: {
      type: Boolean,
      default: true
    },
    // 是否打开主题设置抽屉, 支持v-model绑定
    showSetting: Boolean,
    // 主题设置抽屉界面显示的主题列表
    themes: {
      type: Array,
      default() {
        return [];
      }
    },
    // 主题设置抽屉界面提示文字
    tips: {
      type: String,
      default: ''
    },
    // 主题设置抽屉是否显示颜色选择器
    colorPicker: {
      type: Boolean,
      default: true
    },
    // 主题设置抽屉颜色选择器预设颜色
    predefineColors: {
      type: Array,
      default() {
        return [
          '#f5222d',
          '#fa541c',
          '#fa8c16',
          '#faad14',
          '#a0d911',
          '#52c41a',
          '#13c2c2',
          '#2f54eb',
          '#722ed1',
          '#eb2f96'
        ];
      }
    },
    // 内容区域全屏时是否不显示页签栏
    contentFullscreen: {
      type: Boolean,
      default: false
    },
    // 是否按返回键退出内容区域全屏
    fullscreenExitOnEsc: {
      type: Boolean,
      default: false
    },
    // 是否显示主体部分
    showContent: {
      type: Boolean,
      default: true
    },
    // 是否再次点击选中页签刷新
    clickReload: Boolean,
    // 开启多页签是否缓存组件
    tabKeepAlive: {
      type: Boolean,
      default: true
    },
    // 菜单缩进
    inlineIndent: {
      type: Number,
      default: 16
    },
    // 是否需要返回顶部组件
    showBackTop: {
      type: Boolean,
      default: true
    },
    // 返回顶部的滚动高度
    backTopVisibilityHeight: {
      type: Number,
      default: 200
    },
    // 不显示全局页脚的路由
    hideFooters: Array,
    // 不显示侧边栏的路由
    hideSidebars: Array,
    // 可重复打开页签的路由地址
    repeatableTabs: Array,
    // 是否使用递归渲染菜单
    useDeep: Boolean,
    // 自定义菜单标题的i18n
    i18n: Function
  },
  data() {
    return {
      // 国际化处理后的菜单数据
      menuData: [],
      // 国际化处理后的多页签数据
      tabData: [],
      // 面包屑导航数据
      levelData: [],
      // 侧栏一级菜单数据
      sideNavData: [],
      // 侧栏一级菜单选中
      sideNavActive: [],
      // 侧栏菜单数据
      sideMenuData: [],
      // 侧栏菜单选中
      sideMenuActive: [],
      // 侧栏菜单展开
      sideMenuOpen: [],
      // 顶栏菜单数据
      headMenuData: [],
      // 顶栏菜单选中
      headMenuActive: [],
      // 多页签选中
      tabActive: '/',
      // 当前路由是否隐藏侧栏
      hideSidebar: false,
      // 当前路由是否隐藏页脚
      hideFooter: false,
      // 是否全屏内容区域
      bodyFullscreen: false,
      // 主页路由标题
      homeRouteTitle: this.homeTitle || DEFAULT_HOME_TITLE,
      // 是否折叠一级菜单
      navIsCollapse: this.sideNavCollapse,
      // 内容区域元素
      contentElem: '.ele-admin-layout>.ele-admin-main>.ele-admin-body>.ele-admin-content',
      // 当前屏幕宽度
      screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
      // 窗口大小改变监听器
      onResizeListener: debounce(() => {
        this.updateScreen();
      }, 300)
    };
  },
  computed: {
    // 布局class
    layoutClass() {
      const showSidebar = this.showSideNav || this.showSideMenu;
      return [
        'ele-admin-layout',
        // 折叠侧边栏
        {'ele-admin-collapse': this.collapse},
        // 固定顶栏
        {'ele-admin-fixed-header': this.fixedHeader},
        // 固定侧边栏
        {'ele-admin-fixed-sidebar': this.fixedSidebar && !this.isTopMenu && showSidebar},
        // 固定主体
        {'ele-admin-fixed-body': this.fixedBody},
        // 暗色顶栏
        {'ele-admin-head-dark': this.headStyle !== 'light'},
        // 暗色侧边栏
        {'ele-admin-side-dark': this.sideStyle === 'dark'},
        // 侧边栏双排菜单
        {'ele-admin-side-mix': this.isMixSideMenu && !this.isMobile},
        // 侧边栏彩色图标
        {'ele-admin-side-colorful': this.colorfulIcon},
        // logo宽度自适应
        {'ele-admin-logo-auto': (this.logoAutoSize || this.isTopMenu || !showSidebar) && !this.isMobile},
        // 开启多页签
        {'ele-admin-show-tabs': this.showTabs},
        // 圆点风格页签
        {'ele-admin-tab-dot': this.tabStyle === 'dot'},
        // 卡片风格页签
        {'ele-admin-tab-card': this.tabStyle === 'card'},
        // 主体内容定宽
        {'ele-admin-body-limit': !this.bodyFull},
        // 内容区域全屏
        {'ele-admin-body-fullscreen': this.bodyFullscreen},
        // 内容区域全屏不显示页签栏
        {'ele-admin-content-fullscreen': this.bodyFullscreen && this.contentFullscreen},
        // 侧栏双排菜单布局时折叠一级菜单
        {'ele-admin-nav-collapse': this.navIsCollapse && !this.isMobile}
      ]
    },
    // 是否是移动端小屏幕
    isMobile() {
      return this.screenWidth < 768;
    },
    // 是否折叠侧栏菜单
    sideMenuCollapse() {
      return (this.isMobile || this.isMixSideMenu) ? false : this.collapse;
    },
    // 侧栏一级菜单主题
    sideNavTheme() {
      return this.sideStyle === 'dark' ? 'dark' : 'light';
    },
    // 侧栏菜单主题
    sideMenuTheme() {
      return (this.isMixSideMenu && !this.isMobile) ? 'light' : this.sideNavTheme;
    },
    // 是否显示顶栏左侧功能区
    showHeadLeftTool() {
      return this.isMobile || !this.isTopMenu;
    },
    // 是否显示侧栏一级菜单
    showSideNav() {
      return !(
        !this.isMixSideMenu ||
        this.isMobile ||
        this.isTopMenu ||
        (this.sideNavData.length === 0 && this.menuData.length !== 0) ||
        this.hideSidebar
      );
    },
    // 是否显示侧栏菜单
    showSideMenu() {
      return this.isMobile ? true : !(
        this.isTopMenu ||
        (this.sideMenuData.length === 0 && this.menuData.length !== 0) ||
        this.hideSidebar
      );
    },
    // 是否是栏菜单布局
    isTopMenu() {
      return this.layoutStyle === 'top';
    },
    // 是否是混合菜单布局
    isMixMenu() {
      return this.layoutStyle === 'mix';
    },
    // 是否是双栏菜单侧栏
    isMixSideMenu() {
      return this.sideMenuStyle === 'mix';
    },
    // 页签栏右侧下拉是否显示刷新按钮
    showTabRefresh() {
      return this.bodyFullscreen || (this.isTopMenu && !this.isMobile);
    }
  },
  created() {
    this.changeLanguage();
    const current = this.$route;
    if (current) {
      this.onRouteChange(current);
    }
    // 监听浏览器窗口大小改变
    window.addEventListener('resize', this.onResizeListener);
    window.addEventListener('keydown', this.onKeydownListener);
  },
  methods: {
    /* 折叠展开侧栏 */
    toggleCollapse() {
      this.updateCollapse(!this.collapse);
    },
    /* 更新侧栏折叠状态 */
    updateCollapse(value) {
      this.$emit('update-collapse', value);
    },
    /* 折叠展开一级菜单 */
    toggleNavCollapse() {
      this.navIsCollapse = !this.navIsCollapse;
      this.$emit('update:side-nav-collapse', this.navIsCollapse);
    },
    /* logo点击事件 */
    onLogoClick() {
      this.$emit('logo-click', this.isHome(this.$route));
    },
    /* 刷新页面 */
    reloadPage() {
      this.$emit('reload-page');
    },
    /* 内容区域全屏切换 */
    toggleBodyFullscreen() {
      this.bodyFullscreen = !this.bodyFullscreen;
      this.$emit('body-fullscreen-change', this.bodyFullscreen);
    },
    /* 键盘事件监听 */
    onKeydownListener(event) {
      if (event.keyCode === 27) {
        if (this.fullscreenExitOnEsc && this.bodyFullscreen) {
          this.bodyFullscreen = false;
          event.stopPropagation();
        }
      }
    },
    /* 更新屏幕尺寸 */
    updateScreen() {
      this.screenWidth = document.documentElement.clientWidth || document.body.clientWidth;
      const screenHeight = document.documentElement.clientHeight || document.body.clientHeight;
      this.$emit('update-screen', {width: this.screenWidth, height: screenHeight});
    },
    /* tab切换 */
    tabChange({fullPath, key}) {
      this.$router.push(fullPath || key);
    },
    /* 移除tab */
    tabRemove(value) {
      this.$emit('tab-remove', value);
    },
    /* 移除左边tab */
    tabRemoveLeft(value) {
      this.$emit('tab-remove-left', value);
    },
    /* 移除右边tab */
    tabRemoveRight(value) {
      this.$emit('tab-remove-right', value);
    },
    /* 移除其它tab */
    tabRemoveOther(value) {
      this.$emit('tab-remove-other', value);
    },
    /* 移除全部tab */
    tabRemoveAll(active) {
      this.$emit('tab-remove-all', active);
    },
    /* 切换布局配置 */
    changeStyle(value) {
      this.$emit('change-style', value);
    },
    /* 切换主题色 */
    changeColor(value) {
      this.$emit('change-color', value);
    },
    /* 切换暗黑模式 */
    changeDarkMode(value) {
      this.$emit('change-dark-mode', value);
    },
    /* 切换色弱模式 */
    changeWeakMode(value) {
      this.$emit('change-weak-mode', value);
    },
    /* 设置主页的组件用于keep-alive */
    setHomeComponents(components) {
      this.$emit('set-home-components', components);
    },
    /* 修改设置抽屉的visible */
    updateShowSetting(value) {
      this.$emit('update:show-setting', value);
    },
    /* 处理路由切换 */
    onRouteChange(current) {
      const {meta, matched, path, fullPath} = current;
      if (path.startsWith(REDIRECT_PATH)) {
        return;
      }

      // 判断是否需要隐藏侧栏
      if (this.hideSidebars && this.hideSidebars.includes(current.path)) {
        this.hideSidebar = true;
      } else {
        this.hideSidebar = meta.hideSidebar;
      }

      // 判断是否需要隐藏页脚
      if (this.hideFooters && this.hideFooters.includes(current.path)) {
        this.hideFooter = true;
      } else {
        this.hideFooter = meta.hideFooter;
      }

      // 获取面包屑导航数据
      const levels = [], isHome = this.isHome(current), components = [];
      if (!isHome) {
        levels.push({home: true, title: this.homeRouteTitle});
      }
      matched.forEach((m) => {
        if (m.meta && m.meta.title && m.meta.breadcrumb !== false) {
          levels.push(this.toLevelObject(m.path, m.meta.title));
        }
        if (m.components && m.components.default && m.components.default.name) {
          components.push(m.components.default.name);
        }
      });
      this.levelData = levels;

      // 添加页签
      if (isHome) {
        this.tabActive = '/';
        this.setHomeComponents(components);
      } else {
        let title = meta.title, closable = (meta.closable !== false), key = path;
        if (meta.tabUnique === false || (this.repeatableTabs && this.repeatableTabs.includes(key))) {
          key = fullPath;
        }
        if (title) {
          this.$emit('tab-add', {key, path, title, fullPath, components, closable});
        }
        this.tabActive = key;
      }

      // 获取顶栏和侧栏的菜单数据和选中
      this.updateMenuActive(current);
      if (this.isMixMenu || this.isMixSideMenu) {
        this.splitMenuData();
      }

      // 移动端自动收起侧边栏
      if (this.isMobile) {
        this.updateCollapse(true);
      }
    },
    /* 判断路由是否是主页 */
    isHome(route) {
      if (route) {
        const {path, matched} = route;
        return ('/' === path) || (matched.length ? (matched[0].redirect === path) : false);
      }
    },
    /* 获取path对应的面包屑导航数据 */
    toLevelObject(path, title) {
      const menu = this.findMenuByPath(path);
      return {path: path, title: (menu && menu.meta && menu.meta.title) || title};
    },
    /* 获取path对应的菜单数据 */
    findMenuByPath(path) {
      let data;
      eachTreeData(this.menuData, (d) => {
        if (path === d.path) {
          data = d;
          return false;
        }
      });
      return data;
    },
    /* 更新顶栏和侧栏的菜单选中 */
    updateMenuActive(current) {
      const {matched, meta, path} = current;
      let active = path, active1 = null, active2 = null, openKeys = [];
      if (meta && typeof meta.active === 'string') {
        active = meta.active;
      }
      if (matched && matched.length) {
        let match1 = matched[matched.length - 1], match2 = match1;
        if (matched.length > 1) {
          match1 = matched[1];
        }
        if (matched.length > 2) {
          match2 = matched[2];
        }
        if (match1.meta && typeof match1.meta.active === 'string') {
          active1 = match1.meta.active;
        } else {
          active1 = match1.path;
        }
        if (match2.meta && typeof match2.meta.active === 'string') {
          active2 = match2.meta.active;
        } else {
          active2 = match2.path;
        }
        // 获取菜单展开的key
        matched.forEach((d, i) => {
          if (i !== 0 && i !== (matched.length - 1)) {
            openKeys.push(d.path);
          }
        });
      }
      if (this.isTopMenu) {  // 顶栏导航
        this.headMenuActive = [active].concat(openKeys);
        this.sideNavActive = [];
      } else if (this.isMixMenu) {  // 混合导航
        this.headMenuActive = [active1];
        this.sideNavActive = [active2];
      } else {  // 左侧导航
        this.headMenuActive = [];
        this.sideNavActive = [active1];
      }
      this.sideMenuActive = [active].concat(openKeys);
      if (this.sideUniqueOpen) {
        this.sideMenuOpen = openKeys;
      } else {
        this.sideMenuOpen = Array.from(new Set(this.sideMenuOpen.concat(openKeys)));
      }
    },
    /* 分割出顶栏和侧栏的菜单数据 */
    splitMenuData() {
      if (!this.menuData || !this.menuData.length) {
        this.headMenuData = [];
        this.sideNavData = [];
        this.sideMenuData = [];
      } else if (this.isMobile) {  // 移动端
        this.headMenuData = [];
        this.sideNavData = [];
        this.sideMenuData = this.menuData;
      } else if (this.isTopMenu) {  // 顶部导航
        this.headMenuData = this.menuData;
        this.sideNavData = [];
        this.sideMenuData = [];
      } else if (this.isMixMenu) {  // 混合导航
        this.headMenuData = this.menuData.map((d) => {
          return {path: d.path, meta: d.meta};
        });
        let sideMenus = this.headMenuActive ? this.menuData.filter((d) => {
          return this.headMenuActive[0] === d.path;
        }) : [];
        sideMenus = (sideMenus.length ? sideMenus[0].children : this.menuData[0].children) || [];
        if (!sideMenus.length) {
          this.sideNavData = [];
          this.sideMenuData = [];
        } else if (this.isMixSideMenu) {  // 左侧双菜单
          this.sideNavData = sideMenus.map((d) => {
            return {
              path: d.path,
              meta: d.meta,
              children: this.collapse ? d.children : null,
              tempChildren: d.children
            };
          });
          let temps = this.sideNavActive ? sideMenus.filter((d) => {
            return this.sideNavActive[0] === d.path;
          }) : [];
          temps = (temps.length ? temps[0].children : sideMenus[0].children) || [];
          this.sideMenuData = temps;
        } else {  // 左侧单菜单
          this.sideNavData = [];
          this.sideMenuData = sideMenus;
        }
      } else {  // 左侧导航
        this.headMenuData = [];
        if (this.isMixSideMenu) {  // 左侧双菜单
          this.sideNavData = this.menuData.map((d) => {
            return {
              path: d.path,
              meta: d.meta,
              children: this.collapse ? d.children : null,
              tempChildren: d.children
            };
          });
          let temps = this.sideNavActive ? this.menuData.filter((d) => {
            return this.sideNavActive[0] === d.path;
          }) : [];
          temps = (temps.length ? temps[0].children : this.menuData[0].children) || [];
          this.sideMenuData = temps;
        } else {  // 左侧单菜单
          this.sideNavData = [];
          this.sideMenuData = this.menuData;
        }
      }
    },
    /* 语言切换后重新处理数据 */
    changeLanguage() {
      this.updateMenuData();
      this.updateLevelData();
      this.updateTabData();
    },
    /* 国际化改变后更新菜单数据 */
    updateMenuData() {
      let tempHomeTitle = null;
      this.menuData = formatTreeData(this.menus, (item) => {
        const title = item.meta ? item.meta.title : null;
        if (!tempHomeTitle && (!item.children || !item.children.length)) {
          tempHomeTitle = title;
        }
        return Object.assign({}, item, {
          meta: Object.assign({}, item.meta, {
            title: this.routeI18n(item.path, item) || title
          })
        });
      });
      this.splitMenuData();
      this.homeRouteTitle = this.homeTitle || tempHomeTitle || DEFAULT_HOME_TITLE;
    },
    /* 国际化改变后更新页签数据 */
    updateTabData() {
      const tabs = [];
      this.tabs.forEach((item) => {
        const menu = this.findMenuByPath(item.path);
        tabs.push(Object.assign({}, item, {
          title: this.routeI18n(item.path, menu) || item.title
        }));
      });
      this.tabData = tabs;
    },
    /* 国际化改变后更新面包屑导航数据 */
    updateLevelData() {
      const levels = [];
      this.levelData.forEach((d) => {
        if (d.home) {
          levels.push({home: true, title: this.homeRouteTitle});
        } else {
          levels.push(this.toLevelObject(d.path, d.title));
        }
      });
      this.levelData = levels;
    },
    /* 获取路由地址对应的il8n名称 */
    routeI18n(path, menu) {
      if (this.i18n && path) {
        let key;
        if (path.startsWith('http://') || path.startsWith('https://') || path.startsWith('//')) {
          key = path.replace(/\.(\w)/g, ($0, $1) => $1.toUpperCase());
        } else {
          key = (path.indexOf('/') === 0 ? path.substring(1) : path);
          key = key.replace(/-(\w)/g, ($0, $1) => $1.toUpperCase())
            .replace(/_(\w)/g, ($0, $1) => $1.toUpperCase())
            .replace(/\//g, '.');
        }
        return this.i18n(path, key, menu);
      }
    },
    /* 侧栏折叠状态改变处理 */
    onCollapseChange() {
      if (this.isMixSideMenu) {
        if (this.collapse) {
          this.sideNavData.forEach((d) => {
            d.children = d.tempChildren;
          });
        } else {
          this.sideNavData.forEach((d) => {
            d.children = null;
          });
        }
      }
    },
    /* 获取内容elem */
    getContentElem() {
      return document.querySelector(this.contentElem);
    }
  },
  watch: {
    $route() {
      this.onRouteChange(this.$route);
    },
    layoutStyle() {
      const current = this.$route;
      if (current) {
        this.updateMenuActive(current);
        this.splitMenuData();
      }
    },
    sideMenuStyle() {
      this.splitMenuData();
    },
    isMobile() {
      this.splitMenuData();
    },
    menus() {
      this.updateMenuData();
    },
    tabs() {
      this.updateTabData();
    },
    homeTitle() {
      if (this.homeTitle) {
        this.homeRouteTitle = this.homeTitle;
      } else {
        this.updateMenuData();
      }
      this.updateLevelData();
    },
    sideNavCollapse() {
      this.navIsCollapse = this.sideNavCollapse;
    },
    collapse() {
      this.onCollapseChange();
    }
  },
  unmounted() {
    // 销毁监听
    window.removeEventListener('resize', this.onResizeListener);
    window.removeEventListener('keydown', this.onKeydownListener);
  }
}
</script>
