VUEJS學習網址:https://cn.vuejs.org/javascript
此文章是用來記錄本身的學習和實踐心得。css
看圖說話:html
Pass Propsvue
Emit Eventsjava
v-on
綁定監聽,觸發對應事件;以上爲通用語,具體分析react
<v-input label="姓名"></v-input>
<input v-model="msg" /> <v-profile :message="msg"></v-profile>
子組件接收到數據以後想處理一下不當心改了怎麼辦?git
父組件的數據改變後,子組件的prop會自動更新,可是這個prop的副本不會啊?github
子組件的prop副本改變了想要通知父組件怎麼辦?web
(添加)父組件的prop改變,可是不想通知子組件怎麼辦?vue-router
。。。
其實以上???在2.3有了更好的方法,以前的就是看看。
.sync修飾符
***父組件***
<input v-model="msg" />
<v-profile :message.sync="msg"></v-profile>
***子組件***
$.emit('update:message',newValue)
(9-21)補充:註釋仍是建議使用data或compute屬性,而不是直接修改prop
子組件想要觸發父組件能夠emit(父組件須要監聽纔會觸發),父組件觸發子組件事件呢?
可是!$refs
只在組件渲染完成後才填充,而且它是非響應式的。它僅僅做爲一個直接訪問子組件的應急方案——應當避免在模版或計算屬性中使用 $refs
。
使用空的vue實例做爲中央事件總線
var bus = new Vue(); // 觸發組件 A 中的事件 bus.$emit('id-selected', 1) // 在組件 B 建立的鉤子中監聽事件 bus.$on('id-selected', function (id) { // ... })
考慮vuex
(2018-07-28)注意到了$attrs和¥listeners,用於在多層嵌套中交互,見文檔
首先,在父組件中給子組件標籤中間放置內容是無效的。而後slot出場。
白話版本:
匿名slot:
slot標籤存在與子組件template中;
子組件在父組件中使用的時候,子組件標籤中的結構會在編譯後替換子組件的slot標籤;
若是子組件中沒有slot,則父組件中子組件標籤中的內容會消失;
具名slot:
顧名思義,是具備name屬性的slot標籤;並有匿名組件的特性(以上);
子組件在父組件中使用的時候,子組件中的結構中會有某些標籤擁有slot屬性並賦值,這些會在編譯後替換子組件的相應slot標籤;
一句話解釋:主要的內容是寫在父組件中的子組件標籤中,編譯後插入子組件的相應位置
講真,說到這裏我本身都不明白要slot幹嗎。
官方給了個佈局的例子:
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
<app-layout> <h1 slot="header">這裏多是一個頁面標題</h1> <p>主要內容的一個段落。</p> <p>另外一個主要段落。</p> <p slot="footer">這裏有一些聯繫信息</p> </app-layout>
可是好像也沒什麼好推薦的。(我的見解)
再想一想:
子組件的template中至少有一個slot標籤,slot標籤中的內容是default content。什麼場景能用到呢?我想到了剛剛寫的表格數據篩選,當時用的是v-if,v-else。若是改爲slot呢。。。想到slot屬性值須要動態傳餐,原來寫在子組件內部的過濾過程要搬出來放到父組件中執行,而後把執行好的數據塞給子組件的prop。。。
再理一次:
我在子組件的template中設置兩個slot
<slot name="Data">各類展示數據的結構都放這裏</slot>
<slot name="noData">沒有相關數據</slot>
父組件中設置
<input v-model="filterData" /> <button v-on:click="filterMethod">篩選</button> <v-table :datas="datas"> <div slot="Data">
...
<div> <v-tabel>
關鍵就是slot屬性動態賦值的問題。。。走不通,腦洞大了按下不說了
做用域插槽
語法:
<template scope="props"> ... </template>
——————這個官網例子我是好半天才明白
<my-awesome-list :items="items"> <!-- 做用域插槽也能夠是具名的 --> <template slot="item" scope="props"> <li class="my-fancy-item">{{ props.text }}</li> </template> </my-awesome-list>
以上的template中的props其實和子組件的props屬性是相同的,子組件傳遞了什麼prop,它就接收什麼,像是下邊的傳了個text
<ul> <slot name="item" v-for="item in items" :text="item.text"> <!-- 這裏寫入備用內容 --> </slot> </ul>
我看了很長很長時間,爲何要這麼拐個彎呢。。。
————一晚上事後—————
這樣內容更靈活:數據是相同的(父組件提供數據),子組件負責了循環(添加邏輯),父組件引用子組件時插入的做用域插槽的模板決定了(展現的形式)!這分工!!!點個贊!!!
我修改了一下本身的table而後頁面展現了個空白。以後發現問題出在子組件往外傳數據的時候變量名不能用"name"。修改掉。2017-07-14:使用index也不行。。。
2017-07-15:在實際使用的時候發現複用性不強。感受父子組件之間聲明式props傳遞數據的方式使加強複用性變得困難。
<component>
元素,動態地綁定到它的 is
特性,咱們讓多個組件可使用同一個掛載點,並動態切換:很適用於製做Tab類的效果<component v-bind:is="currentView" :data1="data1" :data2="data2"> <!-- 組件在 vm.currentview 變化時改變! --> </component>
done()
//放到鉤子最後,表示執行工做完畢,能夠切換組件,配合keep-alive使用,activated鉤子只執行一次暫時說到這裏,忽然得回頭看一下react,沒時間了,回頭會繼續。
以上的滿基礎的(我是新手),有什麼不對的求指出,感謝!!!
添加:
使用全局註冊的時候沒有問題(框架自行解決)
若是是模塊引用(我都是這樣的),須要在第一次循環的子組件上聲明
beforeCreate: function () { this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue') }
本身模仿的示例
treeFolder
<template>
<ul>
<li v-for="folder in folders">
<span @click="toggle(folder)">folder.name:{{folder.name}}</span>
<tree-folder-content v-if="folder.children"
:children="folder.children"
v-show="folder.show"
/>
</li>
</ul>
</template>
<script>
import treeFolderContent from './treeFolderContent.vue';
export default{
name: "tree-folder",
data(){
return {
expand: false
}
},
components: {
'tree-folder-content': treeFolderContent
},
props: ['folders'],
methods:{
toggle: function(item) {
item.show = !item.show;
}
}
}
</script>
treeFolderContent
<template>
<ul>
<li v-for="child in children">
<span @click="toggle(child)">child.name:{{child.name}}</span>
<TreeFolder v-if="child.children"
:folders="child.children"
v-show="child.show"
/>
</li>
</ul>
</template>
<script>
export default{
name: "tree-folder-content",
beforeCreate(){
this.$options.components.TreeFolder = require('./treeFolder.vue');
},
data(){
return {
expand: false
}
},
props: ['children'],
methods:{
toggle: function(item) {
item.show = !item.show;
}
}
}
</script>
引用方式
<template>
<div class="main">
<div class="content">
<tree-folder :folders="menu"></tree-folder>
</div>
</div>
</template>
<script>
import treeFolder from './../commen/treeFolder.vue'
export default{
name: "nav3",
data(){
return {
menu: [
{
name: 'a一級導航', show: true,
children: [
{name: 'a二級導航', show: false},
{name: 'a二級導航', show: false}
]
},
{
name: 'b一級導航', show: true,
children: [
{name: 'b二級導航', show: false},
{name: 'b二級導航', show: false},
{
name: 'b二級導航', show: false,
children: [
{
name: 'b三級導航', show: false,
children: [
{name: 'b四級導航', show: false,}
]
}
]
},
]
},
{
name: 'c一級導航', show: true,
children: [
{name: 'c二級導航', show: false},
{name: 'c二級導航', show: false},
{
name: 'c二級導航', show: false,
children: [
{name: 'c三級導航', show: false}
]
},
]
}
]
}
},
components: {
'tree-folder': treeFolder
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less" rel="stylesheet/less">
.content {
background: blue;
color: #fff;
}
</style>
小點tip:
v-once
將渲染結果緩存起來;vue1.x版本中有不少系統自帶的過濾器,在vue2.x版本中都沒有了。
2017-07-15
看圖說話:
mounted
不會承諾全部的子組件也都一塊兒被掛載。若是你但願等到整個視圖都渲染完畢,能夠用 vm.$nextTick 替換掉 mounted。OK,問題解決。DOM展示給用戶後,用戶操做(v-on)引起data change。可是這時候並非直接操做DOM,而是操做虛擬dom(我的理解:由vue-loader將vue組件文件中的代碼解析成了javascript,(render的過程)在用戶操做的時候,最早操做這些僞DOM(js操做),而後在re-render成真正的DOM。再此,也總結出vue的一大特色:data和dom並非直接通信,而是經過虛擬dom)。這裏又牽扯出了數據驅動。。。看圖。。。先看看,等等換成新的關注點吧(>.<)
當這個鉤子被調用時,組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做。然而在大多數狀況下,你應該避免在此期間更改狀態。若是要相應狀態改變,一般最好使用計算屬性或 watcher 取而代之。(官網原文,我以爲記着就好)
該鉤子在服務器端渲染期間不被調用。
//用Javascript代碼表示DOM節點的僞代碼 Let domNode = { tag: 'ul' attributes: { id: 'myId' } children: [ //這裏是 li ] };
var loading = document.createElement("div"); loading.style.width = "1000px"; loading.style.height = "1000px"; loading.className = 'loading'; loading.style.backgroundColor = "#000";
數據驅動原理
連接:
2017-07-17
會有 6 個(CSS)類名在 enter/leave 的過渡中切換
v-enter
: 定義進入過渡的開始狀態。在元素被插入時生效,在下一個幀移除。
v-enter-active
: 定義過渡的狀態。在元素整個過渡過程當中做用,在元素被插入時生效,在 transition/animation
完成以後移除。 這個類能夠被用來定義過渡的過程時間,延遲和曲線函數。
v-enter-to
: 2.1.8版及以上 定義進入過渡的結束狀態。在元素被插入一幀後生效(於此同時 v-enter
被刪除),在 transition/animation
完成以後移除。
v-leave
: 定義離開過渡的開始狀態。在離開過渡被觸發時生效,在下一個幀移除。
v-leave-active
: 定義過渡的狀態。在元素整個過渡過程當中做用,在離開過渡被觸發後當即生效,在 transition/animation
完成以後移除。 這個類能夠被用來定義過渡的過程時間,延遲和曲線函數。
v-leave-to
: 2.1.8版及以上 定義離開過渡的結束狀態。在離開過渡被觸發一幀後生效(於此同時 v-leave
被刪除),在 transition/animation
完成以後移除。
看概念並不難,直接說我跳過的坑:
css過渡
css動畫 顧名思義,是動畫 animation 。
搭配animate.css一塊兒使用。能夠經過如下特性來自定義過渡類名:他們的優先級高於普通的類名
enter-class
enter-active-class
enter-to-class
(>= 2.1.8 only)leave-class
leave-active-class
leave-to-class
(>= 2.1.8 only)event.preventDefault()
或 event.stopPropagation()
是很是常見的需求。儘管咱們能夠在 methods 中輕鬆實現這點,但更好的方式是:methods 只有純粹的數據邏輯,而不是去處理 DOM 事件細節。(原文)<button v-on:click="warn(' ...', $event)"> Submit </button> ...... methods: { warn: function (message, event) { // 如今咱們能夠訪問原生事件對象 if (event) event.preventDefault() alert(message) } }
<!-- 阻止單擊事件冒泡 --> <a v-on:click.stop="doThis"></a> <!-- 阻止默認事件 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 點擊事件將只會觸發一次 --> <a v-on:click.once="doThis"></a> <!-- 只有在 keyCode 是 13 時調用 vm.submit() --> <input v-on:keyup.13="submit"> <!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 縮寫語法 --> <input @keyup.enter="submit"> .enter .tab .delete (捕獲 「刪除」 和 「退格」 鍵) .esc .space .up .down .left .right 自定義鍵值修飾符 Vue.config.keyCodes.f1 = 112
鼠標或鍵盤事件監聽
.ctrl
.alt
.shift
.meta
關注點:命名視圖
https://jsfiddle.net/posva/6du90epg/
關注點:v-once 與 keep-alive
今天把本身寫的心得又讀了一遍,對v-once 和keep-alive有點迷惑
v-once只渲染元素和組件一次。隨後的從新渲染,元素/組件及其全部的子節點將被視爲靜態內容並跳過。這能夠用於優化更新性能。
keep-alive包裹動態組件時,會緩存不活動的組件實例,而不是銷燬它們。
今天11月30日,由於一些緣由我有2個月沒有注意「vuejs」,就這樣它悄悄地改變了。。。
紙上得來終覺淺,但願有機會去實踐。
實踐來了。
2018.1.15
工做告一個段落了,使用公司的接口將新的webApp項目改爲了vuejs項目。不是每一個頁面都從新寫了,時間也是不容許的吧。
實現:vue-router,vuex,vue-resourse,selected,下拉加載,輸入框和select等。
地址:*********************老大說放公司代碼屬於侵權。。。
不會再新增關於vue的新隨筆,就這一篇,不斷的補充,感受也挺好。(我又加了一個關於框架的。。。)
關注點:watch
watch用來監控某個變化的屬性,而後執行方法。在我以往的使用中,只有該監控的屬性發生變化時纔會觸發方法。
2018-08-01 在項目中使用vue有半年了,這半年來項目不斷,也算是用vue‘摸爬滾打’了,可是總以爲淺。想的用的都很表面,只是‘能跑通’罷了。挫敗。