镇江网站建设价格,cad dwt模板做网站模版,怎么创建自己的官网,深圳网站建设怎样目录
0.概念解释
前言
需求分析
Vue.extend
编程式的使用组件
源码分析 0.概念解释 Vue.extend和VueComponent是Vuejs框架中创建组件的两种不同方式。Vue.extend方法能够让你根据Vue对象#xff08;继承#xff09;来定义一个新的可重用的组件构造器。而VueComponent方…目录
0.概念解释
前言
需求分析
Vue.extend
编程式的使用组件
源码分析 0.概念解释 Vue.extend和VueComponent是Vuejs框架中创建组件的两种不同方式。Vue.extend方法能够让你根据Vue对象继承来定义一个新的可重用的组件构造器。而VueComponent方法则是将该元件定义下侧的函数以及组件实例化时需要用到的选项如data、computed、watch、methods、created等作为对象传入系统会将这个对象转换成一个Vue的构造器。 两者的关系是 Vue.extend本质上是一个用来创建Vue组件的函数而VueComponent是定义组件的一种方式。使用Vue.extend可以灵活地定义组件而使用VueComponent可以使代码更加简洁可以快速创建出组件。Vue.extend的好处是它可以通过链式调用更方便地定义组件而在VueComponent中只允许传入对象参数因此Vue.extend灵活度更高。尽管VueComponent定义组件更简洁但其性能却不及Vue.extend而且它也不便于做复杂的组件定义。因此Vue.extend和VueComponent有其各自的应用场景可以根据实际需求来选择使用哪一种而不是简单地把它们二者看成同一种方式。
前言
写Vue.js已经3年了吧对Vue.extend全局方法的了解也就停留在了解啦一直抱着不用就不学的思想造成了一次又一次的错过~~~
直到最近才通过公司10年秃头少年的代码才知道错过Vue.extend方法也就等于错过了对Vue组件的第二春了解的机会 需求分析
在页面中弹出消息提示框比如在用户点击按钮给予回应
这种业务场景很常见吧肯定是先创建一个弹框组件在需要使用弹框的地方注册组件并挂载到页面上去
但是需求还没结束又提出在所以页面都可以弹出这个消息提示框
首选局部注册肯定是不行了局部注册只能当前页面使用所以要选择在App.vue中注册并挂载因为App.vue是所有组件的根组件所以组件也都能访问到App.vue中的方法我们只需要在App.vue暴露一个弹框显示的方法就可以了
产品还不打算放过我又提出需求是可以同时出现多个消息提示框
这个就不好实现了呀一个组件挂载只能弹出一个提示框总不能在App.vue挂载很多个吧其实这也是解决方案但是不利于扩展、占用内存
那就没有办法了吗也不是那就要请出主角Vue.extend全局方法 Vue.extend
看看官方的八股文
使用基础 Vue 构造器创建一个“子类”。参数是一个包含组件选项的对象
我认为这段文字表达十分明了首先Vue.extend参数是包含组件选项的对象返回值是Vue的子类
import Vue from vue
let VueComponent Vue.extend({})
VueComponent.prototype.__proto__ Vue.prototype // true
我们这里将子类称为VueComponent
你对这个名称很熟悉吧~~~
import Vue from vue/dist/vue.esm.js // 必须引入这个版本的Vue才可以使用template选项
new Vue({el: #app,template: App/App,components: { App },mounted() {let app this.$children[0]; // App组件实例let VueComponent app.constructor // App构造函数console.log(app);console.log(VueComponent);console.log(VueComponent.prototype.__proto__ Vue.prototype);}
})
不难发现VueComponent就是组件的构造函数~~~
是不是一下就明白了Vue.extend的返回值就是组件的构造函数传入的选项就是组件的初始配置
Vue.extend作用可以理解为
首选创建一个Vue类的子类组件的构造函数将传入的组件选项配置当做实例子类的默认值组件的初始配置并返回这个类组件的构造函数
Vue.component(Toast, {}) // 全局注册组件
console.log(Vue.component(Toast)); // Toast组件构造函数
在使用Vue.component方法注册全局组件时其实内部也是先调用Vue.extend生成VueComponent再声明到全局组件中局部组件也是一样的~~~
其实这里还能了解一个知识点所以的组件构造函数的父类都是Vue所以组件可以使用Vue上所以方法和属性比如emit、set等 编程式的使用组件
VueComponent可以被称为小VueVueComponent的使用也就可以对照Vue
let VueComponent Vue.extend({})
new VueComponent({el: #app,template: h1Vue.extend的使用/h1
})
是不是和Vue的使用一模一样喃
区别在于Vue.extend可以通过参数确定组件的初始配置~~~
现在完成一下最开始的需求吧~
编写my-toast.vue
templateh1 classtitle v-ifshow{{ title }}/h1
/template
scriptexport default {name: my-toast,props: {title: {typeof: String,default: }},data() {return {show: true};},created() {setTimeout(() {this.show false;this.$nextTick(() {this.$destroy();});}, 2000);}};
/script
style.title {width: 180px;height: 50px;position: fixed;right: 20px;top: 20px;background-color: rgba(0, 0, 0, 0.15);text-align: center;line-height: 50px;border-radius: 8px;font-size: 16px;}
/style
在vue的原型上绑定显示弹框方法
import Vue from vue;
import myToast from ./components/my-toast.vue;
Vue.prototype.$toast function (title) {const ToastComponent Vue.extend(myToast);const toastComponent new ToastComponent({propsData: {title}})toastComponent.$mount(document.createElement(div));document.body.appendChild(toastComponent.$el);
}
在需要弹框的地方调用方法
// ....某vue页面
mounted() {this.$toast(测试);
}
let vm new VueComponent(options)的注意点
传递的props配置需要配置到propsData属性中使用VueX、VueRoter等第三方模块需要把这些模块挂载到options上使用插槽需要通过vm.$scopedSlots传递源码分析
你可以在源码目录src/core/global-api/extend.js下找到这个函数的定义
Vue.extend function (extendOptions: any): typeof Component {extendOptions extendOptions || {}// this指的是Vueconst Super this// 每个组件构造函数都有唯一的cidconst SuperId Super.cid// 创建完的VueComponent构造函数会保存到_Ctor中// 如果下次传入相同的extendOptions和SuperId就直接取用缓存内的值const cachedCtors extendOptions._Ctor || (extendOptions._Ctor {})if (cachedCtors[SuperId]) {return cachedCtors[SuperId]}// 获取组件nameconst name getComponentName(extendOptions) || getComponentName(Super.options)if (__DEV__ name) {// 校验组件namevalidateComponentName(name)}// 创建VueComponent构造函数const Sub function VueComponent(this: any, options: any) {this._init(options)} as unknown as typeof Component// 重点实现了原型链继承让VueComponent的原型指向Vue的原型// Vue的原型的所有方法和属性在VueComponent也存在Sub.prototype Object.create(Super.prototype)Sub.prototype.constructor Sub// 生成唯一cidSub.cid cid// 传入的extendOptions和Vue.options合并Sub.options mergeOptions(Super.options, extendOptions)Sub[super] Super// 配置props的响应式if (Sub.options.props) {initProps(Sub)}// 配置computed的响应式if (Sub.options.computed) {initComputed(Sub)}// 继承静态方法Sub.extend Super.extendSub.mixin Super.mixinSub.use Super.use// ASSET_TYPES [component, directive, filter]ASSET_TYPES.forEach(function (type) {Sub[type] Super[type]})if (name) {Sub.options.components[name] Sub}// 保存基础配置Sub.superOptions Super.optionsSub.extendOptions extendOptionsSub.sealedOptions extend({}, Sub.options)// 设置缓存cachedCtors[SuperId] Subreturn Sub}
Vue.extend关键在于继承Vue抛开其他功能代码主要实现继承的代码
// 继承原型
Sub.prototype Object.create(Super.prototype)
Sub.prototype.constructor Sub
// 继承静态方属性和方法
// 继承静态方法
Sub.extend Super.extend
Sub.mixin Super.mixin
Sub.use Super.use
// ASSET_TYPES [component, directive, filter]
ASSET_TYPES.forEach(function (type) {Sub[type] Super[type]
})