Vue3 has been around for a while, and vuE3 + TS was used in a new project last year, so I’ve been trying to write something. There are many blogs that compare the two versions, so I will not write them (in case they are not good enough and the writing is not good enough to make people laugh). So write something small, like the -Toast widget. If there is anything wrong, please correct me.
Vue3 spelled
<! -- ./src/main.vue -->
<template>
<transition name="scale">
<div v-show="visible" class="jr-toast">
<div class="jr-toast_content">
{{ content }}
</div>
</div>
</transition>
</template>
<script>
import { defineComponent, reactive, ref, toRefs } from 'vue'
export default defineComponent({
setup() {
const state = reactive({
content: ' '.type: ' '.// You can display different ICONS according to different types
delay: ' '
})
const visible = ref(false)
let timer
const close = () = > {
clearTimeout(timer)
visible.value = false
timer = null
}
const open = () = > {
if (timer) clearTimeout(timer)
visible.value = true
timer = setTimeout(close, state.delay)
return close
}
return {
...toRefs(state),
visible,
open,
close
}
}
})
</script>
<style lang="scss" scoped>
.jr-toast {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
.jr-toast_content {
padding: 10px 20px;
color: #fff;
word-break: break-all;
background-color: rgba(0.0.0.7);
border-radius: 10px;
}
.scale-enter-active..scale-leave-active {
transition: transform .2s;
}
.scale-enter..scale-leave-to {
transform: scale(0)}</style>
Copy the code
// index.js
import { createApp } from 'vue'
import main from './src/main.vue'
let instance
const initInstance = () = > {
// This is the biggest difference from VUE2
// In vue2, we just need instance.$mount() to get the node
const app = createApp(main)
// Need a container
const container = document.createElement('div')
// Mount again - After mounting, return the instance context
instance = app.mount(container)
document.body.appendChild(container)
}
const Toast = option= > {
if(! instance) initInstance() option =typeof option === 'string' ? { content: option } : option
const defaultOption = {
content: ' '.delay: 1500.type: 'info'
}
for (const key in defaultOption)
instance[key] = option[key] || defaultOption[key]
return instance.open()
}
const types = ['success'.'error'.'warn'.'info']
types.forEach(type= > Toast[type] = content= > Toast({ content, type }))
// Export the method directly
export default Toast
// // or mount on the global configuration of the root instance
// export default app => app.config.globalProperties.$Toast = Toast
Copy the code
Vue2 spelled
<! -- ./src/main.vue -->
<template>
<transition name="scale">
<div v-show="visible" class="jr-toast">
<div class="jr-toast_content">
{{ content }}
</div>
</div>
</transition>
</template>
<script>
export default {
props: {
content: String.type: String.delay: String
},
data() {
return {
timer: null.visible: false}},methods: {
open() {
const { timer, delay, close } = this
if (timer) clearTimeout(timer)
this.visible = true
this.timer = setTimeout(close, delay)
return close
},
close() {
clearTimeout(this.timer)
this.timer = null
this.visible = false}}}</script>
<style lang="scss" scoped>
.jr-toast {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
.jr-toast_content {
padding: 10px 20px;
color: #fff;
word-break: break-all;
background-color: rgba(0.0.0.7);
border-radius: 10px;
}
.scale-enter-active..scale-leave-active {
transition: transform .2s;
}
.scale-enter-from..scale-leave-to {
transform: scale(0)}</style>
Copy the code
// index.js
import Vue from 'vue'
import main from './src/main.vue'
// Vue2 needs to extend a subclass with vue.extend ()
const Constructor = Vue.extend(main)
let instance
const Toast = option= > {
if(! instance) { instance =new Constructor()
instance.$mount()
document.body.appendChild(instance.$el)
}
option = typeof option === 'string' ? { content: option } : option
const defaultOption = {
content: ' '.delay: 1500.type: 'info'
}
for (const key in defaultOption)
instance[key] = option[key] || defaultOption[key]
return instance.open()
}
const types = ['success'.'error'.'warn'.'info']
types.forEach(type= > Toast[type] = content= > new Toast({ content, type }))
export default Vue => Vue.prototype.$Toast = Toast
Copy the code
The complete code
vue3 Toast
vue2 Toast