Vue. Use source code analysis
import { toArray } from '.. /util/index'
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
const args = toArray(arguments.1)
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this}}Copy the code
- Point 1: Avoid repeated installation, first there will be a check whether it has been installed, if so, directly back
- Point 2:
If the plug-in has the Install method, the install method is called directly
If the plug-in itself is a method, run it directly
Keep a record of installed plug-ins to avoid repeated installation
Two, vUE package plug-in common methods
1. Add global methods or attributes, such asvue-custom-element
MyPlugin.install = function (Vue, options) {
// The first method. Add global methods or properties
Vue.myGlobalMethod = function () {
/ / logic...}}Copy the code
Registration method
import registerCustomElement from './utils/registerCustomElement';
import { getProps, convertAttributeValue } from './utils/props';
function install(Vue) {
Vue.customElement = function vueCustomElement(tag, componentDefinition, options = {}) {
const isAsyncComponent = typeof componentDefinition === 'function';
const optionsProps = isAsyncComponent && { props: options.props || [] };
const props = getProps(isAsyncComponent ? optionsProps : componentDefinition);
// register Custom Element
const CustomElement = registerCustomElement(tag, {
// Related operations
});
return CustomElement;
};
}
export default install;
if (typeof window! = ='undefined' && window.Vue) {
window.Vue.use(install);
if (install.installed) {
install.installed = false; }}Copy the code
Method of use
Vue.customElement('widget-vue', {
props: [
'prop1'.'prop2'.'prop3'].data: {
message: 'Hello Vue! '
},
template: '{{ message }}, {{ prop1 }}, {{prop2}}, {{prop3}}
'
});
Copy the code
<widget-vue prop1="1" prop2="string" prop3="true"></widget-vue>
Copy the code
2. Add global resources: directives/filters/transitions, etc.vue-touch
vueTouch.install = function (Vue) {
Vue.directive('touch', {
isFn: true.acceptStatement: true.priority: Vue.directive('on').priority,
bind: function () {
// The binding operation
},
update: function (fn) {
// Update operations
},
unbind: function () {
// Unbind}})}Copy the code
3. Add some component options via mixin methods, such asvue-router
Plug-in internal definition:
Vue.mixin({
beforeCreate () {
if (isDef(this.$options.router)) {
this._routerRoot = this
this._router = this.$options.router
this._router.init(this)
Vue.util.defineReactive(this.'_route'.this._router.history.current)
} else {
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
}
registerInstance(this.this)
},
destroyed () {
registerInstance(this)}})Copy the code
External use:
new Vue({
router,
render: h= > h(App),
}).$mount('#app')
Copy the code
So each component will execute this._router.init(this) when executing the beforeCreate life cycle.
4. Add Vue instance methods by adding them to VUe.prototype
Vue.prototype.$myMethod = function (methodOptions)
{ / / logic... }
Copy the code
5. Globally register components, such aselementUI
// The sixth way is to register the componentVue.com Ponent (Component name, component)Copy the code
3. The principle of openness and isolation
Being open to extension means that existing code can be extended to accommodate new requirements or changes
Being closed to changes means that once the class is designed, it can do its work independently without making any changes to the class
Rule suggestions:
1. Open and closed principle is the most important design principle. Liskov substitution principle and composite/polymerization reuse principle provide guarantee for the realization of open and closed principle.
2. Reconstruction can be carried out through Template Method mode and Strategy mode to achieve a design idea that is closed to modification and open to expansion.
3. Encapsulating changes is an important means to realize the open and closed principle. For the frequently changing state, it is generally encapsulated as an abstraction, such as the IBankProcess interface in banking business.
4. Refuse to abuse abstraction and only abstract the parts that change frequently. This experience can be gained by learning and applying design patterns.
Iv. Principles of plug-in development
- Plug-in parameters should be kept to a minimum and focused on user concerns
- The implementation of a plug-in or component should be based on usage scenarios
- Developing a component or plug-in should maintain the open and closed principles of software engineering
- A good plug-in or component is not achieved overnight, and often needs to find problems in the later use process, to improve
-
- A component or plug-in must be well documented, and not everyone who uses it is concerned with its internal implementation. They are more concerned with getting started quickly
Five, core code
Toast the plugin
It can only be called functionally
import Toast from './component'
import { iconsMap, titleMap } from './config'
const ToastPlugin = {
install (Vue, options = {}) {
const ToastConstructor = Vue.extend(Toast)
Vue.prototype.$toast = toast
function buildProps (args) {
let props = {}
// Configuration item operation
return props
}
function toast () {
if (!arguments[0]) return
const propsData = buildProps(arguments)
const instance = new ToastConstructor({ propsData })
document.body.appendChild(instance.$mount().$el)
}
}
}
export default ToastPlugin
Copy the code
Text input includes emoticons
import Emoji from './App.vue'
const components = [
Emoji
]
const install = function (Vue, opts = {}) {
components.map(component= >{ Vue.component(component.name, component); })}/* Supports the use of tags to introduce */
if (typeof window! = ='undefined' && window.Vue) {
install(window.Vue);
}
export default {
install,
Emoji
}
Copy the code
Vue. use When installing the plug-in, the install method is executed directly, that is, it is registered globally and can be called via tags (elementUI).