vue2實踐(二)

因爲上篇文章內容太多,致使SF編輯器有點卡,因此新開闢了一篇,也方便閱讀。css

elementUI樣式是全局的

以前在用mint-ui的時候每一個組件裏面都有style標籤,樣式都是內部的,公用的寫在了mint-ui/lib/style.css文件裏而且該樣式文件就是在mint-ui項目裏,可是element組件裏都沒有style標籤,翻看了一會,發現element能夠自定義主題,而mint不能夠,這樣element的樣式全寫成了全局的,這樣方便用戶配置主題。樣式文件寫在packages/theme-default/src內,打包element的時候會將theme-default這個獨立的庫放到打包好的文件夾內。theme-default針對每一個組件有個對應的css文件,index.css去@importhtml

@import "./base.css";
@import "./pagination.css";
@import "./dialog.css";
@import "./autocomplete.css";
@import "./dropdown.css";
@import "./dropdown-menu.css";
@import "./dropdown-item.css";
@import "./menu.css";
@import "./submenu.css";
@import "./menu-item.css";
@import "./menu-item-group.css";
@import "./input.css";
@import "./input-number.css";
@import "./radio.css";
@import "./radio-group.css";
@import "./radio-button.css";
@import "./checkbox.css";
@import "./checkbox-group.css";
...

style直接寫在組件上會起做用

<topic :style="topicDialogStyle"></topic>

 computed: {
    topicDialogStyle() {
      return {
        maxHeight: "65vh",
        overflow: "auto"
      }
    }
  }

上篇提到class直接寫在組件上面是會渲染到組件的根節點上面,慣性思惟,認爲style也會在跟組件上起做用,測試了下是會起做用的,
若是組件的style都用scoped修飾,那麼每一個組件的樣式都是在本組件起做用,即便className渲染到了子組件的根節點,在父組件中定義的相同className的style也不會起做用,由於加了scoped之後組件的每一個HTML標籤都被加了一個data屬性,vue

clipboard.png

1的地方是根節點,有兩個data屬性,這個不知道爲啥,裏面的子節點都是一個data屬性,而且都是相同的。再看看vue對加了scoped的style作了啥,git

clipboard.png
clipboard.png

中括號裏就是data屬性,每一個組件data屬性都不一樣,保證了每一個組件scoped的樣式只在當前組件中有效。既然父組件中定義的樣式對子組件無效咋辦,有不少解決辦法:github

  • 利用class能夠在組件上直接寫,子組件能夠約定不一樣的className,子組件裏面寫幾套style
  • 經過props將在父組件定義的style對象傳遞進去
  • 在父組件中再開闢個不加scoped屬性的style,不過這麼寫可能污染到其餘組件的樣式。
  • 在子組件添加style屬性,直接影響子組件根元素的樣式

發現個奇怪的現象,在父組件中設置line-height(是scoped)子組件的全部行高都受影響,也就是全部的子元素都繼承了這個屬性,不設置行高默認爲normal,因此解決辦法就是給子組件的外層設置line-height:normalvue-router

style直接寫在組件上面,會對根元素起做用,vuex

<el-input-number size="small" :style="{color:'blue'}"></el-input-number>
<el-input-number size="small" style="color:blue"></el-input-number>

clipboard.png

"vue": "2.2.2",不知道什麼緣由,後續再看。小程序

自定義element dialog寬度

因爲style 加了 scoped ,因此裏面每一個樣式都是CSS [attribute] 選擇器只對加了attribute屬性的標籤有效,而dialog不少是全局樣式,想改變dialog的高度寫在scoped裏面是無效的,因此能夠寫在不加scoped標籤的style裏面,segmentfault

clipboard.png

custom-class Dialog 的自定義類名 string — —數組

經過custom-class props去控制dialog的整體樣式,同時要注意改classname的惟一性,以防污染其餘組件。

router-view標籤建立的命名路由並不會在每次切換路由的時候銷燬

app.vue

<template>
  <div id="app">
    <router-view name="header"></router-view>//頭部有搜索框和logo
    <router-view name="nav"></router-view>//tab導航欄
    <router-view></router-view>
  </div>
</template>

router/index.js

{
      path: '/',
      name: 'Login',
      component: Login
    },
    {
      path: '/index',
      name: 'Index',
      components: {
        default: Index,
        header: Header,
        nav: Nav
      }
    },
    {
      path: '/paperDetail',
      name: 'PaperDetail',
      components: {
        default: PaperDetail,
        header: Header,
        nav: Nav
      }
    },

由於登陸頁是獨立的,不須要頭部和導航欄,因此要使用命名路由去動態匹配除了登陸頁的其餘頁面,本覺得這麼動態匹配的header.vuenav.vue是在導航欄切換的時候被銷燬的,無心間發現beforeMountbeforeDestroy鉤子函數並不會在導航欄切換的時候調用,(beforeRouteEnterbeforeRouteLeave任然會被正常調用,調用順序是enter->watch route->leave,)那麼這麼就不會增長格外的內存開銷,就等同於寫死組件在根組件:

<template>
  <div id="app">
    <header></header>
    <navbar></navbar>
    <router-view></router-view>
  </div>
</template>

正如官網所述,

clipboard.png

小結:針對不一樣路由須要不一樣的數據話,能夠去監聽路由的變化,可是這個監聽只針對複用組件,好比header.vue,對於paperDetail.vue這種沒有複用的組件是無效的。

設置position:absolute對沒有加position定位的父組件不會起冒泡效果

<div class="top-pane" @click="handleItemClick" v-else>
      <ul class="blue-pane" @click="handleUlClick">
        <li class="normal-line play-button-pane" @click.prevent="handleBtnClick" v-show="showPlayButton">
          <img src="../assets/imgs/play-btn.png" alt="">
        </li>
      </ul>
    </div>

css

.top-pane {
 .blue-pane {
      height: 250px;
      position: relative;
       .play-button-pane {
        position: absolute;
        top: 50%;
        left: 50%;
        margin-top: -40px;
        margin-left: -40px;
        >img {
          width: 80px;
        }
      }
  }
}

點擊play-button-pane handleItemClick並不會執行,而handleUlClick能夠執行,說明事件並無冒泡到沒有添加position的top-pane節點,而冒泡到了添加position:relative的blue-pane節點。具體爲啥,有待討論。

頁面刷新beforeRouteEnter鉤子函數中的from.path爲"/"

一直覺得頁面刷新和router.push()的方式是同樣的,拿到的from.path都是上次路徑,使用中發現並非如此,每次頁面刷新,不論是從哪一個組件跳轉過來的,from.path都是"/"

深度做用選擇器 >>>

原由,我想對element的carousel的高度根據屏幕的大小進行調整,可是API只提供了height屬性,可是我不想用js拿到屏幕寬度去控制height,我想用media query控制

<el-carousel trigger="click" height="800px" class="index-carouse pc-index-carouse">
        <el-carousel-item v-for="(item,index) in carouse" :key="index">
          <a :href="item.imgLink">
            <img :src="item.src" alt="">
          </a>
        </el-carousel-item>
      </el-carousel>
      
      <style lang="less" scoped>
        .pc-index-carouse {
          height: 400px;
          .el-carousel__container {
            height: 100% !important;
          }
        }
      </style>

carousel

由於加了scoped 節點有了data-v-277d1ceb屬性

.pc-index-carouse .el-carousel__container[data-v-277d1ceb] {
  height: 100% !important;
}

可是classname屬性data-v-277d1ceb加在了.el-carousel__container上,應該只加在.pc-index-carouse上這個時候就該深度做用選擇器出場了

.pc-index-carouse {
  height: 400px;
  /deep/ .el-carousel__container {
    height: 100% !important;
  }
}

編譯後的樣式

.pc-index-carouse[data-v-277d1ceb] .el-carousel__container {
  height: 100% !important;
}

這樣就經過樣式改變了carousel的高度

淺談vue中style的scoped屬性(修改特定Element組件樣式的方法)
Scoped CSS

錨點定位報錯

vue-router Failed to execute 'querySelector' on 'Document'

原來是由於我每一個節點的id都是數字,變成字符串就行了

scrollBehavior (to, from, savedPosition) {
  if (to.hash) {
    return {
      selector: to.hash
    }
  }
}
關於Failed to execute 'querySelectorAll' on 'Document': '#1517905886124' is not a valid selector."

組件自定義事件傳參

用的是vant的小程序版的swipe-cell

if (this.data.asyncClose) {
        this.$emit('close', {
          position: position,
          instance: this
        });
      } else {
        this.swipeMove(0);
      }

父組件裏使用swipe-cell

<van-swipe-cell
        :right-width="65"
        :left-width="65"
        async-close
        :key="item._id"
        v-for="item in list"
        @close="onSwipeClose(arguments,item)"
      >

嘗試了各類辦法都不能得到兩個參數,onSwipeClose.bind(item) 也不行,onSwipeClose返回函數也不行;arguments就是上面emit出去的參數,item就是循環的item。

關於vue自定義事件中,傳遞參數的一點理解

vuex action 只能傳遞一個額外參數

傳遞兩個參數都有值
傳遞兩個參數都有值

到action裏丟了,只剩dishName

到action裏丟了,只剩dishName

因此只能傳遞一個對象或者數組

Only one parameter works when dispatching actions.

相關文章
相關標籤/搜索