tremble 6 år sedan
förälder
incheckning
728ceff1ce

+ 18 - 19
src/App.vue

@@ -1,10 +1,11 @@
 <template>
   <div id="app">
     <div class="big-nav">
-      <iheader />
-      <inavs />
+      <iheader>
+        <inavs slot-scope="{cp, split}" :cp="cp" :split="split"/>
+      </iheader>
     </div>
-    <div class="mask" :class="{active: cp}" :style="{zIndex: maskZIndex}"></div>
+    <div class="mask" :class="{active: showMask}" :style="{zIndex: maskZIndex}"></div>
     <!-- <ichat /> -->
     <router-view/>
     <ifooter v-if="$route.name!=='about'" />
@@ -12,7 +13,6 @@
 </template>
 
 <script>
-import {mapState} from 'vuex'
 import '@/assets/style/reset.scss'
 import '@/assets/style/public.scss'
 import '@/assets/imgfont/iconfont.css'
@@ -27,7 +27,8 @@ export default {
   name: 'App',
   data () {
     return {
-      maskZIndex: -1
+      maskZIndex: -1,
+      showMask: false
     }
   },
   components: {
@@ -37,22 +38,20 @@ export default {
     inavs: navs,
     ichat: chat
   },
-  computed: {
-    ...mapState({
-      cp: state => state.ui.nav
+  mounted () {
+    this.$bus.$on('showMask', () => {
+      clearTimeout(this.timeout)
+      this.maskZIndex = 3
+      this.showMask = true
     })
-  },
-  watch: {
-    cp (newVal) {
+
+    this.$bus.$on('hideMask', () => {
       clearTimeout(this.timeout)
-      if (newVal) {
-        this.maskZIndex = 993
-      } else {
-        this.timeout = setTimeout(() => {
-          this.maskZIndex = -1
-        }, 700)
-      }
-    }
+      this.showMask = false
+      this.timeout = setTimeout(() => {
+        this.maskZIndex = -1
+      }, 700)
+    })
   }
 }
 </script>

+ 1 - 1
src/page/home2/index.vue

@@ -68,7 +68,7 @@
         <div class="item item-2">
           <div class="media iframe">
             <div>
-            <iframe src="http://www.4dmodel.com/SuperTwo/index.html?m=158&version=one" frameborder="0"></iframe>
+            <!-- <iframe src="http://www.4dmodel.com/SuperTwo/index.html?m=158&version=one" frameborder="0"></iframe> -->
             </div>
           </div>
           <div class="content">

+ 51 - 43
src/page/layout/header/index.vue

@@ -1,28 +1,37 @@
 <template>
-  <div class="header-layout" :class="{active: headActive}" @mouseenter="active = true" @mouseleave="active = false">
-    <router-link :to="{name: 'home'}" class="logo">
-      <i class="iconfont icon-logo_a"></i>
-      <i class="iconfont icon-logo_b"></i>
-    </router-link>
+  <div class="header-layout">
+    <div class="logo-layout">
+      <router-link :to="{name: 'home'}" class="logo">
+        <i class="iconfont icon-logo_a"></i>
+        <i class="iconfont icon-logo_b"></i>
+      </router-link>
+    </div>
     <div class="menu">
       <div class="lang">
-        <a :class="{active: language === 'en'}" @click="$store.commit('change_language', 'en')">En</a>
-        <a :class="{active: language === 'cn'}" @click="$store.commit('change_language', 'cn')">Cn</a>
+        <vcenter>
+          <a :class="{active: language === 'en'}" @click="$store.commit('change_language', 'en')">En</a>
+          <a :class="{active: language === 'cn'}" @click="$store.commit('change_language', 'cn')">Cn</a>
+        </vcenter>
       </div>
-      <div class="list">
+      <div class="list" ref="list" @mouseleave="hoverCp !== 'isearch' && hideCp()">
         <a
           v-for="nav in navs"
           :key="nav.text"
-          @mouseover="overHandle(nav)"
-          @mouseout="outHandle"
+          @mouseenter="hoverCp !== 'isearch' && showCp(nav.cp, 135)"
           @click="clickHandle(nav)"
-          :class="{active: cp === nav.cp}">
+          :class="{active: hoverCp === nav.cp}">
           {{nav.text}}
         </a>
+
+        <div class="child-layout" :style="{maxHeight: height + 'px'}">
+          <i class="silp" :style="{left: split + 'px'}"></i>
+          <slot :split="split" :cp="hoverCp" />
+        </div>
+
       </div>
     </div>
     <div class="ctrl">
-      <a class="search" @click="$store.commit('change_nav', 'isearch')" :class="{active: cp === 'isearch'}">
+      <a class="search" @click="searchHandle" :class="{active: hoverCp === 'isearch'}">
         <vcenter>
           <i class="iconfont icon-sousuo open"></i>
           <i class="iconfont icon-cuo hide"></i>
@@ -41,12 +50,16 @@
 <script>
 import {mapState} from 'vuex'
 import vcenter from '@/components/vcenter'
+import { getPosition } from '@/util'
 
 export default {
   data () {
     return {
+      height: 0,
+      hoverCp: null,
+      split: 0,
       overb: false,
-      active: false,
+      active: true,
       navs: [
         {text: '产品购买', cp: 'iproduct'},
         {text: '核心技术', cp: 'videos'},
@@ -60,52 +73,47 @@ export default {
     clickHandle (nav) {
       this.$router.push({name: nav.cp})
     },
-    overHandle (nav) {
+    showCp (cp, height) {
+      this.$bus.$emit('showMask')
       clearTimeout(this.timeout)
-      this.$store.commit('change_nav', nav.cp)
+      this.hoverCp = cp
+      this.height = height
     },
-    outHandle () {
+    hideCp () {
+      this.$bus.$emit('hideMask')
+      this.height = 0
       clearTimeout(this.timeout)
       this.timeout = setTimeout(() => {
-        this.$store.commit('change_nav', '')
-      }, 300)
+        this.hoverCp = null
+      }, 700)
+    },
+    searchHandle () {
+      if (this.hoverCp === 'isearch') {
+        this.hideCp()
+      } else {
+        this.showCp('isearch', window.innerHeight - 68)
+      }
     }
   },
   computed: {
     ...mapState({
-      language: state => state.language.current,
-      cp: state => state.ui.nav
-    }),
-    headActive () {
-      return this.active || this.cp || this.overb
-    }
-  },
-  watch: {
-    cp (newVal) {
-      let nav = this.navs.find(nav => nav.cp === newVal)
-      nav && nav.to && this.$router.push(nav.to)
-    }
+      language: state => state.language.current
+    })
   },
   mounted () {
-    this.scrollHandle = () => {
-      this.overb = (window.scrollY || window.pageYOffset) > 0
+    this.sizeHandle = () => {
+      this.split = getPosition(this.$refs.list).x
     }
-    window.addEventListener('scroll', this.scrollHandle)
-    this.$bus.$on('nav_over', () => {
-      clearTimeout(this.timeout)
-    })
-    this.$bus.$on('nav_out', () => {
-      let index = this.navs.findIndex(nav => nav.cp === this.cp)
-      ~index && this.$store.commit('change_nav', '')
-    })
+    window.addEventListener('resize', this.sizeHandle)
+    setTimeout(this.sizeHandle, 300)
   },
-  beforeDestroy () {
-    window.removeEventListener('scroll', this.scrollHandle)
+  destroyed () {
+    window.removeEventListener('resize', this.sizeHandle)
   },
   components: {vcenter}
 }
 </script>
 
 <style lang="scss" scoped>
-@import './style.scss';
+@import './istyle.scss';
 </style>

+ 175 - 0
src/page/layout/header/istyle.scss

@@ -0,0 +1,175 @@
+.header-layout {
+  $ts: all .7s cubic-bezier(.77, 0, .175, 1);
+  $split: #7f7f7f;
+  background-color: #101010;
+  display: flex;
+  color: #fff;
+  justify-content: space-between;
+
+  .child-layout {
+    position: absolute;
+    top: 100%;
+    max-height: 0;
+    left: 0;
+    right: 0;
+    transition: $ts;
+    overflow: hidden;
+
+    .silp {
+      position: absolute;
+      width: 1px;
+      height: 100%;
+      background-color: $split;
+      z-index: 2;
+    }
+  }
+
+  .logo-layout {
+    flex: 0 1 340px;
+    text-align: center;
+
+    .logo {
+      position: relative;
+      width: 150px;
+      height: 100%;
+      display: inline-block;
+
+      i {
+        position: absolute;
+        left: 50%;
+        top: 60%;
+        transform: translateX(-50%) translateY(-50%);
+      }
+
+      .icon-logo_b {
+        font-size: 110px;
+        color: #fff;
+      }
+
+      .icon-logo_a {
+        font-size: 40px;
+        margin-left: -48px;
+        margin-top: -6px;
+        color: #1fe4dc;
+      }
+    }
+  }
+
+  .menu {
+    display: flex;
+    justify-content: space-evenly;
+    width: 940px;
+
+    .lang {
+      box-sizing: border-box;
+      text-align: center;
+      padding-right: 10px;
+
+      a {
+        display: inline-block;
+        font-size: 16px;
+        font-weight: bold;
+        margin-left: 5px;
+      }
+    }
+
+    .list {
+      border-left: 1px solid $split;
+      padding: 0 20px;
+      display: flex;
+      min-width: 480px;
+      max-width: 750px;
+      justify-content: space-between;
+      flex: 1;
+
+      a {
+        display: inline-block;
+        padding: 25px 20px 25px 0;
+        font-size: 16px;
+        text-decoration: none;
+        font-weight: bold;
+        position: relative;
+        flex: auto;
+
+        &::after {
+          display: none;
+          content: '';
+          border: 6px solid transparent;
+          position: absolute;
+          right: 0;
+          top: 50%;
+          transform: translateY(-50%);
+        }
+      }
+    }
+  }
+
+  .ctrl {
+    flex: 0 0 auto;
+
+    a {
+      display: inline-block;
+      text-decoration: none;
+      padding: 0 14px;
+      height: 100%;
+
+      i,
+      span {
+        display: inline-block;
+        vertical-align: middle;
+      }
+
+      i {
+        font-size: 24px;
+      }
+
+      span {
+        font-size: 16px;
+        margin-left: 4px;
+        font-weight: bold;
+      }
+
+      &.user {
+        background-color: #fff;
+        color: #101010
+      }
+    }
+
+    .search {
+      position: relative;
+
+      .hide,
+      .open {
+        transition: $ts
+      }
+
+      .open {
+        opacity: 1;
+        transform: scale(1);
+      }
+
+      .hide {
+        opacity: 0;
+        transform: scale(0);
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translateX(-50%) translateY(-50%);
+        font-size: 16px;
+      }
+
+      &.active {
+        .open {
+          opacity: 0;
+          transform: scale(0);
+        }
+
+        .hide {
+          opacity: 1;
+          transform: scale(1) translateX(-50%) translateY(-50%);
+        }
+      }
+    }
+  }
+
+}

+ 29 - 31
src/page/layout/header/style.scss

@@ -57,10 +57,10 @@
     $margin: 25px;
     $lrwidth: 340px;
     $ts: all .7s cubic-bezier(.77,0,.175,1);
+    justify-content: space-between;
 
     background-color: $bgcolor;
-    position: relative;
-    padding: 0 120px 0 238px;
+    display: flex;
 
     .logo .icon-logo_b {
       transition: $ts;
@@ -125,41 +125,40 @@
       z-index: 1
     }
 
-    .logo {
-      z-index: 2;
-      position: absolute;
-      width: $lrwidth;
-      height: 100%;
-      left: 0;
-      top: 0;
+    .logo-layout {
+      flex: 0 1 340px;
+      text-align: center;
+    
+      .logo {
+        width: 150px;
+        z-index: 2;
+        position: relative;
+        height: 100%;
+        display: inline-block;
 
-      i {
-        position: absolute;
-        left: 50%;
-        top: 60%;
-        transform: translateX(-50%) translateY(-50%);
-      }
+        i {
+          position: absolute;
+          left: 50%;
+          top: 60%;
+          transform: translateX(-50%) translateY(-50%);
+        }
 
-      .icon-logo_b {
-        font-size: 110px;
-      }
+        .icon-logo_b {
+          font-size: 110px;
+        }
 
-      .icon-logo_a {
-        font-size: 40px;
-        margin-left: -48px;
-        margin-top: -6px;
-        color: #1fe4dc;
+        .icon-logo_a {
+          font-size: 40px;
+          margin-left: -48px;
+          margin-top: -6px;
+          color: #1fe4dc;
+        }
       }
     }
-
     .ctrl {
       z-index: 2;
-      position: absolute;
-      right: 0;
-      top: 0;
-      width: $lrwidth;
-      height: 100%;
       text-align: right;
+      flex: 0 0 auto;
 
       a {
         display: inline-block;
@@ -221,10 +220,9 @@
     .menu {
       z-index: 2;
       $lwidth: 260px;
-      margin: 0 auto;
-      max-width: 1200px;
       padding-left: $lwidth;
       position: relative;
+      flex: 1;
 
       .lang {
         box-sizing: border-box;

+ 9 - 71
src/page/navs/index.vue

@@ -1,11 +1,10 @@
 <template>
-  <div class="second" :style="style" ref="second" @mouseenter="overHandle" @mouseleave="outHandle">
-    <component :is="result" @mouseout.stop />
+  <div class="second" ref="second">
+    <component :is="cp" :split="split"/>
   </div>
 </template>
 
 <script>
-import {mapState} from 'vuex'
 import icase from './case/'
 import isearch from './search/'
 import iproduct from './product/'
@@ -13,64 +12,14 @@ import iservice from './service/'
 import iforum from './forum/'
 
 export default {
-  data () {
-    return {
-      style: {
-        height: 'auto',
-        visibility: 'hidden'
-      },
-      result: ''
-    }
-  },
-  methods: {
-    overHandle () {
-      this.$bus.$emit('nav_over')
-    },
-    outHandle () {
-      this.$bus.$emit('nav_out')
-    }
-  },
-  computed: {
-    ...mapState({
-      cp: state => state.ui.nav
-    })
-  },
-  watch: {
-    cp (newVal, oldVal) {
-      this.timeouts && this.timeouts.forEach(time => {
-        clearTimeout(time)
-      })
-      this.timeouts = []
-      this.timeouts.push(
-        setTimeout(() => {
-          let time = 700
-          if (!newVal && oldVal) {
-            this.style.height = 0 + 'px'
-            this.timeouts.push(setTimeout(() => {
-              this.result = newVal
-            }, time))
-          } else if (!oldVal && newVal) {
-            this.result = newVal
-            this.timeouts.push(setTimeout(() => {
-              this.style.visibility = 'hidden'
-              this.style.height = 'auto'
-              setTimeout(() => {
-                let height = this.$refs.second.offsetHeight
-                this.style.height = 0
-                this.style.visibility = 'visible'
-                this.timeouts.push(setTimeout(() => {
-                  this.style.height = height + 'px'
-                }, 16))
-              }, 16)
-            }, 16))
-          } else {
-            this.result = newVal
-          }
-        }, 50)
-      )
+  props: {
+    split: {
+      default: 0,
+      type: Number
     },
-    result (newVal) {
-      console.log(newVal)
+    cp: {
+      default: '',
+      type: String
     }
   },
   components: {
@@ -82,14 +31,3 @@ export default {
   }
 }
 </script>
-
-<style scoped>
-.second {
-  position: absolute;
-  left: 0;
-  top: 100%;
-  width: 100%;
-  transition: height .5s cubic-bezier(.77,0,.175,1);
-  overflow: hidden;
-}
-</style>

+ 12 - 25
src/page/navs/product/index.vue

@@ -1,18 +1,12 @@
 <template>
-<div>
-  <div class="search-con">
-    <div class="search-ban">
-      <div class="search-camera">
-        <router-link :to="item.to" tag="a" class="camera" v-for="(item,i) in cameraArr" :key="i">
-          <vcenter>
-            <img :src="item.img" >
-            <div style="margin-top:10px;">{{item.name}}</div>
-          </vcenter>
-        </router-link>
-      </div>
-    </div>
+  <div class="search-camera" :style="{paddingLeft: split+'px'}">
+    <router-link :to="item.to" tag="a" class="camera" v-for="(item,i) in cameraArr" :key="i">
+      <vcenter>
+        <img :src="item.img" >
+        <div style="margin-top:10px;">{{item.name}}</div>
+      </vcenter>
+    </router-link>
   </div>
-</div>
 </template>
 
 <script>
@@ -32,6 +26,11 @@ const cameraArr = [{
 }]
 
 export default {
+  props: {
+    'split': {
+      default: 0
+    }
+  },
   components: {
     vcenter
   },
@@ -39,18 +38,6 @@ export default {
     return {
       cameraArr
     }
-  },
-  computed: {},
-  watch: {},
-  // 方法集合
-  methods: {
-
-  },
-  created () {
-
-  },
-  mounted () {
-
   }
 }
 </script>

+ 17 - 31
src/page/navs/product/style.scss

@@ -1,38 +1,24 @@
 $lHeight: 145px;
 
-.search-con {
-  position: relative;
-  width: 100%;
-  padding: 0 340px;
+.search-camera {
   background-color: #fff;
   height: $lHeight;
-  line-height: $lHeight;
   border-bottom: 1px solid #e5e5e5;
-  .search-ban {
-    position: relative;
-    margin: 0 auto;
-    max-width: 1200px;
-    height: $lHeight;
-    .search-camera{
-      margin-left: 260px;
-      display: inline-block;
-      // height: $lHeight;
-      line-height: 0;
-      border-left: #e5e5e5 1px solid;
-      .camera{
-        display: block;
-        height: $lHeight;
-        padding: 0 30px;
-        line-height: 1;
-        text-align: center;
-        font-size: 14px;
-        display: inline-block;
-        color: #ff0000;
-        cursor: pointer;
-        &:first-child{
-          color: #787878;
-        }
-      }
+  display: flex;
+
+  .camera {
+    max-width: 120px;
+    flex: 1;
+    padding: 0 30px;
+    line-height: 1;
+    text-align: center;
+    font-size: 14px;
+    color: #ff0000;
+    cursor: pointer;
+    height: 100%;
+
+    &:first-child {
+      color: #787878;
     }
   }
-}
+}

+ 1 - 1
src/page/navs/search/index.vue

@@ -20,7 +20,7 @@
       <div class="img-con">
         <img :src="require('@/assets/images/search.png')" alt="">
       </div>
-      </div>
+    </div>
     </div>
     <Item :data='items' />
     <div class="more">

+ 35 - 46
src/page/navs/service/index.vue

@@ -1,45 +1,46 @@
 <template>
-<div>
-  <div class="search-con">
-    <div class="search-ban">
-      <div class="search-camera">
-        <router-link :to="item.to" tag="a" class="camera" v-for="(item,i) in serviceArr" :key="i">
-          <vcenter>
-            <img :src="item.img" >
-            <div style="margin-top:10px;">{{item.name}}</div>
-          </vcenter>
-        </router-link>
-      </div>
-    </div>
-  </div>
+<div class="search-camera" :style="{paddingLeft: split + 'px'}">
+  <router-link :to="item.to" tag="a" class="camera" v-for="(item,i) in serviceArr" :key="i">
+    <vcenter>
+      <img :src="item.img" >
+      <div style="margin-top:10px;">{{item.name}}</div>
+    </vcenter>
+  </router-link>
 </div>
 </template>
 
 <script>
 import vcenter from '@/components/vcenter'
-const serviceArr = [{
-  img: require('@/assets/images/service_icon_01@2x.png'),
-  name: '使用教程',
-  to: {name: 'service_list', params: {id: 'use'}}
-}, {
-  img: require('@/assets/images/service_icon_02@2x.png'),
-  name: '常见问题',
-  to: {name: 'service_list', params: {id: 'qa'}}
-}, {
-  img: require('@/assets/images/service_icon_03@2x.png'),
-  name: 'app下载',
-  to: {name: 'service_down'}
-}, {
-  img: require('@/assets/images/service_icon_04@2x.png'),
-  name: '维修服务',
-  to: {name: 'service_support'}
-}, {
-  img: require('@/assets/images/service_icon_05@2x.png'),
-  name: '网站条款',
-  to: {name: 'service_list', params: {id: 'clause'}}
-}]
+const serviceArr = [
+  {
+    img: require('@/assets/images/service_icon_01@2x.png'),
+    name: '使用教程',
+    to: {name: 'service_list', params: {id: 'use'}}
+  }, {
+    img: require('@/assets/images/service_icon_02@2x.png'),
+    name: '常见问题',
+    to: {name: 'service_list', params: {id: 'qa'}}
+  }, {
+    img: require('@/assets/images/service_icon_03@2x.png'),
+    name: 'app下载',
+    to: {name: 'service_down'}
+  }, {
+    img: require('@/assets/images/service_icon_04@2x.png'),
+    name: '维修服务',
+    to: {name: 'service_support'}
+  }, {
+    img: require('@/assets/images/service_icon_05@2x.png'),
+    name: '网站条款',
+    to: {name: 'service_list', params: {id: 'clause'}}
+  }
+]
 
 export default {
+  props: {
+    'split': {
+      default: 0
+    }
+  },
   components: {
     vcenter
   },
@@ -47,18 +48,6 @@ export default {
     return {
       serviceArr
     }
-  },
-  computed: {},
-  watch: {},
-  // 方法集合
-  methods: {
-
-  },
-  created () {
-
-  },
-  mounted () {
-
   }
 }
 </script>

+ 16 - 30
src/page/navs/service/style.scss

@@ -1,38 +1,24 @@
 $lHeight: 145px;
 
-.search-con {
-  position: relative;
-  width: 100%;
-  padding: 0 340px;
+.search-camera {
   background-color: #fff;
   height: $lHeight;
-  line-height: $lHeight;
   border-bottom: 1px solid #e5e5e5;
-  .search-ban {
-    position: relative;
-    margin: 0 auto;
-    max-width: 1200px;
-    height: $lHeight;
-    .search-camera{
-      margin-left: 260px;
-      display: inline-block;
-      border-left: #e5e5e5 1px solid;
-      line-height: 0;
-      .camera{
-        display: block;
-        height: $lHeight;
-        padding: 0 50px;
-        line-height: 1;
-        text-align: center;
-        font-size: 14px;
-        display: inline-block;
-        cursor: pointer;
-        color: #787878;
-        img{
-          height: 70px;
-          width: 70px;
-        }
-      }
+  display: flex;
+
+  .camera {
+    max-width: 120px;
+    flex: 1;
+    padding: 0 30px;
+    line-height: 1;
+    text-align: center;
+    font-size: 14px;
+    cursor: pointer;
+    height: 100%;
+    color: #787878;
+
+    img {
+      width: 100%;
     }
   }
 }

+ 0 - 2
src/page/videos/index.vue

@@ -63,11 +63,9 @@ export default {
     this.timeout = setTimeout(() => {
       let height = getPosition(this.$refs.itemLayout).y
       let items = Array.from(this.$refs.itemLayout.querySelectorAll('.item-layout'))
-      console.log(height)
 
       this.scrollHandle = function () {
         items.forEach(item => {
-          console.log(item.offsetTop)
           if (item.offsetTop + height <= window.innerHeight + window.scrollY - 100) {
             item.classList.remove('hide')
           } else {