5、Nuxt3 elementplus引入及多皮肤主题模式切换—黑暗模式、layouts、elementplus城市选择组件

2,095 阅读2分钟

本章节接下来我们来引入我们开发所需要的UI组件elementplus,实现顶部和底部整体布局以及配置黑暗模式 。最终效果如下:

基础模式

基础模式

黑暗模式

黑暗模式

一、引入组件


//安装elementplus
1、npm install element-plus --save

//安装 @element-plus/icons 图标库
2、npm install  @element-plus/icons

二、然后在我们的plugins创建element-plus.client.ts文件。注意:如果我们在文件命名时加上 .client,例如 element-plus.client.ts,此时代表该插件只在客户端加载


import *  as ElementPlus from 'element-plus/dist/index.full'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
// @ts-ignore
import { defineNuxtPlugin } from '#app'

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.use(ElementPlus, {
    locale: zhCn,
  })
})

找到nuxt.config.ts,引入样式:

  css:[
        'element-plus/dist/index.css',
        '~/assets/css/resetElStyle.scss'
    ],

三、找到我们的整体布局组件default.vue,我们来使用一下引入的elementplus,看是否引入成功。(我做了一个简单布局,使用了scss,所以复制的时候需要大家提前安装一下scss)

在顶部引入一个模式切换组件。如图:

新增模式切换功能

新增模式切换功能

1、首先我们引入图标及切换组件:


//引入我们需要的图标
import { Moon, Sunny,  Search} from '@element-plus/icons-vue'
//引入样式文件
import theme from '@/utils/theme'
import { colorMix } from "@/utils/tool"

//在页面使用
<el-switch
  class="change_ico"
  v-model="isDark"
  size="small"
  inline-prompt
  style="--el-switch-on-color: #f2f2f2; --el-switch-off-color: #141414"
  :active-icon="Sunny"
  :inactive-icon="Moon"
  @change="themeChange"
  />
    
// 设置switch的背景颜色
const blackColor = 'var(--bg-color-mute)'
const themeColorObj = {
  defaultTheme: {
    title: '浅色主题'
  },
  darkTheme: {
    title: '深色主题'
  }
}

//模式切换事件

const themeChange = (val: boolean) => {
  if(val){
    state.currentSkinName = 'defaultTheme'
    switchTheme( state.currentSkinName )
  }else{
    state.currentSkinName = 'darkTheme'
    switchTheme(state.currentSkinName)
  }
}
const switchTheme = (type?:string) =>{
  type = type || 'darkTheme'
  const colorObj = theme[type]
  for (let i = 1; i < 10; i += 1) {
    colorObj[`--el-color-primary-light-${10 - i}`] = colorMix(colorObj['--el-color-white'], colorObj['--el-color-primary'], i * 0.1)
  }
  Object.keys(colorObj).map(item => {
    document.documentElement.style.setProperty(item, colorObj[item])
  })
}

2、事件处理完毕,接下来我们就需要配置主题的样式 首先:在utils创建样式文件theme.ts及tool.ts,我们只处理两种模式,如果要多种可自行拓展,完整代码如下:可以直接拷贝到自己项目中 theme.ts

export default {
  'defaultTheme': {
    '--el-background-color-base': '#ffffff',
    '--el-color-white': '#ffffff',
    '--el-text-color-bar':'#ffffff',
    '--el-color-black': '#ffffff',
    '--el-color-primary': '#409eff',
    '--el-navbar_bg':'#0440D7',//导航
    '--el-slider_bg':'#0440D7',
    '--el-background-top-color':'#e3e4e5',
    "--el-box-color-base": "#f5f7fa", // 分类框
    '--el-logo_bg':'#333',//logo
    '--el-en_bg':'#666666',//英文
    '--bg-color-mute': '#f2f2f2',//模式切换按钮
    '--el-text-color-cls': '#666666',//顶部选项颜色
    '--el-text-color-th': 'rgba(0, 0, 0, 0.3)', // 最次要文字颜色
    '--el-color-primary-light-1': '#53a8ff',
    '--el-color-primary-light-2': '#66b1ff',
    '--el-color-primary-light-3': '#79bbff',
    '--el-color-primary-light-4': '#8cc5ff',
    '--el-color-primary-light-5': '#a0cfff',
    '--el-color-primary-light-6': '#b3d8ff',
    '--el-color-primary-light-7': '#c6e2ff',
    '--el-color-primary-light-8': '#d9ecff',
    '--el-color-primary-light-9': '#ecf5ff',
    '--el-input-bg-color': '#fff', //输入框背景色
    '--el-fill-color-blank': '#fff',
    '--el-select-box':'#fff',//下拉框BG
    '--el-select-box-active':'#fff',//下拉框激活BG
    '--el-input-border-color':'#00adff',//下拉边框
    '--el-hover-bg-color':'#2590F9',//鼠标放入背景色
    '--el-switch_bg':'#f2f2f2', //模式切换
    '--el-switch-color':'#666666',//模式颜色
    '--el-footer-bg':'#F6F7F8',//底部颜色
    '--el-btn-color':'#ffffff',//按钮颜色

    '--el-color-success': '#67c23a',
    '--el-color-success-light': '#e1f3d8',
    '--el-color-success-lighter': '#f0f9eb',
    '--el-color-warning': '#e6a23c',
    '--el-color-warning-light': '#faecd8',
    '--el-color-warning-lighter': '#fdf6ec',
    '--el-color-danger': '#f56c6c',
    '--el-color-danger-light': '#fde2e2',
    '--el-color-danger-lighter': '#fef0f0',
    '--el-color-error': '#f56c6c',
    '--el-color-error-light': '#fde2e2',
    '--el-color-error-lighter': '#fef0f0',
    '--el-color-info': '#909399',
    '--el-color-info-light': '#e9e9eb',
    '--el-color-info-lighter': '#f4f4f5',
    '--el-text-color-primary': '#303133',
    '--el-text-color-regular': '#606266',
    '--el-text-color-secondary': '#909399',
    '--el-text-color-placeholder': '#c0c4cc',
    '--el-border-color-base': '#dcdfe6',
    '--el-border-color-light': '#e4e7ed',
    '--el-border-color-lighter': '#ebeef5',
    '--el-border-color-extra-light': '#f2f6fc',
    '--color-input-bg': '#f4f5f5',
    '--color-input-error-bg': '#ffece8',
    '--color-input-placeholder': '#86909c',
    '--color-input-text': '#4e5969',
    '--color-input-icon': '#f53f3f',
    '--el-popup-modal-background-color': 'var(--el-color-black)',
    '--el-popup-modal-opacity': '.5',
    '--el-border-width-base': '1px',
    '--el-border-style-base': 'solid',
    '--el-border-color-hover': 'var(--el-text-color-placeholder)',
    '--el-border-base': 'var(--el-border-width-base) var(--el-border-style-base) var(--el-border-color-base)',
    '--el-border-radius-base': '4px',
    '--el-border-radius-small': '2px',
    '--el-border-radius-round': '20px',
    '--el-border-radius-circle': '100%',
    '--el-box-shadow-base': '0 2px 4px rgba(0, 0, 0, .12),0 0 6px rgba(0, 0, 0, .04)',
    '--el-box-shadow-light': '0 2px 12px 0 rgba(0, 0, 0, .1)',
    '--el-svg-monochrome-grey': '#dcdde0',
    '--el-fill-base': 'var(--el-color-white)',
    '--el-font-size-extra-large': '20px',
    '--el-font-size-large': '18px',
    '--el-font-size-medium': '16px',
    '--el-font-size-base': '14px',
    '--el-font-size-small': '13px',
    '--el-font-size-extra-small': '12px',
    '--el-font-weight-primary': '500',
    '--el-font-line-height-primary': '24px',
    '--el-font-color-disabled-base': '#bbb',
    '--el-index-normal': '1',
    '--el-index-top': '1000',
    '--el-index-popper': '2000',
    '--el-disabled-fill-base': 'var(--el-background-color-base)',
    '--el-disabled-color-base': 'var(--el-text-color-placeholder)',
    '--el-disabled-border-base': 'var(--el-border-color-light)',
    '--el-transition-duration': '.3s',
    '--el-transition-duration-fast': '.2s',
    '--el-transition-function-ease-in-out-bezier': 'cubic-bezier(.645, .045, .355, 1)',
    '--el-transition-function-fast-bezier': 'cubic-bezier(.23, 1, .32, 1)',
    '--el-transition-all': 'all var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-fade': 'opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-md-fade': 'transform var(--el-transition-duration) var(--el-transition-function-fast-bezier),opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-fade-linear': 'opacity var(--el-transition-duration-fast) linear',
    '--el-transition-border': 'border-color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-color': 'color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)'
  },
  'darkTheme':{
    "--el-color-primary": "#409eff", // 主题色
    '--el-background-top-color':'#262727',
    "--el-box-color-base": "#262727", // 分类框
    "--el-background-color-base": "#14161a", // 基础背景色
    "--el-color-white": "#1d1e1f", // 基础白色
    "--el-color-black": "#262727", // 基础黑色
    '--el-navbar_bg':'#14161a', //导航色
    '--el-switch_bg':'#2c2c2c', //模式切换
    '--el-logo_bg':'#fff',//logo
    '--el-slider_bg':'#1B222C',
    '--el-en_bg':'#fff',//英文
    '--el-btn-color':'#E5EAF3',//按钮颜色
    '--el-text-color-bar':'#ffffff',
    '--el-text-color-primary': '#FAFAFA', // 主要文字颜色
    '--el-text-color-regular': '#FAFAFA', // 常规文字颜色
    '--el-text-color-placeholder': '#c0c4cc',  // 占位文字颜色
    '--el-text-color-secondary': 'rgba(255, 255, 255, 0.5)', // 次要文字颜色
    '--el-text-color-th': 'rgba(255, 255, 255, 0.3)', // 最次要文字颜色
    '--el-text-color-cls': '#fff',//顶部选项颜色
    "--el-border-color-base": "#4C4D4F", // 一级边框颜色
    "--el-border-color-light": "#414243", // 二级边框颜色
    "--el-border-color-lighter": "#363637", // 三级边框颜色
    "--el-border-color-extra-light": "#2B2B2C", // 四级边框颜色
    '--el-input-bg-color': '#2c2c2c', //输入框背景色
    '--el-fill-color-blank': '#414243',
    '--el-select-box':'#4C4D4F',//下拉框BG
    '--el-select-box-active':'#414243',//下拉框激活BG
    '--el-input-border-color':'#fff',//下拉边框
    '--el-switch-color':'#ffffff',//模式颜色
    '--el-footer-bg':'rgba(255, 255, 255, 0.02)',//底部颜色
    '--bg-color-mute': '#2c2c2c',//模式切换按钮
    '--el-hover-bg-color':'#2590F9',//鼠标放入背景色
    '--el-color-success': '#67c23a', // 成功颜色
    '--el-color-success-light': '#e1f3d8',
    '--el-color-success-lighter': '#f0f9eb',
    '--el-color-warning': '#e6a23c', // 警告颜色
    '--el-color-warning-light': '#faecd8',
    '--el-color-warning-lighter': '#fdf6ec',
    '--el-color-danger': '#f56c6c', // 危险颜色
    '--el-color-danger-light': '#fde2e2',
    '--el-color-danger-lighter': '#fef0f0',
    '--el-color-error': '#f56c6c', // 错误颜色
    '--el-color-error-light': '#fde2e2',
    '--el-color-error-lighter': '#fef0f0',
    "--el-color-info": "#7B88A9", // 信息颜色
    '--el-color-info-light': '#e9e9eb',
    '--el-color-info-lighter': '#f4f4f5',
    '--color-input-bg': '#f4f5f5', // input 输入框
    '--color-input-error-bg': '#ffece8',
    '--color-input-placeholder': '#86909c',
    '--color-input-text': '#4e5969',
    '--color-input-icon': '#f53f3f',
    '--el-svg-monochrome-grey': '#dcdde0',
    '--el-font-color-disabled-base': '#bbb',
    '--el-popup-modal-background-color': 'var(--el-color-black)',
    '--el-popup-modal-opacity': '.5',
    '--el-border-width-base': '1px',
    '--el-border-style-base': 'solid',
    '--el-border-color-hover': 'var(--el-text-color-placeholder)',
    '--el-border-base': 'var(--el-border-width-base) var(--el-border-style-base) var(--el-border-color-base)',
    '--el-border-radius-base': '4px',
    '--el-border-radius-small': '2px',
    '--el-border-radius-round': '20px',
    '--el-border-radius-circle': '100%',
    '--el-box-shadow-base': '0 2px 4px rgba(0, 0, 0, .12),0 0 6px rgba(0, 0, 0, .04)',
    '--el-box-shadow-light': '0 2px 12px 0 rgba(0, 0, 0, .1)',
    '--el-fill-base': 'var(--el-color-white)',
    '--el-font-size-extra-large': '20px',
    '--el-font-size-large': '18px',
    '--el-font-size-medium': '16px',
    '--el-font-size-base': '14px',
    '--el-font-size-small': '13px',
    '--el-font-size-extra-small': '12px',
    '--el-font-weight-primary': '500',
    '--el-font-line-height-primary': '24px',
    '--el-index-normal': '1',
    '--el-index-top': '1000',
    '--el-index-popper': '2000',
    '--el-disabled-fill-base': 'var(--el-background-color-base)',
    '--el-disabled-color-base': 'var(--el-text-color-placeholder)',
    '--el-disabled-border-base': 'var(--el-border-color-light)',
    '--el-transition-duration': '.3s',
    '--el-transition-duration-fast': '.2s',
    '--el-transition-function-ease-in-out-bezier': 'cubic-bezier(.645, .045, .355, 1)',
    '--el-transition-function-fast-bezier': 'cubic-bezier(.23, 1, .32, 1)',
    '--el-transition-all': 'all var(--el-transition-duration) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-fade': 'opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-md-fade': 'transform var(--el-transition-duration) var(--el-transition-function-fast-bezier),opacity var(--el-transition-duration) var(--el-transition-function-fast-bezier)',
    '--el-transition-fade-linear': 'opacity var(--el-transition-duration-fast) linear',
    '--el-transition-border': 'border-color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)',
    '--el-transition-color': 'color var(--el-transition-duration-fast) var(--el-transition-function-ease-in-out-bezier)'
  }

}

tool.ts


export const colorMix = (color1, color2, weight) => {
  weight = Math.max(Math.min(Number(weight), 1), 0)
  let r1 = parseInt(color1.substring(1, 3), 16)
  let g1 = parseInt(color1.substring(3, 5), 16)
  let b1 = parseInt(color1.substring(5, 7), 16)
  let r2 = parseInt(color2.substring(1, 3), 16)
  let g2 = parseInt(color2.substring(3, 5), 16)
  let b2 = parseInt(color2.substring(5, 7), 16)
  let r: number | string = Math.round(r1 * (1 - weight) + r2 * weight)
  let g: number | string = Math.round(g1 * (1 - weight) + g2 * weight)
  let b: number | string = Math.round(b1 * (1 - weight) + b2 * weight)
  r = ("0" + (r || 0).toString(16)).slice(-2)
  g = ("0" + (g || 0).toString(16)).slice(-2)
  b = ("0" + (b || 0).toString(16)).slice(-2)
  return "#" + r + g + b;
}

最后我们来简单配置一下公共样式和模式切换重置公共样式:在assets/css 创建 resetElStyle.scss


.mt10 {
  margin-top: 10px;
}
body{
  background: var(--el-color-black)
}
.main_color{
  background-color: var(--el-background-color-base);
}
.el_base_color{
  background-color: var(--el-background-top-color);
}
.el-menu-item{
  border-bottom:none !important;
}
.right-menu .right-menu-item{
  width:62px;
  height:62px;
  background-color: var(--el-slider_bg);
  border-radius: 6px;
  overflow: hidden;
}
.right-menu-item .right-menu-qrcode .qrcode-box{
  background:var(--el-slider_bg);
  padding:5px
}
.right-menu-item .right-menu-qrcode p{
  padding:-12px 0 5px 0;
  text-align:center;
  color:#fff;
  font-size:12px
}
.logoWall .logo_animate{
  width: 100%;
  height: 450px;
  background: var(--el-background-color-base);
  position: relative;
}
body {
  p{
    color:var(--el-text-color-primary)
  }
  span{
    color:var(--el-text-color-primary)
  }
  .change_ico{
    margin-left:22px;
    width:42px;
    height:24px;
  }
  .change_ico  .el-switch__action{
    background-color: var(--el-switch-color) !important;
  }
  .change_ico .el-icon{
    font-size: 16px;
    color:var(--el-switch-color) !important;
  }
  //下拉框
  .el-scrollbar{
    background: var( --el-select-box);
    .selected{
      background: var(--el-select-box-active);
      color: var(--el-color-primary);
    }
    .el-select-dropdown__item.hover, .el-select-dropdown__item:hover{
      background: var(--el-select-box-active);
      color: var(--el-color-primary);
    }
  }
  /*数字输入框*/
  .el-input-number__decrease, .el-input-number__increase {
    background: var(--el-color-black)
  }

  // 复合输入框
  .el-input-group__append, .el-input-group__prepend {
    border: 1px solid var(--el-border-color-base);
    border-right: none;
  }

  //  日期选择 el-date-picker
  .el-picker-panel {
    border: 1px solid var(--el-border-color-light);
    background: var(--el-color-black)
  }


  // 日期和时间范围
  .el-date-editor .el-range-input {
    background: var(--el-color-white)
  }

  .el-picker-panel__footer {
    background: var(--el-color-black)
  }

  // 时间选择
  .el-time-panel__content {
    .el-time-spinner__item:hover, .el-scrollbar__thumb:hover {
      background: var(--el-select-box-active)
    }
  }

  // 表格分页
  .el-pagination.is-background .btn-next, .el-pagination.is-background .btn-prev, .el-pagination.is-background .el-pager li {
    background: var(--el-color-black)
  }

  // menu
  .el-menu {
    border-right: none;
  }
}

到此为止我们已经处理完毕,如果要在某个地方使用如下:例如



background-color: var(--el-background-color-base);
color: var(--el-color-primary);

接下来附上我们布局组件 default.vue

预览效果图 :

555.jpg

注意 :1、在layouts下的文件中, 页面出口元素必须被包裹;例如:

    <div> 
        <slot /> <!--页面出口--->
    </div>

注意 :2、在navbar导航中,路由的跳转我们需要使用 nuxt-link ,例如:<nuxt-link to="/exercise">在线练习</nuxt-link>,如果要传递参数如下:

<nuxt-link :to="{name:'跳转路由名称',query:{字段:'名称'}}">跳转传惨</nuxt-link>

注意 :3、我们要了解 elementplus el-menu 组件的使用:例如

<el-menu
      :default-active="activeIndex" <!--  默认激活菜单的 index -->
      class="el-menu-tabs"
      mode="horizontal" <!-- 布局方式,horizontal横向  -->
      :ellipsis="isCollapse" <!-- 是否省略多余的子项 -->
      background-color="var(--el-navbar_bg)" <!-- 背景字颜 -->
      text-color="var(--el-text-color-bar)" <!-- 文字颜 -->
      active-text-color="#fff"  <!-- 激活文字颜 -->
      @select="handleSelect" <!-- 菜单激活回调 -->
  >
    <el-menu-item index="1">
      <NuxtLink to="/"> 首 页 </NuxtLink>
    </el-menu-item>
</el-menu>

注意 :4、elementplus el-dialog 和 client-only 的使用

<!---

--->
<template>

    <div>
        <client-only> <!-- 表示只在客户端渲染 -->
          <el-dialog :closeOnClickModal="false" width="440px" center  v-model="state.forgetVisible">
    
          </el-dialog>
        </client-only>
    </div>

</template>

<script setup lang="ts">


</script>


完整代码:

/*
 *   佛曰:
 *        写字楼里写字间,写字间里程序员;
 *        程序人员写程序,又拿程序换酒钱。
 *        酒醒只在网上坐,酒醉还来网下眠;
 *        酒醉酒醒日复日,网上网下年复年。
 *        但愿老死电脑间,不愿鞠躬老板前;
 *        奔驰宝马贵者趣,公交自行程序员。
 *        别人笑我忒疯癫,我笑自己命太贱;
 *        不见满街漂亮妹,哪个归得程序员?
 *
 * @Description: 布局组件
 * @version:1.2.0
 * @Date: 2022-09-12 15:22:12
 * @Author: wenBin
 */

<template>
  <div class="el_full_box mx-auto">
    <div class="common-layout">
      <el-container>
        <!--头部布局-->
        <el-header>
          <div class="el_full_box el_base_color">
            <div class="hj_container hj_title_box">
              <span>欢迎来到XXXXXX</span>
              <div class="hj_search">
                <div class="hj_ruzhu">
                  <div>
                    <div class="hj_rt">
                      <ul>
                        <li @click="opeanCooper">
                          <span class="hj_span1">商务合作</span>
                          <b></b>
                        </li>
                        <li  v-if="state.userData">
                          <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
                            <div class="avatar-wrapper u_name">
                              <img v-if="state.userData" :src="state.userData.headimg" class="u_img">
                              <span class="user_name">{{state.userData.truename}}</span>
                              <i class="el-icon-caret-bottom" />
                            </div>
                            <el-dropdown-menu slot="dropdown">
                              <nuxt-link to="/user">
                                <el-dropdown-item>个人中心</el-dropdown-item>
                              </nuxt-link>
                              <el-dropdown-item divided>
                                <span @click="loginout" style="display:block;">退出登录</span>
                              </el-dropdown-item>
                            </el-dropdown-menu>
                          </el-dropdown>
                          <b></b>
                        </li>
                        <li  v-if="!state.userData" @click="login">
                          <span class="hj_lo">登录/注册</span>
                          <b v-if="state.userData"></b>
                        </li>
                        <li v-if="state.userData">
                          <nuxt-link to="/user">
                            <span class="hj_cc">个人中心</span>
                          </nuxt-link>
                          <b v-if="!state.userData"></b>
                        </li>
                        <!--                        <li v-if="!state.userData">-->
                        <!--                          <nuxt-link to="/reg">-->
                        <!--                            <span class="hj_ccc">注册</span>-->
                        <!--                          </nuxt-link>-->
                        <!--                        </li>-->
                        <li>
                          <el-switch
                              class="change_ico"
                              v-model="isDark"
                              size="small"
                              inline-prompt
                              style="--el-switch-on-color: #f2f2f2; --el-switch-off-color: #141414"
                              :active-icon="Sunny"
                              :inactive-icon="Moon"
                              @change="themeChange"
                          />
                        </li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="hj_box">
            <div class="hj_container nave_bar">
              <div class="c_logo">
                <img style="height: 30px;" src="/assets/images/logo.png" />
                <span>XXXXXX课堂</span>
              </div>
              <el-menu
                  :default-active="activeIndex"
                  class="el-menu-tabs"
                  mode="horizontal"
                  :ellipsis="isCollapse"
                  background-color="var(--el-navbar_bg)"
                  text-color="var(--el-text-color-bar)"
                  active-text-color="#fff"
                  @select="handleSelect"
              >
                <el-menu-item index="1">
                  <NuxtLink to="/"> 首 页 </NuxtLink>
                </el-menu-item>
                <el-menu-item index="2">
                  <nuxt-link to="/learn"> 学习中心 </nuxt-link>
                </el-menu-item>
                <el-menu-item index="3">
                  <nuxt-link to="/exercise">在线练习</nuxt-link>
                </el-menu-item>
                <el-menu-item index="4">
                  <NuxtLink to="/workplace"> 职场提升</NuxtLink>
                </el-menu-item>
                <el-menu-item index="5">
                  <NuxtLink to="/employment"> 行业资讯</NuxtLink>
                </el-menu-item>
                <el-menu-item index="6">
                  <NuxtLink to="/business"> 新闻资讯</NuxtLink>
                </el-menu-item>
                <!--                <el-menu-item index="7">-->
                <!--                  <NuxtLink to="/live"> 网红直播</NuxtLink>-->
                <!--                </el-menu-item>-->
                <!--                <el-sub-menu index="8">-->
                <!--                  <template #title>政策动态</template>-->
                <!--                  <el-menu-item index="8-1"> 政策公告 </el-menu-item>-->
                <!--                  <el-menu-item index="8-2"> 行业动态 </el-menu-item>-->
                <!--                  <el-menu-item index="8-3"> IP 新闻</el-menu-item>-->
                <!--                </el-sub-menu>-->
                <el-menu-item index="9">
                  <NuxtLink to="/about"> 关于我们 </NuxtLink>
                </el-menu-item>
              </el-menu>
              <div class="hj_search">
                <div class="search_lf_box">
                  <div class="search_box">
                    <el-input placeholder="课程名称" v-model="state.searchCtn"></el-input>

                    <div v-if="state.searchCtn"  class="sou_action">
                      <b></b>
                      <nuxt-link style="margin-top:2px;"  v-if="searchCtn" :to="{name:'searchlist',query:{kwd:state.searchCtn}}">

                        <img  @click="getSearchAll" class="hj_btn" src="/assets/images/ssuo.png" alt="">
                      </nuxt-link>
                    </div>

                    <div v-else class="sou_action" @click="getSearchAll">
                      <b></b>
                      <el-icon size="28" color="var(--el-text-color-secondary)" >
                        <Search style="width: 2em; height: 2em;"/>
                      </el-icon>
                    </div>

                    <!--<el-button v-else @click="getSearchAll" class="hj_btn">搜索</el-button>-->
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-header>
        <!--主题插槽-->
        <el-main class="el_main">
          <slot />
        </el-main>
        <!---底部布局---->
        <div class="el_footer">
          <div class="hj_footer">
            <div class="footer_box">
              <div class="lf">
                <div>
                  <h6>友情链接</h6>
                  <div class="footer_phone hj_href">
                    <div>
                      <a style="text-align: left" href="https://daxuepc.com/index">腾讯大学</a>
                      <a href="https://www.examw.com/">中华考试网</a>
                      <a href="https://www.wangxiao.cn/?agent=qqcheng">中大网校</a>
                      <a href="http://www.offcn.com/">中公公务员网</a>
                      <a href="http://www.huatu.com/">公务员考试网</a>
                      <a href="http://www.woshipm.com/">人人都是产品经理</a>
                      <a href="https://ke.qq.com/itdoc">IT教程</a>
                      <a href="http://www.yixiuxueyuan.com/">益修学院</a>
                      <a  href="https://www.qidianla.com/index/main.html">起点学院</a>
                      <a  style="text-align: left"  href="http://hrss.henan.gov.cn" target="_blank">河南省人社厅</a>
                      <a href="https://www.baishan.com" target="_blank">白山云科技</a>
                      <a href="https://www.alibabagroup.com/cn/global/home" target="_blank">阿里巴巴</a>
                    </div>
                  </div>
                </div>
              </div>
            </div>
           <div class="hj_bei hj_shuoming">
              <span>Copyright © 2022 All Rights Reserved     </span>

              <img style="width:22px;"  src="/assets/images/logo.png" />

              <span> XXXXX信息科技有限公司  版权所有</span>
              <a href="https://beian.miit.gov.cn/" target="_blank">豫ICP备333333333号-1</a>
            </div>
          </div>
        </div>
      </el-container>
    </div>
    <!--    商务合作表单弹窗   -->
    <client-only>
      <el-dialog
          width="540px"
          v-model="state.cooporationTost"
      >
        <div class="title hj_two hj_t_margin">
          <div>
            <span>商务合作</span>
          </div>
        </div>
        <el-form  ref="ruleFormRef"
                  :model="ruleForm"
                  :rules="rules"
                  class="common-ruleForm"
                  :size="formSize"
                  status-icon
                  label-width="0"
        >
          <el-form-item label=""  prop="cNames">
            <el-input placeholder="请输入姓名" v-model="ruleForm.cNames"></el-input>
          </el-form-item>
          <el-form-item  label="" prop="cPhone">
            <el-input  placeholder="请输入联系方式" v-model="ruleForm.cPhone"></el-input>
          </el-form-item>
          <el-form-item label="" prop="selectedOptions" class="hj_area">
            <el-cascader
                size="large"
                :options="$regionData"
                placeholder="选择所在地区"
                v-model="state.selectedOptions"
                @change="handleChange">
            </el-cascader>
          </el-form-item>
          <el-form-item label="" style="margin-bottom: 40px;" prop="cDesc">
            <el-input
                type="textarea"
                :rows="4"
                placeholder="合作描述"
                v-model="ruleForm.cDesc">
            </el-input>
          </el-form-item>
          <el-button type="primary" class="hj_reg_btn" @click.native.prevent="HeZuo">提 交</el-button>
        </el-form>
      </el-dialog>
    </client-only>
    <!--    注册提示弹窗   -->
    <client-only>
      <el-dialog v-model="state.tipShow" title="注册须知" width="30%" center>
        <div>
          <span><strong style="color:#ff0000">注意</strong>:本平台注册功能只针对个人用户使用,批量组织学习用户,请联系: <strong style="color:#173C80">负责人</strong> / <strong style="color:#173C80">教务老师</strong> 获取本人账号密码登录学习相关课程, <strong style="color:#ff0000">切勿注册</strong> </span>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="backLogin">登 录</el-button>
            <el-button type="primary" @click="wenTi">注 册</el-button>
          </span>
        </template>
      </el-dialog>
    </client-only>
    <!-- 登录弹窗   -->
    <client-only>
      <el-dialog v-model="state.loginVisible" width="440px" center>
        <div  class="hj_login" >
          <div class="title hj_two">
            <div class="loginActive" >
              <img style="width:100px;" src="assets/images/loginImg.png" alt="">
            </div>
          </div>
          <el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-width="0" class="demo-ruleForm">
            <el-form-item label="" prop="phone">
              <el-input placeholder="请输入手机号码" v-model="ruleForm.phone"></el-input>
            </el-form-item>
            <el-form-item  label="" prop="password">
              <el-input placeholder="请输入密码" show-password v-model="ruleForm.password"></el-input>
            </el-form-item>
            <el-form-item class="hj_other" label="">
              <div class="hj_aggrens">
                <el-checkbox v-model="state.checked">记住密码</el-checkbox>
                <div>
                  <span @click="forgetPwd">忘记密码</span>
                  <b></b>
                  <span @click="register">注册</span>
                </div>
              </div>
            </el-form-item>
            <el-form-item label="">
              <el-button  type="primary" @click="userLogin" class="hj_reg_btn hj_sm_btn" >登  录</el-button>
            </el-form-item>
          </el-form>
        </div>

      </el-dialog>
    </client-only>
    <!--  找回密码  -->
    <client-only>
      <el-dialog :closeOnClickModal="false" width="440px" center  v-model="state.forgetVisible">
        <div  class="hj_login" >
          <div class="title hj_two hj_sp">
            <span class="hj_three">找回密码</span>
          </div>
          <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="0" class="demo-ruleForm">
            <div v-if="state.getShow == 0">
              <el-form-item label="" prop="phone">
                <el-input placeholder="请输入注册手机号" v-model="ruleForm.phone"></el-input>
              </el-form-item>
              <el-form-item class="pos_cod" label=""  prop="code">
                <div class="hj_code">
                  <el-input class="_code" placeholder="请输入验证码" v-model="ruleForm.code"></el-input>
                  <el-button @click="getCode" :disabled="state.isDisabled" class="get_cod" type="success"  round>{{state.buttonName}}</el-button>
                </div>
              </el-form-item>
              <el-form-item label="">
                <el-button @click="getSteps(0)"  type="primary" class="hj_reg_btn hj_sm_btn mj_next" >下一步</el-button>
              </el-form-item>
            </div>
            <div v-else>
              <el-form-item label="" prop="password">
                <el-input show-password placeholder="请输入密码" v-model="ruleForm.password"></el-input>
              </el-form-item>
              <el-form-item label="" prop="rePassword">
                <el-input show-password placeholder="请再次输入密码" v-model="ruleForm.rePassword"></el-input>
              </el-form-item>
              <el-form-item label="">
                <el-button  @click="getSteps(1)" type="primary" class="hj_reg_btn hj_sm_btn mj_next" >提 交</el-button>
              </el-form-item>
            </div>
          </el-form>
        </div>
      </el-dialog>
    </client-only>
  </div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, getCurrentInstance }  from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules, ElButton,ElCheckbox } from 'element-plus'
import { Moon, Sunny,  Search} from '@element-plus/icons-vue'
import theme from '@/utils/theme'
import { colorMix } from "@/utils/tool"
const { $router, $regionData,$TextToCode, $CodeToText } = useNuxtApp()
const routeName = $router.currentRoute.value.name
const activeIndex = ref('1')
const isCollapse = ref(false)
const isDark = ref(true)
//导航定位
if(routeName == "learn"){
  activeIndex.value  = "2"
}else if(routeName == "exercise"){
  activeIndex.value  = "3"
}else if(routeName == "industry"){
  activeIndex.value  = "7"
}else if(routeName == "workplace"){
  activeIndex.value  = "6"
}else if(routeName == "about"){
  activeIndex.value  = "9"
}else{
  activeIndex.value = "1"
}
// 设置switch的背景颜色
const blackColor = 'var(--bg-color-mute)'
const themeColorObj = {
  defaultTheme: {
    title: '浅色主题'
  },
  darkTheme: {
    title: '深色主题'
  }
}
const state = reactive({
  currentSkinName: 'defaultTheme',
  searchCtn:'',
  options:[],
  selectedOptions: [],
  cooporationTost:false,
  tipShow:false,
  registerVisible:false,
  loginVisible:false,
  forgetVisible:false,
  loginActives:0,
  checked: true,
  getShow:0,
  buttonName: "获取验证码",
  isDisabled: false,
  ctnList:[],
  sTime: 60,
  userData:''
})

// 表单
const ruleForm = reactive({
  'cNames': '',
  'cPhone': '',
  'phone':'',
  'password':'',
  'region': '',
  'sheng':'',
  'shi':'',
  'xian':'',
  'code':'',
  'rePassword':'',
  'cDesc': ''
})

const rules = reactive<FormRules>({
  cNames: [
    { required: true, message: '请输入您的姓名', trigger: 'blur' }
  ],
  cPhone: [
    { required: true, message: '请输入您的手机号码', trigger: 'blur' }
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入验证码', trigger: 'blur' }
  ],
  rePassword: [
    { required: true, message: '请再次输入密码', trigger: 'blur' }
  ],
  region: [
    {
      required: true,
      message: '请选择所在地区',
      trigger: 'change',
    },
  ],
  cDesc: [
    { required: true, message: '您的合作意向描述', trigger: 'blur' }
  ],

  type: [
    {
      type: 'array',
      required: true,
      message: 'Please select at least one activity type',
      trigger: 'change',
    },
  ],
  resource: [
    {
      required: true,
      message: 'Please select activity resource',
      trigger: 'change',
    },
  ],
  desc: [
    { required: true, message: 'Please input activity form', trigger: 'blur' },
  ],
})

onMounted(() => {
  if(process.client){
    switchTheme(state.currentSkinName)
    state.options = $regionData
    console.log($TextToCode)
    state.selectedOptions = [
      $TextToCode ['河南省'].code,
      $TextToCode ['河南省']['郑州市'].code,
      // $TextToCode ['河南省']['郑州市']['金水区'].code
    ]
  }

})

// 选择时间
const handleChange = (value) => {
  ruleForm.region = $CodeToText[value[0]]+'/'+$CodeToText[value[1]]+'/'+$CodeToText[value[2]]
  ruleForm.sheng = $CodeToText[value[0]]
  ruleForm.shi = $CodeToText[value[1]]
  ruleForm.xian = $CodeToText[value[2]]
}

// 提交商务合作表单
const HeZuo =  ():void => {
  let telReg = /^1[2|3|4|5|6|7|8|9][0-9]{9}$/;
  if(!ruleForm.cNames){
    ElMessage({
      message: '请输入您的姓名',
      type: 'error',
    })
  }else if(!ruleForm.cPhone){
    ElMessage({
      message: '请输入手机号码',
      type: 'error',
    })
  }else if(!telReg.test(ruleForm.cPhone)){
    ElMessage({
      message: '手机号码格式不正确',
      type: 'error',
    })
  }else if(!ruleForm.region){
    ElMessage({
      message: "请选择地址",
      type: 'error',
    })
  }else if(!ruleForm.cDesc){
    ElMessage({
      message: '合作描述不能为空',
      type: 'error',
    })
  }else{
    let data = {
      'name':ruleForm.cNames,
      'phone':ruleForm.cPhone,
      'province':ruleForm.sheng,
      'city':ruleForm.shi,
      'county':ruleForm.xian,
      'demand':ruleForm.cDesc
    }
  	//商务合作接口
  }
}

const getThemes = ():void => {
  ElMessage({
    message: 'Congrats, this is a success message.',
    type: 'success',
  })
}

const themeChange = (val: boolean) => {
  console.log(val)
  if(val){
    state.currentSkinName = 'defaultTheme'
    switchTheme( state.currentSkinName )
  }else{
    state.currentSkinName = 'darkTheme'
    switchTheme(state.currentSkinName)
  }
}
const switchTheme = (type?:string) =>{
  type = type || 'darkTheme'
  const colorObj = theme[type]
  for (let i = 1; i < 10; i += 1) {
    colorObj[`--el-color-primary-light-${10 - i}`] = colorMix(colorObj['--el-color-white'], colorObj['--el-color-primary'], i * 0.1)
  }
  Object.keys(colorObj).map(item => {
    document.documentElement.style.setProperty(item, colorObj[item])
  })
}

//商务合作
const opeanCooper = () => {
  state.cooporationTost = true
  console.log(state.cooporationTost)
}

//导航切换
const handleSelect = (key: string, keyPath: string[]) => {

}

// 搜索
const goSearch = () => {

}
const getSearchAll = () => {

}
// 退出登录
const loginout = () => {

}
//登录注册
const login = () => {
  state.loginVisible = true
}
//返回登录
const backLogin = () => {
  state.tipShow = false
  state.loginVisible = true
}

//注册
const register = () => {
  state.tipShow = true
  state.loginVisible = false
}
//获取验证码
const getCode = () => {
  state.isDisabled = true;
  var telReg = /^1[2|3|4|5|6|7|8|9][0-9]{9}$/;
  if(ruleForm.phone){
    state.isDisabled = false;
    ElMessage({
      message: "手机号码不能为空",
      type: 'error',
    })
  }else if(!telReg.test(ruleForm.phone)){
    state.isDisabled = false;
    ElMessage({
      message: "手机号码格式不正确",
      type: 'error',
    })
  }else{
    let data = {
      phone:ruleForm.phone
    }
    getCodes(data)
    let interval = window.setInterval(function() {
      state.buttonName = '' + state.sTime + '秒后重新发送';
      --state.sTime;
      if(state.sTime < 0) {
        state.buttonName = "重新发送";
        state.sTime = 60;
        state.isDisabled = false;
        window.clearInterval(interval);
      }
    }, 1000);
  }
}

const getCodes = (data) => {
 //获取验证码接口
}

//注册弹窗
const wenTi = () => {
  state.tipShow = false
  state.loginVisible = false
  // refreshCode()
}

// 忘记密码
const forgetPwd = () => {
  state.forgetVisible = true
}

const getSteps = (i:number) => {
  if(i == 0){
    var telReg = /^1[2|3|4|5|6|7|8|9][0-9]{9}$/;
    if(!ruleForm.phone){
      ElMessage({
        message: "请输入手机号码",
        type: 'error',
      })
    }else if(!telReg.test(ruleForm.phone)){
      ElMessage({
        message: "手机号码格式不正确",
        type: 'error',
      })
    }else if(!ruleForm.code){
      ElMessage({
        message: "请输入验证码",
        type: 'error',
      })
    }else{
      state.getShow = i+1
    }
  }else{
    if(!ruleForm.password){
      ElMessage({
        message: "请输入密码",
        type: 'error',
      })
    }else if(!ruleForm.rePassword){
      ElMessage({
        message: "请再次输入密码",
        type: 'error',
      })
    }else if(ruleForm.password !== ruleForm.rePassword){
      ElMessage({
        message: "两次密码不一致",
        type: 'error',
      })
    }else{
      let data = {
        'username':ruleForm.phone,
        'code':ruleForm.code,
        'newspassword':ruleForm.password
      }
     //忘记密码接口
    }
  }
}
const userLogin = () => {

}

const handleClick = () => {

}
</script>

<style lang="scss" scoped>
:deep(.el-input__inner){
  height: 40px;
  line-height: 40px;
  width: 100%;
}
//登录注册
.hj_login{
  .hj_code{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    .get_cod{
      width:200px;
      color:#fff !important;
      font-size: 14px;
      background-color: #173C80;
      border-color:#173C80;
      height:40px;
      line-height: 40px;
      margin-left:22px;
      border-radius: 4px !important;
      &:hover{
        background-color: #4570AB;
        color:#fff;
        border:1px solid #4570AB;
      }
      :deep(span){
        color:#fff !important;
      }
    }
  }
  padding:0 22px;
  :deep(.el-input){
    height: 42px;
  }
  :deep(.el-input__inner){
    -webkit-appearance: none;
    border-radius: 4px;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    font-size: inherit;
    height: 40px;
    line-height: 40px;
    outline: 0;
    padding: 0 15px;
    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
    width: 100%;
  }
  .hj_other{
    >div{
      line-height: inherit !important;
    }
    .hj_aggrens{
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      width:100%;
      :deep(.el-checkbox__label){
        color:#333 !important;
        font-size: 14px !important;
        font-weight: inherit !important;
      }
      span:hover{
        cursor: pointer;
      }
      div{
        display: flex;
        justify-content: flex-end;
        align-items: center;
        span{
          display: inline-block;
          font-size: 14px;
          color:#999;
          font-weight: bold;
          &:hover{
            cursor: pointer;
          }
        }
        b{
          display: inline-block;
          height:10px;
          width:1px;
          background-color: #999;
          margin-left:12px;
          margin-right:12px;
        }
      }
    }
  }
}
//商务合作
.title{
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin-top:-42px;

  div{
    text-align: center;
    padding: 10px 14px;
  }
  span{
    width:100%;
    display: block;
    text-align: center;
    font-size: 18px;
    margin-bottom: 32px;
    color:#333;
  }
}
.hj_two{
  width:100%;
}
.hj_reg_btn{
  width:100%;
  height:42px;
  font-size: 16px;
}
.common-ruleForm{
  padding:12px 32px 0 32px;
  :deep(div){
    width:100%;
  }
}
.el_full_box{
  .el-header{
    position: fixed;
    left:0;
    top:0;
    width:100%;
    padding:0;
    height:80px;
    z-index: 1000;
    background-color: var(--el-navbar_bg);
    .hj_box{
      background-color: var(--el-navbar_bg);
      box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .05);
      width:100%;
      height:50px;
      overflow: hidden;
      .nave_bar{
        display: flex;
        justify-content: space-between;
        align-items: center;
        .hj_search{
          width:120px;
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          .search_lf_box{
            width:100%;
            border-top-left-radius: 45px;
            border-bottom-left-radius: 45px;
            border-bottom-right-radius: 12px;
            border-top-right-radius: 12px;
            .search_box{
              position: relative;
              display: flex;
              justify-content: space-between;
              :deep(.el-input__inner){
                width: 90px;
                height: 32px;
                font-size: 12px;
                //border:1px solid var(--el-border-color-base)
                border:none;
              }
              //:deep(.el-input__wrapper ){
              //  justify-content: flex-end;
              //}
              >div{
                float: right;
                width: 100%;
                height: 32px;
                border-radius: 45px;
              }

              .sou_action{
                display: flex;
                justify-content: center;
                align-items: center;
                &:hover{
                  cursor: pointer;
                }
                .hj_btn{
                  width:22px;
                  height:22px;
                  color:#fff;
                  border-radius: 45px;
                  text-align: center;
                  margin-top:6px;
                  &:hover{
                    cursor: pointer;
                  }
                }
                b{
                  display: inline-block;
                  width:1px;
                  height:28px;
                  background-color: #efefef;
                  margin-right:5px;
                }
              }

            }
          }
          .hj_ruzhu{
            display: flex;
            flex-direction: column;
            margin-left:22px;
            min-width: 170px;
            text-align: right;
            div{
              display: flex;
              flex-direction: row;
              justify-content: flex-end;
              align-items: center;
              .hj_rt{
                b{
                  display: flex;
                  margin-left:16px;
                  margin-right:16px;
                  height:16px;
                  width:1px;
                  background-color:var(--el-text-color-primary);
                }
                ul{
                  overflow: hidden;
                  display: flex;
                  flex-direction: row;
                  padding-left:0;
                  li{
                    display: flex;
                    flex-direction: row;
                    cursor: pointer;
                    align-items: center;
                    a{
                      display: flex;
                      justify-content: flex-start;
                      align-items: center;
                    }
                    .user_name{
                      display: inline-block;
                      width:50px;
                      color:#00adff !important;
                    }
                    .hj_lo{
                      display: inline-block;
                      width:33px;
                    }
                    .hj_ccc{
                      width:32px;
                    }
                    .hj_cc{
                      display: inline-block;
                      width:68px;
                    }
                  }
                }
              }
              span{
                font-size: 14px;
                color:#fff;
              }
            }

          }
        }
        .c_logo{
          display: flex;
          justify-content: flex-start;
          align-items: center;
          span{
            display: inline-block;
            font-size:18px;
            color:var(--el-text-color-bar);
            font-weight: 400;
          }

        }
        .el-menu-tabs{
          display: flex;
          justify-content: space-between;
          a{
            padding:0 10px;
            font-weight:400;
            font-size:14px;
            text-decoration:none;

          }
        }
      }
      .hj_container {
        max-width: 1200px;
        min-width: 1100px;
        margin: 0 auto;
        height:52px;
        .el-menu_box{
          display: flex;
          justify-content: space-between;
          align-items: center;
          border-bottom: 1px solid var(--el-navbar_bg);
          height:60px;
          width:100%;
          li{
            height:60px;
            line-height: 60px;
          }
        }
      }
    }
    .hj_title_box{
      height:36px !important;
      >span{
        font-size: 13px;
        color:var(--el-text-color-cls);
      }

    }

    .hj_container{
      max-width: 1200px;
      min-width: 1100px;
      margin:0 auto;
      padding: 0 22px 0 22px;
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      position: relative;
      height:100px;
      .hj_header{
        height: 95px;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        .hj_title{
          min-width: 367px;
          display: flex;
          justify-content: flex-start;
          flex-direction: column;
          strong{
            font-weight: 700;
            font-family: Microsoft YaHei;
            font-size: 24px;
            color: var(--el-logo_bg);
          }
          span{
            font-family: Times New Roman;
            font-size: 12px;
            color: var(--el-en_bg);
          }
        }
      }
      .hj_search{
        display: flex;
        flex-direction: row;
        justify-content: flex-end;
        .hj_ruzhu{
          display: flex;
          flex-direction: column;
          justify-content: flex-end;
          margin-left:22px;
          min-width: 170px;
          text-align: right;
          position: relative;
          .hj_rt{
            :deep(.el-switch__action) {
              display: none;
            }
            :deep(.el-switch) {

            }
            .hj_span1{
              display: inline-block;
              width:72px;
              &:hover{
                color:#ff3f29;
              }
            }
            ul{
              overflow: hidden;
              display: flex;
              flex-direction: row;
              padding-left:0;
              li{
                display: flex;
                flex-direction: row;
                cursor: pointer;
                align-items: center;
                .hj_theme{
                  margin-left:22px;
                  :deep(.el-input__inner) {
                    font-size: 12px;
                    border:1px solid var(--el-border-color-base)
                  }
                }

                .u_img{
                  width:32px;
                  height:32px;
                  margin-right:8px;
                }
                a{
                  display: flex;
                  justify-content: flex-start;
                  align-items: center;
                }
                span{
                  font-size: 13px;
                  color:var(--el-text-color-cls);
                  &:hover{
                    color:#ff3f29;
                  }
                }
                b{
                  display: flex;
                  margin-left:16px;
                  margin-right:16px;
                  height:10px;
                  width:1px;
                  background-color:var(--el-text-color-cls);
                }
              }
            }
          }
          .hj_phone{
            position: absolute;
            bottom:-14px;
            right:6px;
            font-size: 14px;
            color:#FF0200;
            text-align: center;
            margin-top:12px;
            animation:mymove 5s infinite;
            -webkit-animation:mymove 5s infinite;
            animation-direction:alternate;
            animation-timing-function: ease-in-out;
            -webkit-animation:mymove 5s infinite;
            -webkit-animation-direction:alternate;
            -webkit-animation-timing-function: ease-in-out;
          }
          @keyframes mymove
          {
            0%{
              transform: scale(1);  /*开始为原始大小*/
            }
            25%{
              transform: scale(1.1); /*放大1.1倍*/
            }
            50%{
              transform: scale(1);
            }
            75%{
              transform: scale(1.1);
            }

          }

          @-webkit-keyframes mymove /*Safari and Chrome*/
          {
            0%{
              transform: scale(1);  /*开始为原始大小*/
            }
            25%{
              transform: scale(1.1); /*放大1.1倍*/
            }
            50%{
              transform: scale(1);
            }
            75%{
              transform: scale(1.1);
            }
          }
          img{
            margin-left:12px;
          }
          div{
            display: flex;
            flex-direction: row;
            justify-content: flex-end;
            align-items: center;
            span{
              font-size: 14px;
            }
          }

        }
        .search_lf_box{
          width:45%;
          padding-left:4px;
          .search_box{
            position: relative;
            padding-right:37px;
            >div{
              height:39px;
              border: var(--el-input-bg-color);
              border-top-left-radius: 45px;
              border-bottom-left-radius: 45px;
            }
            .hj_btn{
              position: absolute;
              right:32px;
              top:0px;
              width:89px;
              z-index: 99;
              height:39px;
              background-color: var(--el-navbar_bg);
              color: var(--el-color-primary);
              border-top-left-radius: 0px;
              border-top-right-radius: 12px;
              border-bottom-left-radius: 0px;
              border-bottom-right-radius: 12px;
              text-align: center;
              &:hover{
                border:1px solid #548DD4;
                background-color: var(--el-hover-bg-color);
              }
            }
            span{
              font-size: 16px;
              color:#fff;
            }
            span:hover{
              color:#fff !important;
            }
          }
        }
      }
    }
  }
  .el_main{
    width: 100%;
    margin-top:86px;
    min-height: 70vh;
    background-color: var(--el-background-color-base);
    padding: 0;
  }
  .el_footer{
    padding:0;
    .hj_footer{
      width:100%;
      background-color: var(--el-footer-bg);
      padding-top: 24px;
      padding-bottom: 24px;
      background-image: url('assets/images/footer-logo-dark.png');
      background-position: 50%;
      background-size: 100%;
      padding:32px 0;
      background-repeat: no-repeat;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      align-items: center;
      .hj_shuoming{
        color:var(--el-text-color-th);
        font-size: 14px !important;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        span{
          color:var(--el-text-color-th);
          font-size: 14px !important;
        }

      }
      .hj_bei{
        font-size: 14px !important;
        margin:12px 0 32px 0;
        color:var(--el-text-color-th);
        a{
          text-decoration: none;
          font-size: 14px;
          color:var(--el-text-color-th);
          display: inline-block;
          margin-left:6px;
        }
      }
      .footer_box{
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        max-width: 1200px;
        min-width: 1100px;
        margin:0 auto;
        padding: 0 6px 0 6px;
        margin-bottom: 32px;
        a{
          margin-bottom: 12px;
          display: inline-block;
          font-size: 16px;
          color: var(--el-text-color-secondary);
          text-decoration: none;
          vertical-align: top;
        }
        img{
          width:120px;
          height:120px;
        }
        .lf{
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          width:100%;
          h6,span{
            font-size: 16px;
            color: var(--el-text-color-primary);
          }
          h6{
            padding-left:42px;
          }
          >div{
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            .footer_phone {
              flex-direction: row !important;
              justify-content: flex-start;
              align-items: center;
              div:first-child{
                padding-left:42px;
                a{
                  display: inline-block;
                  font-size: 14px;
                }
              }
              div{
                a:first-child{
                  margin-right:22px;
                }
                a{
                  display: inline-block;
                  font-size: 14px;
                }
              }
              h4{
                border-bottom: 0;
                font-size: 20px;
                color:#fff;
                margin-top:32px;
              }
              span{
                font-size: 20px;
                color:#fff;
              }
              img{
                width:67px;
                height:70px;
              }
            }
          }
          .hj_href{
            a{
              display: inline-block;
              margin-right:42px;
            }
          }
        }
        .rt{
          display: flex;
          justify-content: flex-end;
          width:25%;
          span{
            display: block;
            font-size: 14px;
            color:var(--el-text-color-secondary);
            margin-top:8px;
          }
          div{
            width:100%;
            display: flex;
            justify-content: flex-end;
            align-items: center;
            div{
              display: flex;
              justify-content: center;
              flex-direction: column;
              align-items: center;
            }
          }

        }
      }

    }

  }

}
</style>

附加:城市选择组件引入及使用

1、首先引入 element-china-area-data

npm install element-china-area-data

2、其次我们在plugins 引入城市选择插件。 新建 city.client.ts

import { regionData ,CodeToText,TextToCode} from 'element-china-area-data'
// @ts-ignore
import { defineNuxtPlugin } from '#app'

export default defineNuxtPlugin(nuxtApp => {
    // @ts-ignore
    // return nuxtApp.vueApp.use(regionData)
    return {
        provide: {
            regionData,
            CodeToText,
            TextToCode
        }
    }
})

最后我们在default.vue 引入

const { $router, $regionData,$TextToCode, $CodeToText } = useNuxtApp()

//使用
const handleChange = (value) => {
  ruleForm.region = $CodeToText[value[0]]+'/'+$CodeToText[value[1]]+'/'+$CodeToText[value[2]]
  ruleForm.sheng = $CodeToText[value[0]]
  ruleForm.shi = $CodeToText[value[1]]
  ruleForm.xian = $CodeToText[value[2]]
}

//默认赋值
state.selectedOptions = [
  $TextToCode ['河南省'].code,
  $TextToCode ['河南省']['郑州市'].code,
  $TextToCode ['河南省']['郑州市']['金水区'].code
]

效果图如下:

城市选择运行效果图