Vue.js仿eleme項(xiàng)目(2)

五,項(xiàng)目實(shí)戰(zhàn),頁(yè)面骨架開發(fā)

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語(yǔ)法。在eslintrc.js的rules下面加兩個(gè)配置:
 'semi': ['error', 'always'],
 'indent': 0
  • main.jsnew Vue({ el: 'body', components: { App } });將body作為一個(gè)element掛載點(diǎn),所以app.vue中寫的template代碼都在body標(biāo)簽里面。

(Vue2.0中,不要把掛載點(diǎn)設(shè)置到 html 或者 body 標(biāo)簽上,因?yàn)?Vue 2.0 現(xiàn)在會(huì)把組件的 dom 替換到掛載的節(jié)點(diǎn)上。所以你需要?jiǎng)?chuàng)建一個(gè)子節(jié)點(diǎn),然后掛載上去。)

  • App.vue中引入組件header并注冊(cè)。注意我們已經(jīng)在webpack中寫過alias路徑,也可以不需要./直接寫components;components中的key不要命名為header,防止警告和原生標(biāo)簽沖突。
import header from './components/header/header.vue';
export default {
    components: {
      'v-header': header
    }
  };
  • 安裝stylus依賴。方法一,cnpm install stylus stylus-loader; 方法二,在package.json里面改,然后cnpm install。stylus語(yǔ)法參考張?chǎng)涡竦姆g。

補(bǔ)充一點(diǎn)npm知識(shí):

當(dāng)你為你的模塊安裝一個(gè)依賴模塊時(shí),正常情況下你得先安裝他們,在模塊根目錄下npm install module-name,然后連同版本號(hào)手動(dòng)將他們添加到模塊配置文件package.json中的依賴?yán)?dependencies)。
-savesave-dev可以省掉你手動(dòng)修改package.json文件的步驟。
npm install module-name -save
自動(dòng)把模塊和版本號(hào)添加到dependencies部分。
npm install module-name -save-dev
自動(dòng)把模塊和版本號(hào)添加到devdependencies部分。

devDependencies 下列出的模塊,是我們開發(fā)時(shí)用的,不會(huì)被部署到生產(chǎn)環(huán)境,比如css-loader。dependencies 下的模塊,則是我們生產(chǎn)環(huán)境中需要的依賴。

  • 在App.vue中引用header組件<v-header></v-header>;書寫tab布局的樣式和模板,使用flex布局(推薦阮一峰教程)。

注意我們不需要額外考慮瀏覽器兼容的style樣式,因?yàn)樵?vue-loader/postcss文件可以搞定。不過要注意兼容情況,參考這個(gè)http://coding.imooc.com/learn/questiondetail/3644.html
postcss根據(jù)http://caniuse.com/書寫,兼容性不錯(cuò)。

<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語(yǔ)法加start掛載點(diǎn),不能用new語(yǔ)法。注意app的寫法也要變。

components/goods/good.vue (注意import的時(shí)候可以不需要.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' }">評(píng)論</a>
      </div>
      <div class="tab-item">
        <a v-link="{ path: '/seller' }">商家</a>
      </div>
    </div>
    <router-view></router-view>
  </div>
</template>
....

接著我們用router.go('/goods');指定默認(rèn)的路由。(vue-router 2.0 中,router.go 變成 router.push了 參數(shù)是一樣的.)

然后添加tab<a>標(biāo)簽的stylus樣式。display改為塊級(jí)元素這樣點(diǎn)擊不用具體到文字上而是區(qū)塊上就可以。注意CSS書寫規(guī)范,先寫布局,方框等觸發(fā)dom重繪的放在布局后面,最后才寫字體、顏色等可以被繼承的。然后把默認(rèn)的class名字v-link-active換一個(gè)名字寫進(jìn)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'
});

幾個(gè)tips:

如果改的是非 src 文件夾下的代碼,比如改的 webpack 的配置文件,就需要重啟服務(wù)。

vue-router hash 模式的大致原理是根據(jù)修改 hash 值,觸發(fā) hashChange,然后對(duì)應(yīng)的 hash 去把 router-view 渲染成對(duì)應(yīng)的組件,不會(huì)引發(fā)頁(yè)面的重載。

3. 像素border實(shí)現(xiàn)

關(guān)于tab欄下面的1像素的實(shí)現(xiàn),即不管什么dpr值都是1像素(嚴(yán)格意義上的像素,不是css像素)。由于dpr問題不能直接代碼里寫1px。手機(jī)驗(yàn)證用草料https://cli.im生成二維碼可以方便手機(jī)查看。

流程:偽元素+Y軸縮放。先利用了mixin書寫嵌入代碼中的1px代碼,即 偽元素相對(duì)于元素絕對(duì)定位后(偽元素是宿主元素的子元素),給偽元素1像素邊框。然后給tab的div元素添加新的class, 根據(jù)設(shè)備最小dpr進(jìn)行scallY。這些代碼我們做成全局的以便將來重復(fù)使用。

注意:before 和 :after 這兩個(gè)偽元素,是在CSS2.1里新出現(xiàn)的。起初,偽元素的前綴使用的是單冒號(hào)語(yǔ)法,但隨著Web的進(jìn)化,在CSS3的規(guī)范里,偽元素的語(yǔ)法被修改成使用雙冒號(hào),成為::before & ::after – 這個(gè)樣子,用來跟“偽類(pseudo-classes)”區(qū)分開,(例如 :hover, :active, 等)。

Q: 為啥在main.js已經(jīng)全局引入了 mixin.stylus,在組件里還要再次@import mixin.stylus呢?
A: 全局引入后會(huì)被編譯成全局的css代碼,但mixin中的stylus函數(shù)無法編譯成css,所以 其他組件用到stylus函數(shù)時(shí)無法從全局的css中找到,還要在組件中引入mixin.stylus 才能被編譯成完整的css。mixin實(shí)際上就是把引用的mixin定義的代碼替換到引入的位置,從stylus的編譯考慮,如果你使用了某個(gè)mixin定義的代碼而不去指定它引用的路徑,那么它是完全不知道從哪去查找這個(gè)mixin定義的。

關(guān)于retina像素等等很繞的概念有幾個(gè)鏈接闡釋的不錯(cuò):
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))
...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容