vue項目中遇到的一些問題


或訪問:https://github.com/littleHiuman/experiences-about-vue

求點star呀~~

 歡迎補充!


 

vuex 狀態

vue-cli 命令行

vue vue

vue-router 路由

es6

eslint

 


 Js寫法 規范。

eslint常見問題

 

brace-style?

no-sequences?

block-spacing?

 

比較時,使用全等號

所有的switch語句都必須要有一個default分支

yoda:yoda條件語句就是對象字面量應該寫在比較操作符的左邊,而變量應該寫在比較操作符的右邊(默認的規則要求,變量寫在左邊而字面量寫在右邊)


個別符號以及關鍵字之間需要空格(比如function,逗號,大括號,運算符)

逗號在行尾出現/行首

不以新行開始的塊 { 前面要不要有空格

 

立即調用函數的寫法:

(function() {
  // body 
}());

 

只能使用單引號

最后必須有一行空行,

不能有多余空行

不能有多余空格

空位/制表符距離為2

可以設置帶分號,否則js中不能帶分號。

"semi": [2, "always"]

 

不能 定義了卻未使用的變量

alias中定義的簡稱只能用於js部分。

模塊必須有一個根元素

整個頁面有切換動畫,那么頁面的根元素不能有其他樣式影響

Vue實例中 最后一個屬性末不需要加逗號

對象里的最后一項,不需要加逗號

 


 引入css文件:

1. index.html中引入,

2. <style></style>中引入,需要@import,

或者另外一個<style src=""></style>

3. main.js中引入需要寫loader(inport/require)

require('!style-loader!css-loader!less-loader!./assets/css/common_m.less')

PS:在webpack中配置好了loader之后,不需要在引入文件時寫loader和文件后綴。 

 


 cssloader:

{
  test: /\.css$/,
  exclude: /node_modules/,   loader:
"style-loader!css-loader", }, {   test: /\.less$/,
  exclud: /node_module/,   loader:
"style-loader!css-loader!less-loader", },

 


 

// <router-view></router-view>與寫的位置無關

 


 

path.join(__dirname,'..');

 


 

this.$set(this, '屬性', '值')

 


 css scoped 僅本組件

 


 

對象可以存圖片。使用require即可。

images: {
  error: require('./toast-error.png'),
  success: require('./toast-success.png'),
  load: require('./toast-load.gif'),
  waiting: require('./toast-hourglass.svg')
}

 


 

border。各屏幕分辨率不同出現的粗細問題。

公共部分。寫成組件。利用傳參改變樣式/內容。

Ajax。axios。

跨域問題的解決:1.服務器端協助配置。2.jsonp。3.devServer配置代理。

能用data數據解決的問題,不用方法解決。如取反。長度。是否空/false/true。(Vue是數據驅動而不是結構驅動)

v-bind:style src to ...

 


 

路由傳參。$route。

歷史記錄切換。router-link to/:to或者router.push()/router.replace()

 

#router.push(location) 導航到不同的 URL

// 聲明式
<router-link :to="...">

// 編程式
router.push(...)

// 字符串
router.push('home')

// 對象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})

// 帶查詢參數,變成 /register?plan=private

router.push({ path: 'register', query: { plan: 'private' }})

 

#router.replace(location) 它不會向 history 添加新記錄,而是替換掉當前的 history 記錄。

// 聲明式
<router-link :to="..." replace>

// 編程式
router.replace(...)

 

#router.go(n) 在 history 記錄中向前或者后退多少步,類似 window.history.go(n) 值可以正可以負

 

#綜合使用

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

router.push({ name: 'user', params: { userId: 123 }})

 

這兩種方式都會把路由導航到 /user/123 路徑。

 


 

// 命名視圖

// https://router.vuejs.org/zh-cn/essentials/named-views.html

// https://jsfiddle.net/posva/6du90epg/

// 有時候想同時(同級)展示多個視圖,而不是嵌套展示,例如創建一個布局,有 sidebar(側導航) 和 main(主內容) 兩個視圖,這個時候命名視圖就派上用場了。

// 你可以在界面中擁有多個單獨命名的視圖,而不是只有一個單獨的出口。如果 router-view 沒有設置名字,那么默認為 default。

<router-view class="view one"></router-view>

<router-view class="view two" name="a"></router-view>

<router-view class="view three" name="b"></router-view>

// 一個視圖使用一個組件渲染,因此對於同個路由,多個視圖就需要多個組件。確保正確使用 components 配置(帶上 s):

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

 


 

重定向 和 別名

 


切換時清空歷史記錄。數據丟失。sessionStorage。

相對路徑。

append。concat。

渲染成某個標簽。tag

可以在router-link內嵌套其他內容。

 


 

類型都是Object

$route.params(一個 key/value 對象,包含了 動態片段 和 全匹配片段,如果沒有路由參數,就是一個空對象。)

$route.query(一個 key/value 對象,表示 URL 查詢參數。例如,對於路徑 /foo?user=1,則有 $route.query.user == 1,如果沒有查詢參數,則是個空對象。)

 

<div>
    <router-link :to="{ name: 'Hello' , params: { userId: 123 }}">
        click1
    </router-link>
</div>

<div>
    <router-link :to="{ path: 'hello' , query: {show: 2}}">
        click2
    </router-link>
</div>

console.log(this.$route.params.userId)

console.log('top is params, bottom is query')

console.log(this.$route.query.show)

 


 watch:

watch: {
  '$route' (to, from) {
  // 對路由變化作出響應...
  }
}

 


v-show和v-if 。v-if為假直接不渲染。v-show為假display none。

當 v-if 與 v-for 一起使用時,v-for 具有比 v-if 更高的優先級。

個人建議:外容器overflow hidden,內容器overflow scroll。

 


 

過渡效果:

<transition name="fade"></transition>
.fade-enter-active, .fade-leave-active {   -webkit-transition: opacity .7s;   transition: opacity .7s; } .fade-enter, .fade-leave-active {   opacity: 0 }

 


 

路由鈎子:判斷從哪個路由過來,到哪個路由。然后跳轉到哪個路由。(全局鈎子。局部鈎子。)

component頁面內也可以監聽路由。

 


 

滾動行為。歷史記錄之間切換。頁面位置。返回對象。

scrollBehavior (to, from, savedPosition) {
  return { x: 0, y: 0 }
}

 


 

錨點的實現。通過scrollTop。或滾動行為。

路由元信息。路由嵌套。

 


懶加載。

4、在異步加載頁面中載嵌入異步加載的組件時對頁面是否會有渲染延時影響?

答:會, 異步加載的組件將會比頁面中其他元素滯后出現, 頁面會有瞬間閃跳影響;

解決方案:因為在首次加載組件的時候會有加載時間, 出現頁面滯后, 所以需要合理的進行頁面結構設計, 避免首次出現跳閃現象;

At all:

  1、路由頁面以及路由頁面中的組件全都使用懶加載

  優點:(1)最大化的實現隨用隨載

     (2)團隊開發不會因為溝通問題造成資源的重復浪費    

  缺點:(1)當一個頁面中嵌套多個組件時將發送多次的http請求,可能會造成網頁顯示過慢且渲染參差不齊的問題

  2、路由頁面使用懶加載, 而路由頁面中的組件按需進行懶加載, 即如果組件不大且使用不太頻繁, 直接在路由頁面中導入組件, 如果組件使用較為頻繁使用懶加載

  優點:(1)能夠減少頁面中的http請求,頁面顯示效果好

  缺點:(2)需要團隊事先交流, 在框架中分別建立懶加載組件與非懶加載組件文件夾

  3、路由頁面使用懶加載,在不特別影響首頁顯示延遲的情況下,根頁面合理導入復用組件,再結合方案2

  優點:(1)合理解決首頁延遲顯示問題

     (2)能夠最大化的減少http請求, 且做其他他路由界面的顯示效果最佳

  缺點:(1)還是需要團隊交流,建立合理區分各種加載方式的組件文件夾

export default new Router({
  routes: [
    {
      path: '/',
      component: resolve => require(['components/Hello.vue'], resolve)
    },
    {
      path: '/about',
      component: resolve => require(['components/About.vue'], resolve)
    }
  ]
})

  

// solve:

// components/page

 


 <keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們。和 <transition> 相似,<keep-alive> 是一個抽象組件:它自身不會渲染一個 DOM 元素,也不會出現在父組件鏈中。

當組件在 <keep-alive> 內被切換,它的 activated 和 deactivated 這兩個生命周期鈎子函數將會被對應執行。

主要用於保留組件狀態或避免重新渲染。

 


 組件:

當注冊組件(或者 props)時,可以使用 kebab-case ,camelCase ,或 TitleCase 。Vue 不關心這個。

// 在組件定義中
components: {

  // 使用 kebab-case 形式注冊
  'kebab-cased-component': { },

  // register using camelCase
  'camelCasedComponent': { },

  // register using TitleCase
  'TitleCasedComponent': { }
}

 

在 HTML 模版中,請使用 kebab-case 形式:

<!-- 在HTML模版中始終使用 kebab-case -->

<kebab-cased-component></kebab-cased-component>

<camel-cased-component></camel-cased-component>

<title-cased-component></title-cased-component>

 

當使用字符串模式時,可以不受 HTML 的 case-insensitive 限制。

<!-- 在字符串模版中可以用任何你喜歡的方式! -->

<my-component></my-component>

<myComponent></myComponent>

<MyComponent></MyComponent>

 


 

如果組件未經 slot 元素傳遞內容,你甚至可以在組件名后使用 / 使其自閉合:

<my-component/>

當然,這只在字符串模版中有效。因為自閉的自定義元素是無效的 HTML ,瀏覽器原生的解析器也無法識別它。

 


component命名要求:

1. 檢查名稱是否與 HTML 元素或者 Vue 保留標簽重名,不區分大小寫。(常用HTML標簽)

2. 檢查組件名稱是否以字母開頭,后面跟字母、數值或下划線。

 


使用 Virtual DOM 解析模板時,不會將模板中的標簽名轉成小寫,而是保留原始標簽名。然后,使用原始的標簽名進行匹配組件。

例如, <MyComponent></MyComponent> 不會轉為為小寫形式,直接以 MyComponent 為基礎開始匹配。

當然,匹配的規則依次匹配:原標簽名、camelCase化的標簽名、PascalCase化的標簽名。

//之前在 1.0 不能正常運行的示例代碼,在 2.0 中可以正常運行了:

Vue.component('MyComponent', {
  template: '<div>hello, world</div>'
})

new Vue({
  el: '#app',
  template: '<MyComponent></MyComponent>'
})

 


 

在 Vue 1.0 和 2.0 中還有一種定義組件模板的方式,即使用 DOM 元素。在這種情況下,解析模板時仍然會將標簽轉為小寫形式。所以下面的代碼,在 1.0 和 2.0 均不能正常運行。

// index.html
<div id="app">
  <MyComponent></MyComponent>
</div>

// main.js
Vue.component('MyComponent', {
  template: '<div>hello, world</div>'
})

new Vue({
  el: '#app'
})

 


 由於 JavaScript 的限制, Vue 不能檢測以下變動的數組:

當你利用索引直接設置一個項時,例如:

vm.items[indexOfItem] = newValue

 

當你修改數組的長度時,例如:

vm.items.length = newLength

 

為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果, 同時也將觸發狀態更新:

// Vue.set

Vue.set(example1.items, indexOfItem, newValue)

// Array.prototype.splice`

example1.items.splice(indexOfItem, 1, newValue)

 

為了解決第二類問題,你也同樣可以使用 splice:

example1.items.splice(newLength)

 


 父組件給子組件傳參,通過props屬性。還可以定義類型

https://cn.vuejs.org/v2/guide/components.html#Prop-驗證

除了以下定義一種類型的寫法,還有多種類型,必傳且是某個類型,某個類型且有默認值,某個類型但默認值由一個工廠函數返回,或者是自定義

props: {
  username: String,
}

// 全局注冊的組件的寫法:
props: ['myMessage'],

 

子組件給父組件傳參,通過this.$emit('方法', '內容')

 


vertical-align: top;

兩個span對齊 / 圖片和文字對齊 / inline-block元素 .......

 


 

 字體圖標。

 


 

一行文字超出省略號:

white-space: nowrap
overflow: hidden
text-overflow: ellipsis

 

空白間隙去掉的方法:

font-size: 0;

// 或者 兩個標簽之間緊貼着。

 


 filter類似濾鏡效果。模糊效果。

filter: blur(10px)

 

同上類似。模糊效果(僅對背景生效,僅限iOS系統)

backdrop-filter: blur(10px)

 


 type,給參數 / 變量定義類型。

 


 

computed,內容變時會更新,否則會緩存起來。

如果是傳參等方式得到值,需要判斷值是否為空,否則會報值為undefined的錯。

 


 

使用變量 / 產量拼接內容,而不使用字符串拼接內容。

 


 

各子元素不固定寬 / 高,但是整個布局占固定值時,flex布局。盡量用block元素。

flex的默認值為0 1 auto

flex是放大比例(flex-grow) 縮小比例(flex-shrink)占據的空間(flex-basis)的簡寫屬性

可以填auto(相當於 1 1 auto)和none(0 0 auto)

flex: 1(相當於 1 1 0%)

使用flex屬性后,該元素最好添加width屬性,值為flex-basis定義的值。 

 


 

vue項目中,不用寫CSS的兼容性代碼。

因為vue-loader在編譯.vue文件的時候,使用了Postcss的工具,它會給有兼容性問題的屬性添加兼容性代碼。

它是根據can i use官網寫的代碼。

寫在<style></style>內才會生效。在html中添加style屬性是不會添加兼容性代碼的。

 


 

換行問題:

v-html可以直接加<br>進行換行,v-model中無效

例外:textarea標簽使用v-model時,可以使用\r進行換行

 


 

實現垂直居中的方式:

父元素: display: table,

子元素: display: table-cell;vertical-align: middle;
無論一行或多行。

 


 

刪除線效果 text-decoration: line-through

 


 iScroll

 


 

ref的使用:

在父頁面調用子組件的標簽:

在父頁面中的組件上加ref。然后在子組件中的某個標簽加ref。即可。

 


 nextTick

將回調延遲到下次 DOM 更新循環之后執行。

https://cn.vuejs.org/v2/api/#vm-nextTick

new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // 修改數據
      this.message = 'changed'
      // DOM 還沒有更新
      this.$nextTick(function () {
        // DOM 現在更新了
        // `this` 綁定到當前實例
        this.doSomethingElse()
      })
    }
  }
})

 


 

 

box-sizing: border-box

 


:disabled="type == '值'"

 


:class = name

name可以是computed

 


$dispatch 和 $broadcast在vue2.0中已經棄用,推薦使用一個專用的狀態管理層如:Vuex 。

或者子組件和父組件之間 相互傳參。

 


getBoundingClientRect用於獲取某個元素相對於視窗的位置集合。集合中有top, right, bottom, left等屬性。

 


點擊事件。取消冒泡。

v-on:click.stop="doThis"

阻止默認事件。

v-on:click.prevent="doThis"

https://cn.vuejs.org/v2/guide/events.html#事件修飾符

 


 

判斷頁面來源。

https://router.vuejs.org/zh-cn/advanced/navigation-guards.html

 


 

組件內部的方法,命名建議以兩個下划線開頭

外部傳參方法等,不用兩個下划線開頭。

 


padding取%值,

> %,規定基於父元素的寬度的百分比的內邊距。

 


給按鈕加padding。方便點擊

或者整個部分可以點擊。

 


過濾:filter

// 計算屬性
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

// 或者,你也可以在計算屬性不適用的情況下 (例如,在嵌套 v-for 循環中) 使用 method 方法:
<li v-for="n in even(numbers)">{{ n }}</li>

data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

// -----------------
// 過濾器函數
<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>

// PS: 為了在其他指令中實現更復雜的數據變換,你應該使用計算屬性。

new Vue({
  // ...
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})

// 過濾器可以串聯:
{{ message | filterA | filterB }}

// 過濾器是 JavaScript 函數,因此可以接受參數:
{{ message | filterA('arg1', arg2) }}

// 這里,字符串 'arg1' 將傳給過濾器作為第二個參數, arg2 表達式的值將被求值然后傳給過濾器作為第三個參數。

 

https://cn.vuejs.org/v2/guide/list.html#顯示過濾-排序結果
https://cn.vuejs.org/v2/guide/syntax.html#過濾器

 


export 和 export default

http://es6.ruanyifeng.com/#docs/module#export-命令
http://es6.ruanyifeng.com/#docs/module#export-default-命令

 


 

切換組件時,希望保留組件的狀態時,加上keep-alive 即可

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM