栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

Vue造轮子-手风琴组件

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vue造轮子-手风琴组件

一. 大致的使用方法
  
    内容1
    内容2
    内容3
  

二. 完成最外部的样式
//collapse

  $grey: #ddd;
  $border-radius: 4px;
  .collapse {
    border: 1px solid $grey;
    border-radius: $border-radius;
  }


//collapse-item.vue

  $grey: #ddd;
  $border-radius: 4px;
  .collapseItem {
    > .title {
      border: 1px solid $grey;
      margin-top: -1px;
      margin-left: -1px;
      margin-right: -1px;
    }
    &:first-child {
      > .title {
 border-top-left-radius: $border-radius;
 border-top-right-radius: $border-radius;
      }
    }
  }

三. 进一步调节样式
// collapse-item

  $grey: #ddd;
  $border-radius: 4px;
  .collapseItem {
    > .title {
      border: 1px solid $grey;
      margin-top: -1px;
      margin-left: -1px;
      margin-right: -1px;
      min-height: 32px;
      display: flex;
      align-items: center;
      padding: 0 8px;
    }
    &:first-child {
      > .title {
 border-top-left-radius: $border-radius;
 border-top-right-radius: $border-radius;
      }
    }
    > .content{
      padding: 8px;
    }
  }


四. 默认内容折叠起来和点击切换,基本样式和基本功能完成
// collapse-item
    data (){
      return {
 open: false
      }
    }

    
      
    
五. 完善功能第一个点开,第二个就关闭
  • 因为结构比较简单,就父子两个组件,可以用父子通信来做。
    mounted(){
      this.eventBus.$on('update:selected', (vm)=>{
 if (vm !== this){
   this.close()
 }
      })
    },
    methods:{
      toggle(){
 if(this.open) {
   this.open = false
 }else{
   this.open = true
   this.eventBus.$emit('update:selected', this)
 }
      },
      close(){
 this.close()
      }
    }
六. 增加功能是否可以选择多个
  • 方案一.用 single 变量是否需要控制 eventBus
    // 添加single选项,有single就注入,没有就不注入
    // 但是这种方式不太完美会有警告
    props: {
      single: {
 type: Boolean,
 default: false
      }
    },
    provide() {
      if(this.single){
 return {
   eventBus: this.eventBus
 }
      }
    }
七. 可以设置默认 selected

// index.html

    
      
 内容1
 内容2
 内容3
      
    

// collapse-item.vue
    mounted(){
      this.eventBus && this.eventBus.$on('update:selected', (name)=>{
 if (name !== this.name){
   this.close()
 }else{
   this.show()
 }
      })
    },
八. 回头解决子元素是否可以多个打开
  • 通过 collapse.vue 传给 collapse-item
// index.js
  
    
      内容1 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus consequatur 
      内容2 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid cupiditate dolore d! 
       内容3 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi, magnam. 
      {{selectedTab}}
    
  
// collapse.vue
 mounted(){
      this.eventBus.$emit('update:selected',this.selected)
      this.eventBus.$on('update:selected', (name)=>{
 this.$emit('update:selected',name)
      })
      this.$children.forEach((vm)=>{
 vm.single = this.single
 console.log(vm)
      })
    }
// collapse-item.vue
  mounted(){
      this.eventBus && this.eventBus.$on('update:selected', (name)=>{
 if (name !== this.name){
   if(this.single){
     this.close()
   }
 }else{
   this.show()
 }
      })
    },
9.进一步修改,把选中的值改为数组
    // collapse.vue
    mounted(){
      this.eventBus.$emit('update:selected',this.selected)
      this.eventBus.$on('update:addSelected', (name)=>{
 this.selected.push(name)
 this.eventBus.$emit('update:selected',this.selected)  // 通知儿子
 this.$emit('update:selected',this.selected) // 通知外面
      })
      this.eventBus.$on('update:removeSelected', (name)=>{
 let index = this.selected.indexOf(name)
 this.selected.splice(index,1)
 this.eventBus.$emit('update:selected',this.selected)
 this.$emit('update:selected',this.selected)
      })
      this.$children.forEach((vm)=>{
 vm.single = this.single
 console.log(vm)
      })
    }
    // collapse-item.vue
    methods:{
      toggle(){
 if(this.open) {
   this.open = false
   this.eventBus && this.eventBus.$emit('update:removeSelected', this.name)
   // 移除一个被选中的东西
 }else{
   this.eventBus && this.eventBus.$emit('update:addSelected', this.name)
 }
      },
    }

####10. 将所有数据流让父组件统一管理。

  • 不能直接操作 props 要先深拷贝
  // collapse.vue
      mounted(){
      this.eventBus.$emit('update:selected',this.selected)
      this.eventBus.$on('update:addSelected', (name)=>{
 let selectedCopy = JSON.parse(JSON.stringify(this.selected))
 if(this.single){
   selectedCopy = [name]
 }else{
   selectedCopy.push(name)
 }
 this.eventBus.$emit('update:selected',selectedCopy)  // 通知儿子
 this.$emit('update:selected',selectedCopy) // 通知外面
      })
      this.eventBus.$on('update:removeSelected', (name)=>{
 let selectedCopy = JSON.parse(JSON.stringify(this.selected))
 let index = selectedCopy.indexOf(name)
 selectedCopy.splice(index,1)
 this.eventBus.$emit('update:selected',selectedCopy)
 this.$emit('update:selected',selectedCopy)
      })
      this.$children.forEach((vm)=>{
 vm.single = this.single
 console.log(vm)
      })
    }

11. 数据流的核心
  • 不要出现两个东西互相让对方更新的状态
  // collapse.vue 爸爸
      mounted(){
      this.eventBus.$emit('update:selected',this.selected) // 一开始就通知所有儿子,该选中就选中
      this.eventBus.$on('update:addSelected', (name)=>{
 let selectedCopy = JSON.parse(JSON.stringify(this.selected))
 // 如果用户添加一个我就把selected拷贝一份,因为vue不支持直接修改props
 if(this.single){
   selectedCopy = [name]
 }else{
   selectedCopy.push(name)
 }
 this.eventBus.$emit('update:selected',selectedCopy)  // 得到最新被选中的item之后,通知儿子
 this.$emit('update:selected',selectedCopy) // 通知外面
      })

      this.eventBus.$on('update:removeSelected', (name)=>{
 let selectedCopy = JSON.parse(JSON.stringify(this.selected))
 let index = selectedCopy.indexOf(name)
 selectedCopy.splice(index,1)
 this.eventBus.$emit('update:selected',selectedCopy) // 如果用户想移除,也通知他儿子该移除就移除
 this.$emit('update:selected',selectedCopy)
      })
      this.$children.forEach((vm)=>{
 vm.single = this.single
 console.log(vm)
      })
    }¡
    // collapse-item.vue 儿子
 mounted(){
      this.eventBus && this.eventBus.$on('update:selected', (names)=>{
 // 监听eventBus,只要他爸爸要说更新,他就更新
 console.log(names)
 if (names.indexOf(this.name )>= 0){
   this.open = true
 }else{
     this.open = false
 }
      })
    },
    methods:{
      toggle(){
 if(this.open) {
   // 这里也没有修改自己的OPEN,而是在mounted中等爸爸通知我们修改open,所以他的open永远是爸爸在操作,儿子不操作
   this.eventBus &&this.eventBus.$emit('update:removeSelected', this.name)
   // 他自己触发一个意图,打算移除一个更新
   // 移除一个被选中的东西
 }else{
   this.eventBus && this.eventBus.$emit('update:addSelected', this.name)
   // 他自己触发一个意图,打算添加一个更新
 }
      },
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/240449.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号