我一直都相信,决定将来的是自信与成长速度,成长的过程当中,整理是一个很是重要的环节,接下来是我整理的系统组件开发经常使用的部分。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>
以上是整理的内容。