简述:使用vue.extend返回一个子类构造函数,也就是预设部分选项的vue实例构造器。
也就是说var myVue = vue.extend()返回了vue的一个子类。
后面可以用vue.component()、new myVue().$mount('#id')、new myVue({el:'#id'}) 进行实例化。
实例:
<template>
<my-footer></my-footer>
</template>
<script>
let Footer = Vuew.extend({
data(){
return {
footerName:'I CAN DO IT...'
}
},
template:'<div>{{footerName}}</div>'
});
Vue.component('footer-view',Footer);
// new Footer({
// data:{
// '...':''
// }
// }).$mount('my-footer')
</script>
vue.extend()不经常用到,通常直接用vue.component更简单。
vue.extend 应用场景:
假如我想利用js代码动态的渲染组件,比如我想实现一个类似 alert() 的提示插件。这个时候 vue.extend() 和 vm.$mount()就出场了。
vue的信息提示插件message实例:
message/index.js
import Vue from 'vue'
import Message from './index.vue'
const MessagePlugin = Vue.extend(Message) // 关键代码
export default {
install(Vue) {
// this.$message(option)
Vue.prototype.$message = function({
type = 'info', // 消息类型
message = '提示信息!', // 提示信息
offset = '30', // top偏移量
showClose = false, // 是否显示关闭 按钮
duration = 3000, // 提示停留时间
onClose = null // 提示关闭后的回调函数
} = {}) {
let $vvm
if (!$vvm) {
// $vvm = new MessagePlugin({
// el: document.createElement('div')
// })
$vvm = new MessagePlugin()
$vvm.type = type
$vvm.showClose = showClose
$vvm.offset = offset
$vvm.duration = duration
$vvm.message = message
$vvm.onClose = onClose
$vvm.$mount(document.createElement('div')) //关键代码
document.body.appendChild($vvm.$el) // 关键代码
}
return $vvm.$el
}
}
}
message/index.vue
<template>
<transition
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
@before-leave="beforeLeave"
@after-leave="afterLeave"
>
<div v-show="showMessage" ref="msg" class="message-box">
<p class="message">
<svg-icon class-name="icon" :icon-class="'m-'+type" />
<span>{{ message }}</span>
</p>
<span v-if="showClose" @click="clickClose">X</span>
</div>
</transition>
</template>
<script>
export default {
data() {
return {
showMessage: false, // 是否显示信息
type: '', // info success warning error 默认info
message: '',
offset: '30', // top偏移量 单位px
showClose: true, // 是否显示关闭按钮
duration: 3000, // 信息停留时间 ms
onClose: null, // 关闭后回调
timer: null
}
},
mounted() {
this.init()
},
methods: {
init() {
this.showMessage = true
this.close()
},
// 关闭信息
close() {
const that = this
this.timer = setTimeout(() => {
that.showMessage = false
}, that.duration)
},
// 手动关闭
clickClose() {
this.showMessage = false
this.timer && clearTimeout(this.timer)
},
beforeEnter(el) {
console.log('beforeEnter')
el.style.opacity = 0
el.style.top = '0px'
},
enter(el, done) {
console.log('enter')
const that = this
setTimeout(function() {
el.style.opacity = 1
el.style.top = that.offset + 'px'
}, 0)
},
beforeLeave(el) {
console.log('beforeLeave')
el.style.opacity = 1
el.style.top = this.offset + 'px'
},
leave(el, done) {
console.log('leave')
el.style.opacity = 0
el.style.top = '0px'
setTimeout(() => {
done()
}, 200) // 动画时间持续200ms
},
// 关闭信息
afterLeave(el) {
console.log('afterLeave')
document.body.removeChild(el) // 关键代码
this.onClose && this.onClose()
}
}
}
</script>
<style scoped lang="scss">
.message-box {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: center;
justify-content: space-between;
width: 9rem;
max-width: 90%;
height: 0.8rem;
line-height: .8rem;
padding: 0 .3rem;
border-radius: .08rem;
font-size: 0.28rem;
transition: all .2s ease-in;
z-index: 1000;
&.info {
color: #666;
background: lighten(#666, 50);
}
&.success {
color: #67C23A;
background: lighten(#67C23A, 42);
}
&.warning {
color: #E6A23C;
background: lighten(#E6A23C, 35);
}
&.error {
color: #F56C6C;
background: lighten(#F56C6C, 25);
}
.message {
display: flex;
align-items: center;
}
.icon {
color: inherit;
font-size: 1.5em;
margin-right: 0.1rem;
}
}
</style>