vue实用难点讲解
此篇文章是我基于研究vue文檔三遍的基礎(chǔ)上,覺得還有點難理解或者難記的知識點總結(jié)
列表渲染
1.渲染組件必須加key,并且屬性是手動傳遞給組件的<my-componentv-for="(item, index) in items"v-bind:item="item"v-bind:index="index"v-bind:key="item.id"></my-component> 2.v-for和v-if用在同一個節(jié)點上面,會先執(zhí)行v-for然后再執(zhí)行v-if 3.使用v-for最好加上key值,因為vue本身是基于就地更換的原則,也就是你在1-100之間再插入一個數(shù)值比如5,那么原來的5和后面的數(shù)據(jù)都會依次加一,這樣的效率是非常低的,如果你傳遞了key做唯一的標(biāo)識,那么插入的5就插在4后面了,后面的數(shù)據(jù)就不變了,只是位置挪了下事件對象
- 要使用事件對象,必須在調(diào)用的時候傳遞$event,不能是其他的名字
常用的事件修飾符
.stop 阻止冒泡 .prevent 阻止默認(rèn)行為 .capture 使用事件捕獲 .self 自身觸發(fā) .once 觸發(fā)一次按鍵修飾符
.enter .tab .delete .esc .space .up .down .left .right 自定義修飾符 Vue.config.keyCodes.f1 = 12鼠標(biāo)按鍵修飾符
.left .right .middle
表單
表單修飾符 .lazy v-model默認(rèn)是監(jiān)聽oninput事件的加上這個修飾符,就是監(jiān)聽onchange事件 <input v-model.lazy="msg" > .number 將用戶輸入值轉(zhuǎn)換成數(shù)字 .trim 自動將用戶輸入的首尾空格去掉組件通信
1.父組件傳遞信息給子組件子組件要想得到父組件的數(shù)據(jù),只需要在子組件內(nèi)部通過props顯示的聲明自己想要什么屬性,是不是有點意思,就像女的問男的要東西一樣,我要lv包包。聲明之后父組件將數(shù)據(jù)傳遞給子組件就ok了,如下Vue.component('child',{props: ['message','myMessage'],template: '<span>{{ message }}</span>'})在父組件中使用 <child message="hello!" :my-message="parentMsg"></child> 即可注意:在子組件中不能修改父組件傳遞過來的數(shù)據(jù),只能做備份來修改,并且引用類型要深拷貝 2.在父組件中通過傳遞非props屬性,將自動添加到子組件根元素上面,如下<bs-date-input data-3d-date-picker="true"></bs-date-input>如果子組件上面已經(jīng)存在了同名屬性,一般都是直接替換的,但是class和style是和子組件的class和style合并的 3.子組件通知父組件在子組件中觸發(fā)某個事件同時v-on:click="childfunciton",可以通過在childfunction內(nèi)部添加this.$emit('somefunction')通知觸發(fā)父組件中的事件,在父組件中通過v-on:somefunction="parentfunction"接受到通知,然后觸發(fā)父組件中的parentfunction事件,也就是說在父組件中,將v-on用在子組件標(biāo)簽上面并不是給子組件綁定事件而是監(jiān)聽子組件內(nèi)部的消息,但是如果確實想綁定一個事件給子組件可以通過添加.native修飾符,如下<my-component v-on:click.native="doTheThing"></my-component>這個事件將直接綁定到子組件的根元素 4.子組件父組件數(shù)據(jù)雙向綁定在父組件中的子組件標(biāo)簽上綁定屬性使用.sync修飾符,即可完成數(shù)據(jù)雙向綁定,如下<child :foo.sync="bar"></child>在parent組件內(nèi)部定義bar屬性,即可將bar值實時的通過foo傳遞給子組件在子組件內(nèi)部通過this.$emit('update:foo','hahahha');可以在任意時刻修改父組件中的bar值,此函數(shù)內(nèi)部其實執(zhí)行的是 bar => bar = val,實際上就是直接給bar賦值,但是只能采用這種方式 5.其實上面說的組件通信還是基礎(chǔ)的,下面來看一個高級點的<input v-model="something">v-model其實,就是下面的簡寫形式<input v-bind:value="something" v-on:input="something = $event.target.value">同樣v-model也可以用在組件身上,就是如下的樣子了<custom-input :value="something" @input="value => { something = value }"></custom-input>所以知道這上面兩點就可以實現(xiàn)自定義組件v-model功能了下面是child.vue的代碼<div><input type="text" :value="value" @input="updateValue($event.target.value)">{{value}}</div>export default {props: ['value'],methods: {updateValue(value){this.$emit('input',value)}},}下面是father.vue的代碼<child v-model="price"></child>data () {return {price: ''}}在子組件中的input中輸入數(shù)據(jù),可以動態(tài)的反應(yīng)到父組件中,實現(xiàn)雙向綁定由于默認(rèn)是value和input如果想改變這個默認(rèn)的,可以在子組件中,使用model如下在子組件中聲明model: {prop: 'checked',event: 'change'},props: {checked: Boolean,value: String}所以使用<my-checkbox v-model="foo" value="some value"></my-checkbox>其實就是下面的簡寫<my-checkbox :checked="foo" @change="val => { foo = val }" value="some value"></my-checkbox> 6.非父子組件之間的通信非父子組件之間的通信就要使用$on了首先要有一個空的vue實例var bus = new Vue();如果你使用vue的webpack項目的話,這個東西你要單獨的加在一個js文件中以store.js為例,添加如下代碼import Vue from 'vue'window.bus = new Vue();并且還要在main.js中通過import './store.js'導(dǎo)入,這時就可以在vue項目全局使用bus了如果在一個組件中需要傳遞消息,就使用bus.$emit('fn', 1)傳遞數(shù)據(jù)在要接受數(shù)據(jù)的組件中使用,bus.$on('fn',function(value){...})即可 講到這兒,vue最核心的部分也就將完了,弄懂這塊兒東西,相信后面的學(xué)習(xí)就易如反掌了 7.使用slot實現(xiàn)內(nèi)容分發(fā)實際工作中組件的組成大多數(shù)是類似下面的<parent><child><someother-component></someother-component></child></parent>slot的作用就是用來處理嵌套在組件標(biāo)簽內(nèi)部的內(nèi)容 8.單一slot如果只有一個slot標(biāo)簽并且沒有任何屬性,slot標(biāo)簽將會被全部替換成嵌套在組件標(biāo)簽內(nèi)部的內(nèi)容,如果slot標(biāo)簽自身包裹內(nèi)容,這個內(nèi)容只會在組件標(biāo)簽內(nèi)部不包含任何東西的時候展示,demo如下如果一個child組件的模板內(nèi)容如下<div><h2>I'm the child title</h2><slot>這里面的內(nèi)容只會在沒有插入內(nèi)容時顯示</slot></div>然后<child>hahahhahahah</child>那么hahahhahahah就會替換slot成為child模板的一部分 9.命名slot可以給slot起個名字,比如<slot name="header"></slot>然后給組件標(biāo)簽內(nèi)容添加slot屬性,屬性值和上面的名字相同,就可以實現(xiàn)特殊指派了,如<child><h1 slot="header">指定的內(nèi)容</h1></child>這樣就實現(xiàn)的需求導(dǎo)入了 10.局部slot上面講的slot都是可以實現(xiàn)父組件傳遞數(shù)據(jù)到子組件中,現(xiàn)在想實現(xiàn)將子組件中的數(shù)據(jù)傳遞到slot要替換的內(nèi)容中可以在子組件中的slot插槽中添加任意屬性,如 <slot text="子組件child中的數(shù)據(jù)"></slot>然后,在子組件標(biāo)簽內(nèi)部,如下<parent><child>// 必須使用template標(biāo)簽,并且添加scope屬性,屬性值props就是包含slot傳遞的數(shù)據(jù)對象<template scope="props"><span>父組件parent中的數(shù)據(jù)</span><span>{{props.text}}</span></template></child></parent> 11.動態(tài)組件可以使用同一個綁定點,動態(tài)的切換渲染不同的組件,要實現(xiàn)這個功能要借助component標(biāo)簽和is屬性<component :is="currentView"></component> vue實例代碼如下var vm = new Vue({el: "#example",data: {currentView: 'home'},components: { home,posts,archive }}) 通過改變currentView的值,可以實現(xiàn)動態(tài)切換組件 上面這種寫法可以滿足局部組件,也就是你自己定義的組件的切換,但是如果你使用全局組件,比如某些UI組件庫中的組件,那么就要像下面這樣用var Home = {template: ...};var vm = new Vue({el: "#example",data: {currentView: Home}});如果你想將切換渲染過的組件保留在內(nèi)存中可以使用keep-alive將動態(tài)組件包裹<keep-alive><component :is="currentView">...</component><keep-alive>vue動畫效果
**vue的過渡 過渡一般用于元素的插入,刪除,移除 下面講解過渡的知識1.對單個的元素或者組件使用過渡使用transition標(biāo)簽包裹要應(yīng)用過渡的元素<transition name="fade"><p v-if="show">hello</p></transition>當(dāng)上面的p元素在顯示和隱藏中間切換時,會發(fā)生以下事情第一,檢測目標(biāo)元素,自動添加或移除css過渡類名第二,執(zhí)行transition的鉤子函數(shù)第三,如果上面兩步驟都沒有對應(yīng)的設(shè)置,那么不會應(yīng)用過渡效果2.過渡的類名v-enter 進(jìn)入的開始狀態(tài),在元素插入之前添加,在元素插入之后刪除v-enter-active 整個進(jìn)入過程的狀態(tài),連續(xù)的畫面,這個類就是用來定義動畫的持續(xù)時間,延遲和線性函數(shù)的v-enter-to 進(jìn)入的結(jié)束狀態(tài),在元素插入之后添加,在整個enter-active結(jié)束后刪除v-leave 消失的開始狀態(tài)v-leave-active 整個消失的過程v-leave-to 消失的結(jié)束狀態(tài)上面的這些類名的v是默認(rèn)的前綴,你可以給transition標(biāo)簽指定name屬性,用來自定義類名前綴上面提到的元素的插入和移除就是頁面上dom元素的一瞬間的狀態(tài)3.css過渡就是指定好開始和結(jié)束的css樣式,然后定義動畫的執(zhí)行過程,如下所示.v-enter-active,.v-leave-active{transition: all .3s ease;}.v-enter,.v-leave-to{transform: translateX(10px);opacity: 0;}4.css動畫上面都是應(yīng)用的transition,這里是animation,其實類似.v-enter-active{animation: bounce-in .5s;}.v-leave-active{animation: bounce-in .5s;}@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.5);}100% {transform: scale(1);}}5.css過渡類名如果你使用animate.css這類的第三方css庫,可以借助如下的類名enter-classenter-active-classenter-to-classleave-classleave-active-classleave-to-class使用demo<transitionenter-active-class="animated tada"leave-active-class="animated bounceOutRight"><p v-if="show">hello</p></transition>6.如何區(qū)分animation和transition當(dāng)你的動畫中同時使用transition形式和animation形式的動畫,必須添加type屬性,指定屬性值為animation或者transition7.指定動畫持續(xù)時間vue默認(rèn)的動畫持續(xù)時間是基于根過渡元素,內(nèi)部的子過渡元素的持續(xù)時間如果長于根過渡元素將會被忽略,所以可以在transition標(biāo)簽上面添加duration屬性,demo如下<transition :duration="1000">...</transition><transition :duration="{enter: 500,leave: 800}"></transition>8.添加動畫鉤子函數(shù),這部分內(nèi)容用的比較少,感興趣自行了解9.對初次渲染的元素添加過渡添加appear屬性 <transition appear> </transition>添加這個屬性之后,會自動應(yīng)用之前指定好的enter和leave的動畫,如果想實現(xiàn)單獨的動畫功能可以使用如下的方式<transitionappearappear-class="..."appear-to-class="..."appear-active-class="..."></transition>10.在多個元素中應(yīng)用過渡上面討論的都是基于單個過渡元素,下面討論多個元素的過渡一般使用v-if/v-else在元素之前切換,相同的元素在切換的時候回復(fù)用,所以要添加key屬性,如下<transition><button v-if="isEditing" key="save">Save</button><button v-else key="edit">Edit</button></transition>此外,很可以添加mode屬性,用來指定顯示和隱藏的先后順序in-out 先入后出out-in 先出后入11.列表過渡上面講的都是一次過渡一個元素,現(xiàn)在講一次過渡多個元素過渡多個元素就要借助transition-group并且還要給需要過渡的元素添加key屬性,可以給transition-group標(biāo)簽添加tag屬性,指定具體渲染后的元素,還可以添加.v-move類,當(dāng)元素的位置變化了,自動添加此類,此動畫功能只適用于非display: inline元素 **過渡state數(shù)據(jù)可以對數(shù)字型的數(shù)據(jù),顏色值,這類的數(shù)據(jù)做過渡效果,主要是配合第三方庫來做的,感興趣的自己去看吧render函數(shù)
講實話這部分內(nèi)容在實際使用中,幾乎用不上,個人感覺vue的單文件組件,已經(jīng)替代了這個的功能,所以說強大的jsx功能在vue中可能就是一個擺設(shè)而已,這也是為什么高端互聯(lián)網(wǎng)企業(yè)選擇react的原因了吧 vue的render函數(shù)說白了就是用js編寫html,說實話和jsx比起來,render是非常麻煩的 vue中寫render就不需要template選項了Vue.component('demo-render',{render: function(createElement){// 這個函數(shù)的結(jié)果就是組件的templatereturn createElement(// 這個函數(shù)接受三個參數(shù)'div', 可以是組件也可以是html標(biāo)簽{}, 當(dāng)前vnode的屬性對象,這個屬性對象的介紹請看下面[] 字符串或者數(shù)組都可以,子節(jié)點,如果子節(jié)點下面還有子節(jié)點可以再次調(diào)用createElement方法)}}) 屬性對象的介紹{'class': {//v-bind:class},style: {//v-bind:style},attrs: {//正常的html屬性如id這類的},props: {//當(dāng)前的節(jié)點是另外一個組件的話,這個就是傳遞給組件的屬性對象},domoProps: {//Dom節(jié)點的屬性對象比如innerHTML},on: {//v-on: 不支持修飾符},nativeOn: {// 只能在當(dāng)前的節(jié)點是其它組件的時候生效},directives: [//自定義指令],slot: 'somename', //指定slot標(biāo)簽,用于插入內(nèi)容,屬性值是slot的name屬性值scopedSlots: {// 說實話這個東西對于初學(xué)者是很難懂的,我也是看了很多遍才明白/*局部插槽顧名思義,其實就是用來給子組件使用的,所以這部分內(nèi)容就直接放在render里面編寫default: props => createElement('span',props.text);上面的代碼和下面的原始寫法是表達(dá)的意思是一模一樣的<template scope="props"><span>{{props.text}}</span></template>*/},key: 'myKey', 就是key屬性ref: 'myRef' 當(dāng)前vnode的引用} 使用render的注意點所有的render內(nèi)部使用的vnode必須都是獨一無二的,不同使用相同vnode的引用可以在vue中使用jsx代替你,render函數(shù)的復(fù)雜寫法,例子如下render (h) {return (<AnchoredHeading level={1}><span>Hello</span> world!</AnchoredHeading>)}這就是jsx語法,通俗易懂具體的學(xué)習(xí)地址https://github.com/vuejs/babel-plugin-transform-vue-jsx#usage建議:如果你被jsx的魅力所吸引,我個人覺得還是去學(xué)react的吧,在vue中的單文件組件完全可以滿足你的項目開發(fā)需求,如果你在.vue文件中使用jsx或者render會變得非常奇怪,在template中使用html又在js中使用html簡直就是怪胎自定義指令
說實話,這部分內(nèi)容我不太想寫出來,一門技術(shù)總有好的和壞的反面,偶爾了解一些不太好的東西,對自己學(xué)習(xí)其他知識,可以擴(kuò)展視野 這部分內(nèi)容就是自己寫一個指令比如v-myDirective,然后利用vue提供的鉤子函數(shù),在合適的時機(jī)觸發(fā)他們。簡單demo如下Vue.directive('focus',{// 全局指令})或者directive: {focus: {// 局部指令// 可以在這里面指定鉤子函數(shù),表示在何時執(zhí)行這些鉤子函數(shù)// 說白了就是利用元素的生命周期鉤子實現(xiàn)所謂的自定義指令和vue實例的生命周期鉤子本質(zhì)是一樣的,呵呵bind: function(// 所有的鉤子函數(shù)在這里面都可以傳遞參數(shù),參數(shù)后面講){// 當(dāng)指令綁定到元素上執(zhí)行,只執(zhí)行一次},inserted: // 元素插入的時候執(zhí)行,update: // 元素自身更新,執(zhí)行,componentUpdated: // 子組件更新執(zhí)行,unbind: // 解綁的時候執(zhí)行}}具體使用,就在需要的元素上面直接寫上指令名稱即可 <input v-focus> 鉤子函數(shù)的參數(shù)el // 綁定的dom元素binding // 關(guān)于指令的相關(guān)屬性對象,細(xì)節(jié)自己看vnode ,oldVnode // 虛擬節(jié)點對象 這部分內(nèi)容了解,就可以了Mixins混入
這部分內(nèi)容用的也比較少,不過當(dāng)你的組件中有很多重復(fù)的method或者其他的選項,可以使用這個減少冗余代碼 一個mixin對象可以包含實例的任何選項var myMixin = {created: function(){this.hello();},methods: {hello: function(){console.log('hello from mixin!')}}}var Component = Vue.extend({mixins: [myMixin]})var component = new Component(); 混入的規(guī)則如下1.鉤子函數(shù)會放進(jìn)一個隊列里面,先執(zhí)行mixin對象中的鉤子,然后執(zhí)行實例的鉤子2.methods,components,directives都會被合并成一個對象,同名的屬性只會使用組件的,舍棄掉mixin對象的3.全局混入全局混入盡量不要用會污染所有的vue實例Vue.mixin({created: function() {...}})4.用戶自定義選項的合并默認(rèn)是組件的直接覆蓋掉mixin對象的同名屬性如果想對自定義選項myOption應(yīng)用自定義邏輯,可以使用如下的函數(shù) Vue.config.optionMergeStrategies.myOption = function(toVal,fromVal){// ...}如果自定義選項是對象的話也可以使用methods選項的合并規(guī)則var strategies = Vue.config.optionMergeStrategies;strategies.myOption = strategies.methods結(jié)語
有能力的同學(xué),我建議去學(xué)學(xué)react,畢竟到這兒,vue你已經(jīng)精通了
轉(zhuǎn)載于:https://www.cnblogs.com/ye-hcj/p/7231289.html
總結(jié)
- 上一篇: 管理Sass项目文件结构
- 下一篇: vue.js 安装