Vue.js仿eleme项目(2)

五,项目实战,页面骨架开发

1. 组建拆封

  • static目录下加入文件css/reset.css,做css格式的重置http://cssreset.com
  • 更改index.html,引入reset.css, 加入meta 视口。
<meta name="viewport"
          content = "width=device-width, initial-scale=1.0, maximum-scale=1.0,
    minimum-scale=1.0, user-scalable=no">
<link rel="stylesheet" type="text/css" href="static/css/reset.css">
  • 更改eslint语法。在eslintrc.js的rules下面加两个配置:
 'semi': ['error', 'always'],
 'indent': 0
  • main.jsnew Vue({ el: 'body', components: { App } });将body作为一个element挂载点,所以app.vue中写的template代码都在body标签里面。

(Vue2.0中,不要把挂载点设置到 html 或者 body 标签上,因为 Vue 2.0 现在会把组件的 dom 替换到挂载的节点上。所以你需要创建一个子节点,然后挂载上去。)

  • App.vue中引入组件header并注册。注意我们已经在webpack中写过alias路径,也可以不需要./直接写components;components中的key不要命名为header,防止警告和原生标签冲突。
import header from './components/header/header.vue';
export default {
    components: {
      'v-header': header
    }
  };
  • 安装stylus依赖。方法一,cnpm install stylus stylus-loader; 方法二,在package.json里面改,然后cnpm install。stylus语法参考张鑫旭的翻译。

补充一点npm知识:

当你为你的模块安装一个依赖模块时,正常情况下你得先安装他们,在模块根目录下npm install module-name,然后连同版本号手动将他们添加到模块配置文件package.json中的依赖里(dependencies)。
-savesave-dev可以省掉你手动修改package.json文件的步骤。
npm install module-name -save
自动把模块和版本号添加到dependencies部分。
npm install module-name -save-dev
自动把模块和版本号添加到devdependencies部分。

devDependencies 下列出的模块,是我们开发时用的,不会被部署到生产环境,比如css-loader。dependencies 下的模块,则是我们生产环境中需要的依赖。

  • 在App.vue中引用header组件<v-header></v-header>;书写tab布局的样式和模板,使用flex布局(推荐阮一峰教程)。

注意我们不需要额外考虑浏览器兼容的style样式,因为在 vue-loader/postcss文件可以搞定。不过要注意兼容情况,参考这个http://coding.imooc.com/learn/questiondetail/3644.html
postcss根据http://caniuse.com/书写,兼容性不错。

<style lang="stylus" rel="stylesheet/stylus">
  #app
    .tab
      display: flex
      width: 100%
      height: 40px;
      line-height: 40px
      .tab-item
        flex: 1
        text-align: center
</style>
  1. Vue-router

1.0的文档在这里https://github.com/vuejs/vue-router/tree/1.0/docs/zh-cn
遵循课程,我们安装0.7.13版本的vue-router,用npm安装方法同上(package.json中要写在dependencies里面)。

main.js中引用vue-router,按照官方文档的例子来,要用extend语法加start挂载点,不能用new语法。注意app的写法也要变。

components/goods/good.vue (注意import的时候可以不需要.vue后缀)

<template>
  <div>I am goods</div>
</template>

<script type="text/ecmascript-6">
  export default {};
</script>

<style lang="stylus" rel="stylesheet/stylus">

</style>

main.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App';
import goods from 'components/goods/goods';
import ratings from 'components/ratings/ratings';
import seller from 'components/seller/seller';

Vue.use(VueRouter);

let app = Vue.extend(App);

let router = new VueRouter();

router.map({
  '/goods': {
    component: goods
  },
  '/ratings': {
    component: ratings
  },
  '/seller': {
    component: seller
  }
});

router.start(app, '#app');

App.vue

<template>
  <div>
    <v-header></v-header>
    <div class="tab">
      <div class="tab-item">
        <a v-link="{ path: '/goods' }">商品</a>
      </div>
      <div class="tab-item">
        <a v-link="{ path: '/ratings' }">评论</a>
      </div>
      <div class="tab-item">
        <a v-link="{ path: '/seller' }">商家</a>
      </div>
    </div>
    <router-view></router-view>
  </div>
</template>
....

接着我们用router.go('/goods');指定默认的路由。(vue-router 2.0 中,router.go 变成 router.push了 参数是一样的.)

然后添加tab<a>标签的stylus样式。display改为块级元素这样点击不用具体到文字上而是区块上就可以。注意CSS书写规范,先写布局,方框等触发dom重绘的放在布局后面,最后才写字体、颜色等可以被继承的。然后把默认的class名字v-link-active换一个名字写进new vuerouter中并添加样式。

 .tab-item
      flex: 1
      text-align: center
      & > a
        display: block
        font-size: 14px
        color: rgb(77, 85, 93)
        &.active
          color: rgb(240,20,20)
let router = new VueRouter({
  linkActiveClass: 'active'
});

几个tips:

如果改的是非 src 文件夹下的代码,比如改的 webpack 的配置文件,就需要重启服务。

vue-router hash 模式的大致原理是根据修改 hash 值,触发 hashChange,然后对应的 hash 去把 router-view 渲染成对应的组件,不会引发页面的重载。

3. 像素border实现

关于tab栏下面的1像素的实现,即不管什么dpr值都是1像素(严格意义上的像素,不是css像素)。由于dpr问题不能直接代码里写1px。手机验证用草料https://cli.im生成二维码可以方便手机查看。

流程:伪元素+Y轴缩放。先利用了mixin书写嵌入代码中的1px代码,即 伪元素相对于元素绝对定位后(伪元素是宿主元素的子元素),给伪元素1像素边框。然后给tab的div元素添加新的class, 根据设备最小dpr进行scallY。这些代码我们做成全局的以便将来重复使用。

注意:before 和 :after 这两个伪元素,是在CSS2.1里新出现的。起初,伪元素的前缀使用的是单冒号语法,但随着Web的进化,在CSS3的规范里,伪元素的语法被修改成使用双冒号,成为::before & ::after – 这个样子,用来跟“伪类(pseudo-classes)”区分开,(例如 :hover, :active, 等)。

Q: 为啥在main.js已经全局引入了 mixin.stylus,在组件里还要再次@import mixin.stylus呢?
A: 全局引入后会被编译成全局的css代码,但mixin中的stylus函数无法编译成css,所以 其他组件用到stylus函数时无法从全局的css中找到,还要在组件中引入mixin.stylus 才能被编译成完整的css。mixin实际上就是把引用的mixin定义的代码替换到引入的位置,从stylus的编译考虑,如果你使用了某个mixin定义的代码而不去指定它引用的路径,那么它是完全不知道从哪去查找这个mixin定义的。

关于retina像素等等很绕的概念有几个链接阐释的不错:
https://www.w3cplus.com/css/towards-retina-web.html
http://coding.imooc.com/learn/questiondetail/8563.html
http://benweizhu.github.io/blog/2017/03/25/css-retina-image/

我的疑问,,这段代码不是很懂http://coding.imooc.com/learn/questiondetail/21399.html

具体代码如下:

//mixin.styl

border-1px($color)
  position: relative
  &::after
    display: block
    position: absolute
    left: 0
    bottom: 0
    width: 100%
    border-top: 1px solid $color
    content: ' '
// base.styl

@media (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)
  .border-1px-dpr
    &::after
      -webkit-transition: scaleY(0.7)
      transform: scaleY(0.7)

@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2)
  .border-1px-dpr
    &::after
      -webkit-transition: scaleY(0.5)
      transform: scaleY(0.5)
// App.vue

...
<style lang="stylus" rel="stylesheet/stylus">
  @import "common/stylus/mixin"
  .tab
    display: flex
    width: 100%
    height: 40px;
    line-height: 40px
    // border-bottom: 1px solid rgba(7, 17, 27, 0.1)
    border-1px(rgba(7, 17, 27, 0.1))
...
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容