在 weex 中愉快的使用 scss

weex 是一個能夠利用 vue 或者 Rax 編寫跨平臺手機應用的框架。爲了讓在 weex 有更好的樣式編寫體驗,遂有了如下的方案。

1.初始化一個 weex 工程javascript

npm install weex-toolkit -g
weex create weex-test
cd weex-test
npm run start

這時候就能夠在瀏覽器看到界面了css

2.接着爲了能夠在vue裏面寫scss, 咱們須要安裝兩個東西, sass-loadernode-sassvue

npm install -D sass-loader@7.3.1 node-sass

在這裏要注意一點sass-loader要安裝 7 版本的,否則會報錯,這是由於sass版本高致使的,接下來就能夠愉快的寫scss,還要注意一點須要在style標籤加上語言標記scssjava

<style lang="scss">
</style>

3.爲了更好的組織項目結夠和樣式的統一,咱們會把一些主題顏色、字體大小、文字顏色提取到一個scss文件,咱們把它命名爲variable.scss以下:node

$theme-color: blue;

$font-big: 32px;
$font-nor: 28px;
$font-small: 24px;

咱們把它放到項目的src/common/scss下, 須要的時候就在vue文件中引用, 好比在 index.vue 頁面引用npm

<style lang="scss">
@import './common/scss/variable.scss'
div {
    background-color: $theme-color;
}
</style>

這樣就可讓應用的主體部分的樣式保持一致了。瀏覽器

4.在 weex 中有一些屬性不支持簡寫的方式好比 border,還有一些須要寫兩三條的樣式如文字超出隱藏,這種樣式咱們能夠將它們定義成scss的混合宏(mixin),咱們把它命名爲mixins.scsssass

@mixin border($width, $style, $color) {
    border-width: $width;
    border-style: $style;
    border-color: $color;
}
@mixin border-top($width, $style, $color) {
    border-top-width: $width;
    border-top-style: $style;
    border-top-color: $color;
}

咱們把它放到項目的src/common/scss下, 須要的時候就在vue文件中引用, 好比在 index.vue 頁面引用weex

<style lang="scss">
@import './common/scss/variable.scss';
@import './common/scss/mixins.scss';
div {
    @include border(1px, solid, $theme-color);
}
</style>

這樣咱們就能夠將一些經常使用的css代碼寫進混合宏了框架

5.在weex中因爲不支持類名的權重覆蓋,只支持後面的定義的同類樣式覆蓋前面的樣式,這樣就會致使咱們不能很好的組織 css 代碼, 又不能利用 scss 的優點代碼層級嵌套。爲此咱們引入BEM命名方法,並經過scss的混合宏讓其在寫法上支持嵌套,首先咱們在 src/common/scss 下建立 bem.scss,並寫入以下代碼:

$namespace: '';
$element-separator: '__';
$modifier-separator: '--';

@mixin b($block) {
    @if $namespace == '' {
        $B: $block !global;
    } @else {
        $B: $namespace+'-'+$block !global;
    }

    @if '#{&}' == '' {
        .#{$B} {
            @content;
        }
    } @else {
        @at-root {
            .#{$B} {
                @content;
            }
        }
    }

}

@mixin e($element) {
    $E: $element !global;
    $selector: &;

    @if str-index('#{&}', '__') {
        @at-root {
            .#{$B + $element-separator + $element} {
                @content;
            }
        }
    } @else {
        @at-root {
            #{&+$element-separator+$E} {
                @content;
            }
        }
    }

}
@mixin m($modifier) 
    $M: $modifier !global;
    @at-root {
        #{&+$modifier-separator+$M} {
            @content;
        }
    }
}

因爲weex不支持層級因此咱們只能用@at-root將全部類名提高到第一層。接着咱們在index.vue中引入這個文件:

<template>
    <div class="header">
        <div :class="['header__back', `header__back--${status}`]"></div>
        <div class="header__content"></div>
        <div class="header__other"></div>
    </div>
</template>
<script>
export default {
    data(){
        return {
            status: 'black'
        }
    }
}
</script>
<style lang="scss">
@import './common/scss/variable.scss';
@import './common/scss/mixins.scss';
@import './common/scss/bem.scss'

@include b('header') {
    height: 100px;
    width: 750px;
    flex-direction: row;
    align-items: center;
    @include e('back') {
        flex: 1;
        @include m('black') {
            background-color: #000000;
        }
        @include m('white') {
            background-color: #ffffff;
        }
    }
    @include e('content') {
        flex: 3;
    }
    @include e('other') {
        flex: 1;
    }
}
</style>

編譯後的樣式爲:

.header {
    height: 100px;
    width: 750px;
    flex-direction: row;
    align-items: center;
}
.header__back {
    flex: 1;
}
.header__back--black {
    background-color: #000000;
}
.header__back--white {
    background-color: #ffffff;
}
.header__content {
    flex: 3;
}
.header__other {
    flex: 1;
}

這樣看起來用scss的寫法代碼的結構性和可維護性就會更好一些。

6.因爲這三個文件都是須要在每個vue文件引入的,爲了偷一下懶,咱們能夠用sass-resources-loader 這個loader來讓每個vue文件都注入這幾個scss文件

npm install -D sass-resources-loader

而後修改根目錄下的 configs/utils.js ,找到以下,進行更改

const generateLoaders = (loader, loaderOptions) => {
    let loaders = options.useVue ? [cssLoader] : []
    if (options.usePostCSS) {
      loaders.push(postcssLoader)
    }
    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: options.sourceMap
        })
      })
    }

    //這裏加入如下代碼
    if (loader === 'sass') {
      loaders.push({
        loader: 'sass-resources-loader',
        options: {
          resources: [
            path.resolve(__dirname, '../src/common/scss/variable.scss'),
            path.resolve(__dirname, '../src/common/scss/mixins.scss'),
            path.resolve(__dirname, '../src/common/scss/bem.scss')
          ]
        }
      })
    }

    if (options.useVue) {
      return ['vue-style-loader'].concat(loaders)
    }
    else {
      return loaders
    }
  }

這樣就能夠在weex工程中愉快的編寫scss

相關文章
相關標籤/搜索