项目实训:虚拟现实环境下的远程教育和智能评估系统(十一)

学生端前端的页面组件编写

在我们的前端页面中,我定义了多个页面的组件

具体包括:

用户个人资料和导航菜单组件

<template>
  <header class="side_box">
    <div class="menu_panel">
      <h3 class="title"><i class="iconfont">&#xe60a;</i>个人资料</h3>
      <ul class="menus">
        <li :class="{on: type == 'wdkc'}">
          <router-link :to="{name: 'account-course'}">我的课程</router-link>
        </li>
        <li :class="{on: type == 'wdsc'}">
          <router-link :to="{name: 'account-collect'}">我的收藏</router-link>
        </li>
        <li :class="{on: type == 'wddd'}">
          <router-link :to="{name: 'account-order'}">我的订单</router-link>
        </li>
        <li :class="{on: type == 'grxx'}">
          <router-link :to="{name: 'account'}">个人信息</router-link>
        </li>
      </ul>
    </div>
  </header>
</template>
<script>
import bq from 'bq-static'

export default {
  props: {
    type: {
      type: String,
      default: 'wdkc'
    }
  },
  data() {
    return {
      websiteInfo: this.$store.state.websiteInfo,
      tokenInfo: this.$store.state.tokenInfo,
      userInfo: this.$store.state.userInfo
    }
  },
  mounted() {
    bq()
  },
  methods: {
    close() {
      this.$emit('close')
    }
  }
}
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
.side_box {
  border-radius: 6px 6px 0 0;
  float: left;
  width: 168px;
}

.menu_panel {
  background-color: #fff;
  margin-bottom: 20px;
  border-radius: 6px 6px 0 0;

  .act_icon {
    width: 16px;
    margin-right: 2px;
  }

  .title {
    font-size: 14px;
    color: #333;
    line-height: 60px;
    padding: 0 35px;
    border-bottom: 1px solid rgb(242, 242, 242);

    i {
      padding-right: 6px;
      font-size: 16px;
      position: relative;
      left: -5px;
    }
  }
}

.menus {
  li {
    line-height: 40px;
    // padding-left: 35px;
    text-align: center;

    &:hover, &.on {
      a {
        color: #D51423;
      }
    }
  }

  a {
    color: #333;
    font-size: 14px;
  }
}
</style>

可复用的消息框组件,该组件具有可配置的标题、内容、按钮文本和输入框。

<template>
  <div v-show="isShowMessageBox" class="message-box">
    <div class="mask" @click="cancel" />
    <div class="message-content">
      <h3 class="title">{{ title }}</h3>
      <p class="content">{{ content }}</p>
      <div>
        <!-- eslint-disable-next-line  -->
        <input v-if="isShowInput" ref="input" v-model="inputValue" type="text">
      </div>
      <div class="btn-group">
        <button v-show="isShowCancelBtn" class="btn-default solid_btn" @click="cancel">{{ cancelBtnText }}</button>
        <button v-show="isShowConfimrBtn" class="btn-primary btn-confirm solid_btn" @click="confirm">{{ confirmBtnText }}</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: '提示'
    },
    content: {
      type: String,
      default: '内容'
    },
    isShowInput: {
      type: Boolean,
      default: false
    },
    inputValue: {
      type: String,
      default: ''
    },
    isShowCancelBtn: {
      type: Boolean,
      default: true
    },
    isShowConfimrBtn: {
      type: Boolean,
      default: true
    },
    cancelBtnText: {
      type: String,
      default: '取消'
    },
    confirmBtnText: {
      type: String,
      default: '确定'
    }
  },
  data() {
    return {
      isShowMessageBox: false,
      resolve: '',
      reject: '',
      promise: '' // 保存promise对象
    }
  },
  methods: {
    // 确定,将promise断定为resolve状态
    confirm: function() {
      this.isShowMessageBox = false
      if (this.isShowInput) {
        this.resolve(this.inputValue)
      } else {
        this.resolve('confirm')
      }
      this.remove()
    },
    // 取消,将promise断定为reject状态
    cancel: function() {
      this.isShowMessageBox = false
      this.reject('cancel')
      this.remove()
    },
    // 弹出messageBox,并创建promise对象
    showMsgBox: function() {
      this.isShowMessageBox = true
      this.promise = new Promise((resolve, reject) => {
        this.resolve = resolve
        this.reject = reject
      })
      // 返回promise对象
      return this.promise
    },
    remove: function() {
      setTimeout(() => {
        this.destroy()
      }, 300)
    },
    destroy: function() {
      this.$destroy()
      document.body.removeChild(this.$el)
    }
  }
}
</script>
<style lang="scss" scoped>
.message-box {
  position: relative;
  top: 50%;
  left: 50%;
  z-index: 10009;
}

.message-content {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 999;
  width: 470px;
  margin-left: -235px;
  margin-top: -140px;
  background-color: #fff;
  border-radius: 8px;
  overflow: hidden;

  .title {
    line-height: 45px;
    padding: 0 20px;
    background-color: #f9f9f9;
    font-size: 16px;

    .close {
      float: right;
    }
  }

  .content {
    text-align: center;
    padding: 40px 0;
    font-size: 16px;
  }
}

.btn-group {
  padding: 12px;
  text-align: center;

  .btn-default {
    background-color: #eee;
    border-color: #ddd;
    color: #666;
  }
}
</style>

轮播图组件,具有自动播放和鼠标悬停暂停的功能

<template>
  <div class="banner">
    <ul :style="'height:'+ height+ 'px;'" @mouseout="mout" @mouseover="mover">
      <li v-for="(item, index) in data" :key="index" class="item" :style="'background-image: url('+item.carouselImg+');'" :class="{on:index === num}">
        <a :href="item.carouselUrl" :title="item.carouselTitle" :target="item.carouselTarget" />
      </li>
    </ul>
    <ul class="page_dots">
      <span v-for="(item, index) in data" :key="index" class="dots" :class="{on:index === num}" @mouseenter="num = index" />
    </ul>
    <y-category :height="height" :list="categoryList" />
  </div>
</template>
<script>
import YCategory from './Category'

export default {
  components: {
    YCategory
  },
  props: {
    data: {
      type: [Object, Array],
      default: null
    },
    categoryList: {
      type: [Object, Array],
      default() {
        return []
      }
    },
    height: {
      type: [String, Number],
      default: 456
    }
  },
  data() {
    return {
      websiteInfo: this.$store.state.websiteInfo,
      num: 0,
      interval: null
    }
  },
  mounted() {
    // console.log(this.data)
    this.change()
  },
  methods: {
    change() {
      this.interval = setInterval(() => {
        if (this.num + 1 >= this.data.length) {
          this.num = 0
        } else {
          this.num++
        }
      }, 3000)
    },
    mout() {
      this.change()
    },
    mover() {
      clearInterval(this.interval)
    }
  }
}
</script>
<style lang="scss" scoped>
.banner {
  position: relative;
  width: 1200px;
  margin: 20px auto;
  ul {
    position: relative;
  }

  .item {
    opacity: 0;
    height: 100%;
    background-position: center center;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9;
    transition: all 1s;
    border-radius: 10px;

    &.on {
      opacity: 1;
      z-index: 10;
    }

    a {
      width: 100%;
      height: 100%;
      display: block;
    }
  }

底部信息展示组件,其中包括网站版权信息和备案号相关的内容

<template>
  <div class="i_bottom">
    <div v-if="service.websiteCopyright" class="copyright">
      <span v-html="service.websiteCopyright" />
    </div>
    <!-- <div class="icp_num">
      <a href="http://www.doityun.com/" target="_blank" class="lingke_link">IT云提供计算服务</a>
      <span v-if="service.websiteIcp">&nbsp;|&nbsp;
        <a href="http://www.miitbeian.gov.cn/" target="_blank" class="lingke_link">{{ service.websiteIcp }}</a>
      </span>
      <span v-if="service.websitePrn">&nbsp;|&nbsp;
        <a :href="'http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=' + service.websitePrnNo" target="_blank" class="lingke_link"><img src="~/assets/image/prn_icon.png" class="prn_icon" alt="">&nbsp;{{ service.websitePrn }}</a>
      </span>
    </div> -->
  </div>
</template>
<script>

export default {
  name: 'Bottom',
  data() {
    return {
      service: this.$store.state.websiteInfo || {}
    }
  },
  mounted() {
  }
}
</script>
<style lang="scss" rel="stylesheet/scss">
.i_bottom {
  background: rgb(51, 51, 51);
  padding: 12px 0;
}

.copyright {
  height: 30px;
  line-height: 30px;
  text-align: center;
  color: #ccc;

  a {
    color: #ccc;
  }
}

.icp_num {
  line-height: 30px;
  text-align: center;
  color: #ccc;

  .lingke_link {
    color: #ccc;

    &:hover {
      text-decoration: underline;
    }
  }
}

.prn_icon {
  width: 16px;
  height: 16px;
  position: relative;
}

</style>

等等

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值