专栏首页前端逗逗飞vuecli实现移动端视频类webAPP- 项目基本骨架搭建

vuecli实现移动端视频类webAPP- 项目基本骨架搭建

本节包含如下三部分内容

  • 移动端一像素边框处理
  • 添加阿里图标字体
  • 路由创建(嵌套路由)
  • 底部导航栏 实现
  • 顶部导航栏 实现

创建基本骨架

移动端一像素边框

为什么移动端CSS里面写了1px,实际上看起来比1px粗;是因为UI设计师要求的1px是指设备的物理像素,而CSS里记录的项目是逻辑像素,他们之间存在一个比例关系,我利用媒体查询来解决1像素的问题,如下是我写的移动端一像素边框,可以直接放到项目中使用

@charset "utf-8";
.border,
.border-top,
.border-right,
.border-bottom,
.border-left,
.border-topbottom,
.border-rightleft,
.border-topleft,
.border-rightbottom,
.border-topright,
.border-bottomleft {
   position: relative;
}
.border::before,
.border-top::before,
.border-right::before,
.border-bottom::before,
.border-left::before,
.border-topbottom::before,
.border-topbottom::after,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::before,
.border-topleft::after,
.border-rightbottom::before,
.border-rightbottom::after,
.border-topright::before,
.border-topright::after,
.border-bottomleft::before,
.border-bottomleft::after {
   content: "\0020";
   overflow: hidden;
   position: absolute;
}
/* border
* 因,边框是由伪元素区域遮盖在父级
* 故,子级若有交互,需要对子级设置
* 定位 及 z轴
*/
.border::before {
   box-sizing: border-box;
   top: 0;
   left: 0;
   height: 100%;
   width: 100%;
   border: 1px solid #eaeaea;
   transform-origin: 0 0;
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
   left: 0;
   width: 100%;
   height: 1px;
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
   top: 0;
   width: 1px;
   height: 100%;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
   border-top: 1px solid #eaeaea;
   transform-origin: 0 0;
}
.border-right::before,
.border-rightbottom::before,
.border-rightleft::before,
.border-topright::after {
   border-right: 1px solid #eaeaea;
   transform-origin: 100% 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::before {
   border-bottom: 1px solid #eaeaea;
   transform-origin: 0 100%;
}
.border-left::before,
.border-topleft::after,
.border-rightleft::after,
.border-bottomleft::after {
   border-left: 1px solid #eaeaea;
   transform-origin: 0 0;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
   top: 0;
}
.border-right::before,
.border-rightleft::after,
.border-rightbottom::before,
.border-topright::after {
   right: 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::after {
   bottom: 0;
}
.border-left::before,
.border-rightleft::before,
.border-topleft::after,
.border-bottomleft::before {
   left: 0;
}
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
   /* 默认值,无需重置 */
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
   .border::before {
       width: 200%;
       height: 200%;
       transform: scale(.5);
   }
   .border-top::before,
   .border-bottom::before,
   .border-topbottom::before,
   .border-topbottom::after,
   .border-topleft::before,
   .border-rightbottom::after,
   .border-topright::before,
   .border-bottomleft::before {
       transform: scaleY(.5);
   }
   .border-right::before,
   .border-left::before,
   .border-rightleft::before,
   .border-rightleft::after,
   .border-topleft::after,
   .border-rightbottom::before,
   .border-topright::after,
   .border-bottomleft::after {
       transform: scaleX(.5);
   }
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
   .border::before {
       width: 300%;
       height: 300%;
       transform: scale(.33333);
   }
   .border-top::before,
   .border-bottom::before,
   .border-topbottom::before,
   .border-topbottom::after,
   .border-topleft::before,
   .border-rightbottom::after,
   .border-topright::before,
   .border-bottomleft::before {
       transform: scaleY(.33333);
   }
   .border-right::before,
   .border-left::before,
   .border-rightleft::before,
   .border-rightleft::after,
   .border-topleft::after,
   .border-rightbottom::before,
   .border-topright::after,
   .border-bottomleft::after {
       transform: scaleX(.33333);
   }
}

引入阿里图标字体

为了减少前端项目打包后的体积,常规的做法是 引入图标字体,阿里的图标字体具体怎么申请 自行百度 这个地方就不做讲解了 字体下载成功后 同样需要在main.js中引入

  import 'assets/fonts/iconfont.css'

创建项目路由

  • 找到项目的路由文件夹
  • 修改代码为如下
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    children: [
      {
        path: '/index',
        name: 'index',
        component: () => import(/* webpackChunkName: "index" */ '../views/index/Index.vue'),
      },
      {
        path: '/follow',
        name: 'follow',
        component: () => import(/* webpackChunkName: "fllow" */ '../views/follow/Follow.vue'),
      },
    ],
  },

];

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
});

export default router;

路由采用懒加载的方式引入 另外/ webpackChunkName: "fllow" / 号称是Magic Comments(魔术注释法) 为什么使用嵌套路由

  • 嵌套路由就是在一个被路由过来的页面下可以继续使用路由,嵌套也就是路由中的路由的意思。
  • 为什么要使用嵌套路由

就比如在一个页面中, 在页面的上半部分,有三个按钮,而下半部分是根据点击不同的按钮来显示不同的内容,那么我们就可以在这个组件中的下半部分看成是一个嵌套路由,

也就是说在这个组件的下面需要再来一个, 当我点击不同的按钮时,他们的router-link分别所指向的组件就会被渲染到这个中。

创建底部TabBar

  • 在你的工程内新建Tabbar.vue 代码如下
<template>
  <div class="tab-bar">
    <div class="item" @click="changeTab(0)">
      <router-link to="/index" tag="span" :class="tabIndex === 0 ? 'active':''">首页</router-link>
    </div>
    <div class="item" @click="changeTab(1)">
      <router-link to="/follow" tag="span" :class="tabIndex === 1 ? 'active':''">沈阳</router-link>
    </div>
    <div class="item" @click="changeTab(2)">
      <router-link to="/index" tag="span" :class="tabIndex === 2 ? 'active':''"><img class="dy-btn"
                                                                                     alt=""
                                                                                     src="../../assets/img/dy-btn.png">
      </router-link>
    </div>
    <div class="item" @click="changeTab(3)">
      <router-link to="index" tag="span" :class="tabIndex === 3 ? 'active':''">消息</router-link>
    </div>
    <div class="item" @click="changeTab(4)">
      <router-link to="index" tag="span" :class="tabIndex === 4 ? 'active':''">我的</router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Tabbar',
  data() {
    return {
      tabIndex: 0,
    };
  },
  methods: {
    changeTab(index) {
      this.tabIndex = index;
    },
  },
};
</script>

<style lang="less" scoped>
  .tab-bar {
    height: 50px;
    line-height: 50px;
    width: 100%;
    background: #000000;
    position: fixed;
    bottom: 0;
    left: 0;
    color: #cccccc;
    font-size: 16px;
    display: flex;
    justify-content: center;

    .item {
      flex: 1;
      text-align: center;
    }

    .active {
      color: #ffff;
    }

    .dy-btn {
      display: inline-block;
      width: 50px;
      height: 30px;
      margin: 10px;
    }
  }
</style>

作者:米亚流年
链接:https://juejin.cn/post/6862327793200562184
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

完成后的效果

创建顶部导航栏

在你的工程内创建Topbar.vue 代码如下

<template>
    <div class="top-bar">
      <div class="left">
        <span class="iconfont icon-live"></span>
      </div>
      <div class="center">
        <div class="item" @click="changeTop(0)">
          <span :class="topIndex === 0 ? 'active' : ''">关注</span>
        </div>
        <div class="item" @click="changeTop(1)">
          <span :class="topIndex === 1 ? 'active' : ''">推荐</span>
        </div>
      </div>
      <div class="right">
        <span class="iconfont icon-sousuo"></span>
      </div>
    </div>
</template>

<script>
export default {
  name: 'Topbar',
  data() {
    return {
      topIndex: 1,
    };
  },
  methods: {
    changeTop(index) {
      this.topIndex = index;
    },
  },
};
</script>

<style lang="less" scoped>
  .top-bar {
    background: #000000;
    width: 100%;
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    color: #cccccc;
    display: flex;
    box-sizing: border-box;
    .left {
      width: 20%;
      padding-left: 10px;
      .icon-live {
        font-size: 24px;
      }
    }
    .center {
      flex: 1;
      display: flex;
      justify-content: center;
      .item {
        flex: 1;
        text-align: center;
        span {
          padding: 2px 0px;
          text-align: center;
          position: relative;
        }
        .active {
          color: #ffffff;
          &:after {
            content: "";
            height: 1px;
            width: 30px;
            left: 3px;
            bottom: -2px;
            position: absolute;
            background: #ffffff;
          }
        }
      }
    }
    .right {
      width: 20%;
      padding-right: 10px;
      text-align: right;
      .icon-sousuo {
        font-size: 24px;
      }
    }
  }
</style>

完成后的效果

初始化浏览器默认的样式

因为浏览器是有默认样式的 比如 padding、margin、input、box-sizing之类的 这些默认的样式都需要处理掉,这个地方我采用了第三方包

 yarn add normalize.css

安装成功之后,需要在main.js中引入

  import 'normalize.css/normalize.css';

总结

项目进行到这,看下项目的目录结构

目前顶部导航栏是点击切换的,导航栏文子下方的 横线 是用css的伪类实现的,再后续 的项目迭代中,会对此组件进行封装,并实现滑动切换标签的功能,敬请期待

通过如上步骤,项目目前的运行效果

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • vuecli实现移动端视频类webAPP-项目搭建

    在平时的前端开发中,我们更多的是完成螺丝钉的角色,即在公司的前端框架下,实现各种业务逻辑,Vue技术栈并不是难点所在,难点往往在于从 0 到 1 搭建一个完整的...

    前端逗逗飞
  • vuecli实现移动端视频类webAPP 项目发布地址

    9月初就申请了 掘金小册子,到现在也没审核通过,只能将此项目的文字教程发布到小专栏了, 小专栏地址

    前端逗逗飞
  • 适合初学者练手的vue小项目(附github源码)

    vue慢慢的成为了前端最受欢迎的框架之一,在很多项目之中开发都能用得到,如今也已经发展到3.0了,可能是因为这个框架可以提高工作效率,因此受到大家的追捧,在之前...

    王小婷
  • 分享一个整合SSM框架的高并发和商品秒杀项目

    一个整合SSM框架的高并发和商品秒杀项目,学习目前较流行的Java框架组合实现高并发秒杀API

    Java团长
  • 前后端通吃,vue大全Mark一下

    仓库地址:https://github.com/opendigg/awesome-github-vue

    java乐园
  • Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目...

    八哥
  • 前端性能优化总结

    最近花了一些时间在项目的性能优化上,背后做了很多工作,但是最后依然没有达到自己想要的结果,有些失望,但是还是记录下自己的执着。

    前端迷
  • Vue 实战-视频类webApp

    在平时的前端开发中,我们更多的是完成螺丝钉的角色,即在公司的前端框架下,实现各种业务逻辑,Vue技术栈并不是难点所在,难点往往在于从 0 到 1 搭建一个完整的...

    前端逗逗飞
  • VUE+ElementUI后台管理项目经验与技巧分享

    用vue+elementUI开发项目成了越来越多中小企业的首选,特别是开发各种管理平台和移动端项目,如何从零开始到系统构建呢?以下是我的一些经验和技巧;

    coder_koala
  • 一个合格的中级前端工程师需要掌握的技能笔记(下)

    Github来源:一个合格的中级前端工程师需要掌握的技能 | 求星星 ✨ | 给个❤️关注,❤️点赞,❤️鼓励一下作者

    达达前端
  • 白嫖他悟空CRM项目 ,部署了直接用起来

    建议大家有时间把这个后台改成springboot、SpringMVC、spring的流行框架,这样可以锻炼下自己框架搭建。

    好好学java
  • 百度的71个非常厉害的开源项目

    ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据可...

    开发者技术前线
  • 【程序源代码】Vue开源项目库汇总

    最近在学习VUE,感觉确实不错的前端框架。但光学习基本有点太慢,时间太长,主要是为了项目上手使用,所以在网上找了找比较好的VUE框架开发的项目实例。分享给大家。...

    程序源代码
  • 一份来自前端开发工程师的规范简历

    王小婷
  • IDEA 搭建简单 ssm 框架最详细最简单教程

    为开发一个测试程序,特搭建一个简单的ssm框架,因为网上看到很多都是比较老旧的教程,很多包都不能用了,eclipes搭建并且其中还附带了很多的其他东西,所以特此...

    好好学java
  • 一张图教你快速玩转vue-cli3

    本文系统的梳理了vue-cli3搭建项目的常见用法,目的在于让你快速掌握独立搭建vue项目的能力。你将会了解如下知识点:

    徐小夕
  • SSM 框架整合完整流程讲解(IDEA + Maven)

    在前面的几篇文章中,我分别写了 Mybatis 、Spring、Spring MVC 入门相关技术的几篇文章,

    BWH_Steven
  • 框架篇-Vue面试题5-怎么提高首屏渲染以及性能优化

    安装webpack-bundle-analyzer这个插件,然后使用npm run build --report输出项目打包情况,直观的比较哪个bundle文件...

    itclanCoder
  • Vue-CLI是什么?Vue-CLI2.x到Vue-CLI3.x有哪些进步?

    如果你用Vue搭建过项目,应该都熟悉vue init webpack projectName命令,至于为什么是这个命令,相信了解的人不是特别多,反正我能用就行了...

    Javanx

扫码关注云+社区

领取腾讯云代金券