既然要使用Vue.extend()封装组件,那这玩意儿到底是什么呢?我们且来看官方解释
官方眼里的Vue.extend()
1.参数:
{Object} options
2.用法:
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
data 选项是特例,需要注意 – 在 Vue.extend() 中它必须是函数
<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
结果如下:
复制代码
<p>Walter White aka Heisenberg</p>
在下眼里的Vue.extend()
1.且听分解
按照目前的使用情况来讲,它一般用来封装通用(公共)的通知组件,类似ElementUI的Message提示组件等。
2.使用方式
它的使用方式与message组件是不一样的,它是函数式调用(eg:this.$message(‘test’)),类似的组件还有alert提示组件等通用的函数式组件,实现方法与此类似。
3.需要用到的vue的api
const Message = Vue.extend(message) // 使用基础 Vue 构造器,创建一个“子类”
const _Message = new Message({}) // 实例化组件
let vm = _Message.$mount() // 挂载, vm 就是组件里的this
复制代码
4.使用场景(实例)
此处以Message消息提示组件的封装为例,
源码src文件地址
(内含Message消息提示组件和MessageBox弹框的封装)
1)效果图
2) 代码实现
文件目录展示
![4PY160WO1{$`@132V(VTIX (1).png
// index.js
/* eslint-disable no-mixed-operators */
import Vue from 'vue';
// 导入的message对象为message.vue的配置项
import message from './Message';
// 将组件message.vue的配置项,作为Message类(VUe类,Vue构造器)的默认配置项,
const Message = Vue.extend(message);// 使用基础 Vue 构造器,创建一个“子类”
const vmArr = [];
function $message(opts) {
// 接收参数,传递给message类,覆盖默认值 比如:提示文字/自动关闭时间/主题颜色
// eslint-disable-next-line no-underscore-dangle
const _message = new Message({
data() {
return {
msg: opts.message || '默认提示',
type: opts.type,
isVisible: false,
// eslint-disable-next-line no-mixed-operators
top: `${vmArr.length * 68 + 20}px`,
};
},
methods: {
show() {
this.isVisible = true;
vmArr.push(this);
},
hide() {
this.isVisible = false;
vmArr.shift();
vmArr.forEach((item, index) => {
// eslint-disable-next-line no-param-reassign
item.top = `${index * 68 + 20}px`;
});
},
},
mounted() {
this.show();
setTimeout(() => {
this.hide();
}, 3000);
},
});// 实例化组件
// 模板编译到实例的$el属性
_message.$mount();
// 手动挂载到指定节点body
document.body.appendChild(_message.$el);
}
export default {
// eslint-disable-next-line no-shadow
install(Vue) {
// eslint-disable-next-line no-param-reassign
Vue.prototype.$message = $message;
},
};
复制代码
// Message.vue
<template>
<transition name="fade">
<div
v-if="isVisible"
class="message"
:style="{top: top}"
:class="type"
>
<svg v-if="type === 'success'" t="1619519648259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2605" width="14" height="14"><path d="M0 512a512 512 0 1 0 1024 0A512 512 0 1 0 0 512z" fill="#67c23a" p-id="2606" data-spm-anchor-id="a313x.7781069.0.i0" class=""></path><path d="M439.012 766.976a53.532 53.532 0 0 1-61.44 0.683 55.41 55.41 0 0 1-14.678-14.223L181.248 548.41a36.238 36.238 0 0 1 51.2-51.2l172.146 152.12 397.938-372.28a35.271 35.271 0 0 1 49.891 49.835L447.943 759.24a55.182 55.182 0 0 1-8.931 7.737z" fill="#ffffff" p-id="2607" data-spm-anchor-id="a313x.7781069.0.i1" class="selected"></path></svg>
<svg v-if="type === 'info'" t="1619520503387" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7563" width="14" height="14"><path d="M511.8464 0.4608C229.888 0.4608 0.6144 229.9392 0.6144 512.2048c0 282.2656 229.2736 511.744 511.232 511.744 282.0096 0 511.232-229.4784 511.232-511.744 0-282.2656-229.2224-511.744-511.232-511.744z m79.872 699.648c-38.2976 57.5488-77.4656 102.3488-143.7696 102.3488-44.6976-7.168-63.8976-39.9872-53.504-72.7552l84.6848-281.4976a13.4144 13.4144 0 0 0-7.9872-16.7424c-6.4-2.4064-18.432 5.5808-29.5936 17.5616l-50.2784 63.1808c-1.6384-10.3936 0-27.1872 0-34.4064 38.2976-57.5488 102.1952-103.936 144.5376-103.936 40.7552 3.9936 59.904 36.7616 52.736 72.7552l-85.504 283.0848c-0.768 6.4 2.4576 12.8 8.0384 15.1552 6.3488 2.4064 19.1488-5.5808 30.3616-17.5616l51.0976-61.5936c1.5872 9.6256-0.8192 28.0064-0.8192 34.4064zM580.608 332.288c-32.768 0-59.0848-24.0128-59.0848-58.368 0-35.1744 26.3168-58.368 59.0848-58.368 32.768 0 59.136 23.9616 59.136 58.368 0 35.1744-26.368 58.368-59.136 58.368z" p-id="7564" data-spm-anchor-id="a313x.7781069.0.i14" class="selected" fill="#909399"></path></svg>
{{msg}}
</div>
</transition>
</template>
<script>
export default {
name: 'Message',
};
</script>
<style>
.message {
box-sizing: border-box;
width: 380px;
text-indent: 20px;
line-height: 48px;
font-size: 14px;
border: 1px solid;
border-radius: 4px;
position: fixed;
z-index: 99;
top: 20px;
left: 50%;
transform: translate(-50%);
transition: all .4s;
}
.success {
color: #67c23a;
border-color: #e1f3d8;
background-color: #f0f9eb;
}
.info {
color: #909399;
border-color: #ebeef5;
background-color: #edf2fc;
}
.message > .icon {
margin-right: 10px;
transform: translateY(2px);
}
.fade-enter,.fade-leave-to {
opacity: 0;
transform: translate(-50%, -68px);
}
.fade-enter-to,.fade-leave {
opacity: 1;
transform: translate(-50%);
}
.fade-enter-active,.fade-leave-active {
transition: all .4s;
}
</style>
复制代码
//main.js
/* eslint-disable no-new */
import Vue from 'vue';
import App from './App';
import $message from './components/message';
Vue.use($message);
new Vue({
el: '#app',
name: 'Root',
template: '<App/>',
components: { App },
});
复制代码
// App.vue
<template>
<div class="container">
<button @click="message('success')">成功提示</button>
<button @click="message('info')">消息提示</button>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
message(type) {
this.$message({
type,
message: type === 'success' ? '恭喜你,这是一条成功消息' : '这是一条消息提示',
});
},
},
};
</script>
<style>
* {
margin: 0;
padding: 0;
user-select: none;
}
.container{
text-align: center;
line-height: 800px;
}
</style>
复制代码
以上就是使用Vue.extend()将Message提示组件封装成通用组件的全部代码了
特此说明
比起在座各位,在下还只是个超级小白白……还希望各位不吝赐教,毕竟我心里有数,代码是真的写的一般
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END