我一直都相信,決定將來的是自信與成長速度,成長的過程當中,整理是一個很是重要的環節,接下來是我整理的系統組件開發經常使用的部分。css
本文的主要內容有:html
1.table內編輯 2.高度不固定,顯示隱藏過渡動畫 3.解決vue父組件傳遞props異步數據到子組件的問題
1.table點擊編輯按鈕時,顯示input(此input可修改table裏某一行某一列的內容)、取消按鈕、保存按鈕。
2.點擊保存按鈕,則保存編輯後的內容,點擊取消則不保存。vue
2.編輯因爲input是雙向綁定,輸入的時候就改變了數據,點擊取消時,需恢復原來的數據。需 「拷貝」 一份原來的數據,如取消則使用這個數據。代碼有兩部分,一部分是隻針對一列,名字寫實,理解思路。另外一部分是實際項目開發能用到的,每一列均可編輯,而且名字可變。代碼以下:異步
(1)理解思路,title列進行可編輯函數
請求table數據 this.$http.get(this.tableUrl).then(response => { let commTable1 =response.data.tableData; this.list = commTable1 .map(v => { this.$set(v, 'edit', false); v.oldTitle = v.title ; return v }) }) 點擊保存 save(row) { row.edit = false row.oldTitle = row.title } 點擊取消 cancel(row) { row.title = row.oldTitle row.edit = false }
(2)table每一列進行編輯動畫
table請求數據 this.$http.get(this.tableUrl).then(response => { response = response.data; let commTable1 =response.tableData; this.commTable= commTable1.map(v => { for(var obj in v){ v[`old${obj}`]=v[obj] } this.$set(v, 'edit', false); return v }) }); 點擊保存 save(row) { for(var obj in row){ let str = ''; if(obj.indexOf('old')>-1){ str = obj.replace('old',''); row[obj]=row[str]; } } row.edit = false } } 點擊取消 cancel(row) { let str = ''; if(obj.indexOf('old')>-1){ str = obj.replace('old',''); row[str]=row[obj]; } } row.edit = false; }
無論是vue的過渡動畫,仍是element的過渡動畫,都是須要高度固定,沒法知足需求。接下來是一個大神封裝的一個函數式組件,這個組件只適用於單個內容,若是內容是v-for循環,且高度不固定,我作了一下改裝,使用的是vue 的transition-group。Vue.JS實現垂直方向展開、收縮不定高度模塊的JS組件this
const elTransition = '0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out' const Transition = { 'before-enter' (el) { el.style.transition = elTransition if (!el.dataset) el.dataset = {} el.dataset.oldPaddingTop = el.style.paddingTop el.dataset.oldPaddingBottom = el.style.paddingBottom el.style.height = 0 el.style.paddingTop = 0 el.style.paddingBottom = 0 }, 'enter' (el) { el.dataset.oldOverflow = el.style.overflow if (el.scrollHeight !== 0) { el.style.height = el.scrollHeight + 'px' el.style.paddingTop = el.dataset.oldPaddingTop el.style.paddingBottom = el.dataset.oldPaddingBottom } else { el.style.height = '' el.style.paddingTop = el.dataset.oldPaddingTop el.style.paddingBottom = el.dataset.oldPaddingBottom } el.style.overflow = 'hidden' }, 'after-enter' (el) { el.style.transition = '' el.style.height = '' el.style.overflow = el.dataset.oldOverflow }, 'before-leave' (el) { if (!el.dataset) el.dataset = {} el.dataset.oldPaddingTop = el.style.paddingTop el.dataset.oldPaddingBottom = el.style.paddingBottom el.dataset.oldOverflow = el.style.overflow el.style.height = el.scrollHeight + 'px' el.style.overflow = 'hidden' }, 'leave' (el) { if (el.scrollHeight !== 0) { el.style.transition = elTransition el.style.height = 0 el.style.paddingTop = 0 el.style.paddingBottom = 0 } }, 'after-leave' (el) { el.style.transition = '' el.style.height = '' el.style.overflow = el.dataset.oldOverflow el.style.paddingTop = el.dataset.oldPaddingTop el.style.paddingBottom = el.dataset.oldPaddingBottom } } export default { name: 'VerticalToggle', functional: true, render (h, { children }) { const data = { on: Transition } return h('transition', data, children) } }
組件中可這樣使用.net
import verticalToggle from './vertical-toggle.js'; <vertical-toggle> <div style="background-color:red;" v-show="dialogVisible1">123</div> </vertical-toggle> 以上適用於單個內容,若是內容是v-for循環,且高度不固定,使用的是vue 的transition-group **vue組件:**
<transition-group name="fade2" v-on:enter="enter" v-on:before-leave="beforeLeave" v-on:leave="leave"> <div v-for="(item2,i2) in item.children" :key="i2" class="fade2"> {{item2.name}} </div> <transition-group>
方法:雙向綁定
enter(el){ el.style.height = el.scrollHeight + 'px'; el.style.paddingTop = el.dataset.oldPaddingTop el.style.paddingBottom = el.dataset.oldPaddingBottom }, beforeLeave(el){ el.dataset.oldPaddingTop = el.style.paddingTop el.dataset.oldPaddingBottom = el.style.paddingBottom el.dataset.oldOverflow = el.style.overflow el.style.height = el.scrollHeight + 'px' el.style.overflow = 'hidden' }, leave(el){ el.style.height = 0 el.style.paddingTop = 0 el.style.paddingBottom = 0 },
}
css:code
.fade2-enter-active,.fade2-leave-active { transition: all .5s; } .fade-enter,.fade2-enter,.fade-leave-to,.fade2-leave-to{ height: 0px; }
若是有需求是還要在顯示的組件裏添加內容,則還需下面代碼,由於this.$refs不支持響應,因此就在updated生命週期裏寫了。
updated() { if(this.flog1){ for(let obj of this.list){ let index=this.list.indexOf(obj) this.$refs.fade[index].style.height="auto"; } this.flog2=false; } },
data爲異步獲取的數據,想傳遞給子組件使用
<template> <div> 父組件 <child :child-data="data"></child> </div> </template> <script> import child from './child' export default { data: () => ({ data: '' }), components: { child }, mounted () { // setTimeout模擬異步數據 setTimeout(() => { this.data= '異步的數據' }, 2000) } } </script> 子組件child.vue <template> <div> 子組件{{childData}} </div> </template> <script> export default { props: { childData:{ type:String } }, created () { console.log(this.childData) // 空值 }, } </script>
子組件的html中的{{childData}}的值會隨着父組件的值而改變,可是created裏面的卻不會發生改變(生命週期問題)
解決辦法:我這裏給出我常常用的兩種經常使用的解決方案,還有其餘的解決方案 https://www.jb51.net/article/...。
1.在父組件使用v-if 方法
<template> <div> 父組件 <child :child-data="data" v-if="flag"></child> </div> </template> <script> import child from './child' export default { data: () => ({ data: '', flag: false }), components: { child }, mounted () { // setTimeout模擬異步數據 setTimeout(() => { this.data= '異步的數據' }, 2000) this.flag = true } } </script>
2.子組件使用watch來監聽父組件改變的prop,使用methods來代替created,既然created只會執行一次,可是又想監聽改變的值作其餘事情的話,可以使用這個方法。
<template> <div> 子組件{{childData}} </div> </template> <script> export default { props: { childData:{ type:String } }, created () { console.log(this.childData) // 空值 }, watch: { childData: (val) { this.childData=val; this.updata(); } } methods: { updata () { console.log(this.childData); } } </script>
以上是整理的內容。