1.解决 toast 中传入 html 的问题,通过假的 slot 来实现
// plugins.js toast.$slots.default = [message] // toast.vue <div v-html="$slots.default[0]"></div> // 使用 created() { this.$toast('<p>我是<strong>hi</strong></p>',{}) },
2.在 toast 中加 html 是比较危险的一个动作,所以要加一个选项默认不开启。
// toast.vue <slot v-if="!enableHtml"></slot> <div v-else v-html="$slots.default[0]"></div> // plugin.js,进行传递参数的改写 propsData:toastOptions // 使用 created() { this.$toast('<p>我是<strong>hi</strong></p><a href="http://qq.com">qq</a>',{ enableHtml: false }) },
3.flex-shrink的使用,flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item { flex-shrink: <number>; /* default 1 */ }
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。如果数值越大,缩小比例越大。
4.line的高度问题,如果高度写了最小高度,那么子元素的height%就不生效了。用js去操作line的高度。
// toast.vue <div class="toast" ref="wrapper"> <div class="line" ref="line"></div> </div> 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就把之前那个干掉,再出现。
- 先写一个函数
- 给函数取一个名字
- 把参数提出来
// 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}) } } } /* helpers */ 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.实现动画
- 声明一个动画,然后写到类上面
@keyframes fade { 0% {opacity: 0; transform: translateY(100%);} 100% {opacity: 1;transform: translateY(0);} } .toast { animation: fade 1s; }
- 这里有个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 } }) // 加了这句话 } } } /* helpers */ 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 }
- git相关的钩上,不想管的不用钩上
- 回忆bug是如何产生的,默认样式是:transform:translateX(-50%),进入0%时候transform:translateY(100%),它们两会覆盖。有三个方案,解决。
- 换一种方式去做居中,但是这种方法是最好的,很难想
- 不要用css做动画
- 做两个div外面一个居中,里面一个做动画
- 为什么不写两个动画帧来控制居中,如果一段代码要背下来,那么一定是有问题的。
- 优化三种动画,上下中是不一样的,通过css进行优化。
来源:https://www.cnblogs.com/ories/p/12234961.html