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

造轮子-toast组件的实现(下)

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

造轮子-toast组件的实现(下)

1.解决 toast 中传入 html 的问题,通过假的 slot 来实现

// plugins.js
toast.$slots.default = [message]
// toast.vue
 
// 使用
created() {
    this.$toast('

我是hi

',{}) },

2.在 toast 中加 html 是比较危险的一个动作,所以要加一个选项默认不开启。

// toast.vue


// plugin.js,进行传递参数的改写
propsdata:toastOptions
// 使用
created() {
  this.$toast('

我是hi

qq',{ enableHtml: false }) },

3.flex-shrink的使用,flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

.item {
  flex-shrink: ; 
}

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。如果数值越大,缩小比例越大。

4.line的高度问题,如果高度写了最小高度,那么子元素的height%就不生效了。用js去操作line的高度。

// toast.vue

    


mounted() {
  this.$nextTick(()=>{
    this.$refs.line.style.height = `${this.$refs.wrapper.getBoundingClientRect().height}px`
  })
}, // 这个计较太trick

debugger的技巧,如果眼睛观察到的是0,但是打印出来不是0,可能就是异步的问题。

5.增加toast的位置。

// toast.vue
props: {
  position: {
    type: String,
    default: 'top',
    validator(value){
      return ['top', 'bottom', 'middle'].indexOf(value) >= 0
    }
  }
},
computed:{
  toastClasses(){
    return {
      [`position-${this.position}`]:true
    }
  }
}
// 使用
this.$toast('你的智商需要充值', {
  position: 'bottom'
})
// plugin.js
export default {
  install(Vue, options){
    Vue.prototype.$toast = function (message, toastOptions) {
      let Constructor = Vue.extend(Toast)
      let toast = new Constructor({
 propsdata:toastOptions // 在这里将position传进去
      })
      toast.$slots.default = [message]
      toast.$mount()
      document.body.appendChild(toast.$el)
    }
  }
}

6.开始做如果已经有一个toast就把之前那个干掉,再出现。

  1. 先写一个函数
  2. 给函数取一个名字
  3. 把参数提出来
// plugin.js
import Toast from './toast'

let currentToast

export default {
  install(Vue, options){
    Vue.prototype.$toast = function (message, toastOptions) {
      if(currentToast){
 currentToast.close()
      }
      currentToast = createToast({Vue,message, propsdata: toastOptions})
    }
  }
}


function createToast ({Vue,message,propsData}){
  let Constructor = Vue.extend(Toast)
  let toast = new Constructor({propsData})
  toast.$slots.default = [message]
  toast.$mount()
  document.body.appendChild(toast.$el)
  return toast
}

7.实现动画

  1. 声明一个动画,然后写到类上面
   @keyframes fade {
     0% {opacity: 0; transform: translateY(100%);}
     100% {opacity: 1;transform: translateY(0);}
   } 
   .toast {
     animation: fade 1s;
   }
  1. 这里有个bug,我们在实现一次的时候是有问题的,如果toast被关闭了,我们不需要重复关闭,而我们写的是不管你之前的toast有没有关闭,只要有值的我们就关闭,那这样就会出现一个问题,点了关闭currentToast还是一个Toast并没有把它变成null,所以要加上一个回调告诉外面,我被关了不要重复关我,代码会多调一次close。
  // toast.vue
  close() {
    this.$el.remove()
    this.$emit('close')
    this.$destroy()
  }
  // plugin.js
  export default {
    install(Vue, options){
      Vue.prototype.$toast = function (message, toastOptions) {
 if(currentToast){
   currentToast.close()
 }
 currentToast = createToast({Vue,message, propsdata: toastOptions,onclose: ()=>{
     currentToast = null
   }
 }) // 加了这句话
      }
    }
  }

  
  function createToast ({Vue,message,propsData,onclose}){
    let Constructor = Vue.extend(Toast)
    let toast = new Constructor({propsData})
    toast.$slots.default = [message]
    toast.$mount()
    toast.$on('close',onclose) // 加了这句话
    document.body.appendChild(toast.$el)
    return toast
  }

  1. git相关的钩上,不想管的不用钩上
  2. 回忆bug是如何产生的,默认样式是:transform:translateX(-50%),进入0%时候transform:translateY(100%),它们两会覆盖。有三个方案,解决。
    • 换一种方式去做居中,但是这种方法是最好的,很难想
    • 不要用css做动画
    • 做两个div外面一个居中,里面一个做动画
  3. 为什么不写两个动画帧来控制居中,如果一段代码要背下来,那么一定是有问题的。
  4. 优化三种动画,上下中是不一样的,通过css进行优化。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/245149.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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