移动端Vue2.x Picker的全局调用实现

2022-04-15 0 833
目录
  • 什么是Picker组件
  • Picker组件存在的问题
  • 解决思路
    • 选项解释
  • 解决方案
    • 目录划分
    • 描绘Picker容器
  • 创建Picker
    • 思路大纲
    • Picker函数
    • create
    • show
    • hide
  • remove
    • updateChildrenComponent
  • 结束语

    什么是Picker组件

    对标PC端的Select标签, 移动端的选择框一般是在viewPort底部弹出

    移动端Vue2.x Picker的全局调用实现

    Picker组件存在的问题

    • Picker通常以fixed布局,但是我们在写Picker组件时有遇到过该组件无法在viewport的底部弹出,而是在组件内部弹出,导致样式混淆,不符合C端审美,造成以上问题的原因是因为[层叠上下文]的原因,fixed布局并不是基于viewport为底板,而是当前的层叠上下文
    • Picker若是放置在根组件下的话会造成数据流流向出现混淆,嵌套过深层级的组件无法很便利的触发Picker的显示与隐藏,需要结合状态管理vuex来做处理或者通过透传$listeners,这在一定程度上增加了开发者的心智负担

    解决思路

    利用声明式编程将Picker放置在Body下去使用, 可以较好的规避以上的两个问题,例如利用以下方式调用picker的显示与隐藏

     this.$picker(组件选项, {
     wrapper: {
      props: {},
      on: {}
     },
     props: {},
     on: {}
     })
    

    选项解释

    • wrapper: picker函数编程参数
    • props: 组件选项的选项配置
    • on: 组件选项的时间绑定

    解决方案

    目录划分

     – Components
      – BaseUsedComponents
       – Picker
        – Picker.vue
        – index.js
     – main.js

    描绘Picker容器

    Picker.vue文件作用:

    • 绘制Picker容器
    • 利用transition内置组件结合css3的animation做动画过渡

    代码如下:

     <transition name="slideup">
     <div class="picker" v-if="show">
      <slot></slot>
      <div class="mask"></div>
     </div>
     </transition>
    

    创建Picker

    思路大纲

    • 定义一个Picker函数, 该函数需要做以下几点:
      • 生成Picker的实例PickerInstance
      • 将PickerInstance.show置为true
      • 将Picker容器放入到body底部
    • Picker组件生成需要使用防抖措施,不能在连续点击下
    • 将传入的组件选项根据props与on属性生成vnode,并且放置到默认插槽内
    • 点击mask元素会将Picker隐藏,这里需要再定义一个hide方法
    • hide方法需要做以下几个问题
      • 将实例下show属性置为false
      • 删除body下的安插Picker容器
      • 将实例置为Null,调用GC

    Picker函数

    移动端Vue2.x Picker的全局调用实现

    • 调用create函数生成Picker实例
    • 判断实例是否存在
    • 保留当前组件选项以及配置
    • 更改Picker组件的show属性弹出弹窗,并且安插到body下

    create

    • 创建一个el作为Picker的容器,安插到body下
    • 在render函数里,Picker将之前传入的组件选项作为默认插槽放置到内部,并且自身作为当前实例的子组件充当根元素
    • mounted函数里获取对应的transition时间作为之后hide时触发实际

    移动端Vue2.x Picker的全局调用实现

    为什么需要在requestAnimationFrame里去取动画时间, 而不是在mounted直接可以获取?

    组件的mounted函数是在初始化渲染后就会调用,而Toast组件通过设置showStatus去触发transition的enter函数(虽然Toast组件mounted在之前就会被调用,但此时toast dom上不存在transition class),此时由于触发的是data.setter函数,从而对Watcher进行派发更新,导致所有的操作都在nextTick(也就是微任务)里执行, 所以调用顺序是这样的:

    Toast组件Mounted -> 父组件Mounted(也就是现在所处的Mounted函数, 注意此时因为toast里的transition没有携带appear属性,导致transition enter函数不会触发,从而transition class不会被添加) -> nextTick() -> Toast组件update(v-show) -> transition(v-show触发enter函数) -> toast dom增加了transition类名 -> window.getComputedStyle(toast)获取toastDuration,我们也可以在nextTick里获取,介于transition active在动画全过程都会有,并且requestAnimationFrame属于浏览器重绘(painter)钩子函数,比微任务还要靠后执行,所以在这里获取

    show

    • 获取Picker的实例,Picker是作为该实例的根元素
    • 标记Mounted属性,表示已经安插
    • 监听show属性,在show置为false时调用hide函数
    • 安插到body下

    移动端Vue2.x Picker的全局调用实现

    hide

    • 重置Mounted属性为false
    • 将show函数里的定义的teardown监听函数删除掉,释放内存
    • 设置延时器作为删除真实DOM的钩子函数

    移动端Vue2.x Picker的全局调用实现

    为什么采用setTimeout去删除

    使用监听transtionend会有一个问题:

     Vue本身在transition组件子节点里监听了transitionend(或者animationend)
     动画完成后就会删除掉transition class, 那么此时transition-property就会消失掉
     根据文档显示, transition-property消失后将不触发transition钩子函数,继而无法触发
     transitionend函数,导致remove可能会无法调用,留下之前的ToastConainer

    remove

    remove函数作用是删除真实DOM、清除延时器、将timer以及Picker实例置为null, 调用GC

    移动端Vue2.x Picker的全局调用实现

    updateChildrenComponent

    Picker组件完成后,发现更改传入组件的里的props没有重新,所以这里写了一个手动触发更新组件的函数,组件vnode有4个钩子函数,prepatch是做为update时调用,值有两个,第一个是上一次的vnode,而第二个就是更改后的vnode,所以我们在PickerCommand函数里预暂了原先vnode以及Component,做为diff的旧vnode,调用此函数既可以更新组件

    移动端Vue2.x Picker的全局调用实现

    结束语

    Picker组件只是一个例子,还可以使用更多方法去实现。到此这篇关于移动端Vue2.x Picker的全局调用实现的文章就介绍到这了,更多相关Vue2.x Picker全局调用内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码! 

    免责声明:
    1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

    2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
    如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
    如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

    NICE源码网 JavaScript 移动端Vue2.x Picker的全局调用实现 https://www.niceym.com/32469.html