Maison >interface Web >js tutoriel >Compréhension approfondie de l'API globale Vue
Est-ce que tout le monde connaît l'API ? Cet article présente principalement une compréhension approfondie de l'API globale de la documentation officielle de Vue. L'éditeur pense qu'elle est plutôt bonne, je vais donc la partager avec vous maintenant et la donner comme référence. Suivons l'éditeur pour y jeter un œil, j'espère que cela pourra aider tout le monde.
Vue.extend
Les données de l'élément de configuration doivent fonctionner, sinon la configuration n'est pas valide. Le code source des règles de fusion de données (vous pouvez consulter "Vue Official Documentation - Global Configuration") est le suivant :
Transmettre les données de type non-fonction (le données dans l'image ci-dessus configurée comme {a:1}), lors de la fusion d'options, si les données ne sont pas de type fonction, la version de développement émettra un avertissement puis renverra directement parentVal, ce qui signifie que l'option de données transmise par extend est ignoré.
Nous savons que lors de l'instanciation de Vue, les données peuvent être un objet. Les règles de fusion ici ne sont-elles pas universelles ? Notez qu'il existe un jugement if(!vm) ci-dessus. vm a une valeur lorsqu'il est instancié, il est donc différent de Vue.extend. En fait, les commentaires suivants l'expliquent également (dans une fusion Vue.extend, les deux devraient fonctionner. ), c'est pourquoi la documentation officielle indique que les données constituent un cas particulier.
De plus, la "sous-classe" mentionnée dans le document officiel est due au fait que Vue.extend renvoie une fonction qui "hérite" de Vue. La structure du code source est la suivante :
Vue.extend = function (extendOptions) { //*** var Super = this; var SuperId = Super.cid; //*** var Sub = function VueComponent(options) { this._init(options); }; Sub.prototype = Object.create(Super.prototype); Sub.prototype.constructor = Sub; //*** return Sub };
Vue.nextTick
Puisque vous utilisez vue, vous devez bien sûr penser de manière basée sur les données. appelé basé sur les données signifie ne pas faire fonctionner directement le dom, toutes les opérations du dom peuvent être effectuées en utilisant diverses instructions de vue. Les instructions "lient" les données au dom peuvent non seulement mettre à jour le dom, mais aussi être plus pratiques.Vue.nextTick().then(() => { // do sth })Le rappel permettant à Vue d'exécuter nextTick utilise la méthode d'appel cb.call(ctx) est l'instance actuelle de Vue, elle peut donc être utilisé directement dans le callback. Celui-ci appelle la configuration de l'instance.
nextTick peut être simplement compris comme plaçant le rappel à la fin pour l'exécution. Si Promise et MutationObserver ne sont pas actuellement pris en charge dans le code source, la méthode setTimeout sera utilisée pour exécuter le rappel. retarder l'exécution du code.
if (typeof Promise !== 'undefined' && isNative(Promise)) { } else if (typeof MutationObserver !== 'undefined' && ( isNative(MutationObserver) || // PhantomJS and iOS 7.x MutationObserver.toString() === '[object MutationObserverConstructor]' )) { } else { // fallback to setTimeout /* istanbul ignore next */ timerFunc = function () { setTimeout(nextTickHandler, 0); }; }Prenons un exemple :
<p id="app"> <p ref="dom">{{a}}</p> </p> new Vue({ el: '#app', data: { a: 1 }, mounted: function name(params) { console.log('start'); this.$nextTick(function () { console.log('beforeChange', this.$refs.dom.textContent) }) this.a = 2; console.log('change'); this.$nextTick(function () { console.log('afterChange', this.$refs.dom.textContent) }) console.log('end'); } }) // 控制台依次打印 // start // change // end // beforeChange 1 // afterChange 2Vous pourriez être un peu confus. Puisqu'il est exécuté en dernier, pourquoi beforeChange génère-t-il 1 au lieu de 2 ? C'est parce que la mise à jour dom déclenchée derrière this.a=2 utilise également nextTick. L'ordre d'exécution réel du code ci-dessus est :beforeChange>Update dom>. ;aprèsChangement.
Vue.set
Vue.set( target, key, value ), la cible ne peut pas être une instance de Vue, ni l'objet de données racine d'une instance de Vue, car cela est fait dans le code source Le jugement suivant est rendu :var ob = (target).__ob__; if (target._isVue || (ob && ob.vmCount)) { "development" !== 'production' && warn( 'Avoid adding reactive properties to a Vue instance or its root $data ' + 'at runtime - declare it upfront in the data option.' ); return val }target._isVue empêche l'ajout d'attributs à l'instance Vue, ob && ob. vmCount empêche l'ajout de l'objet de données racine des propriétés Ajouter de l'instance Vue.
Vue.delete
Si Vue peut détecter l'opération de suppression, alors cette API n'apparaîtra pas. Si vous devez utiliser delete pour supprimer l'attribut $data, utilisez Vue.delete, sinon la mise à jour dom ne sera pas déclenchée.var a = [1, 2, 3]; delete a[0]; console.log(a); // [undefined, 2, 3]
Vue.use
Vue.use Le code source est relativement simple et peut être publié dans complet.Vue.use = function (plugin) { var installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters var 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 };Les plug-ins installés sont placés dans InstallPlugins Avant d'installer le plug-in, utilisez InstallPlugins.indexOf(plugin) pour déterminer si le plug est installé. -in a été installé, empêchant ainsi le même plugin d'enregistrement plusieurs fois.
Vue.use({ a: 1, install: function (Vue) { console.log(this.a) // 1 console.log(arguments) // [function Vue(options),"a", "b", "c"] } }, 'a', 'b', 'c')Le type de plug-in est fonction, et l'installation appelle plugin.apply(null, args);, donc en mode strict le plug- dans le contexte d'exécution, il s'agit de null , le mode non strict est Window.
'use strict' Vue.use(function plugin() { console.log(this) // null console.log(arguments) // [function Vue(options),"a", "b", "c"] }, 'a', 'b', 'c')
Vue.compile
和众多 JS 模板引擎的原理一样,预先会把模板转化成一个 render 函数,Vue.compile 就是来完成这个工作的,目标是将模板(template 或 el)转化成 render 函数。
Vue.compile 返回了{render:Function,staticRenderFns:Array},render 可直接应用于 Vue 的配置项 render,而 staticRenderFns 是怎么来的,而且按照官网的例子,Vue 还有个隐藏的配置项 staticRenderFns,先来个例子看看。
var compiled = Vue.compile( '<p>' + '<header><h1>no data binding</h1></header>' + '<section>{{prop}}</section>' + '</p>' ) console.log(compiled.render.toString()) console.log(compiled.staticRenderFns.toString()) // render function anonymous() { with(this) { return _c('p', [_m(0), _c('section', [_v(_s(prop))])]) } } // staticRenderFns function anonymous() { with(this) { return _c('header', [_c('h1', [_v("no data binding")])]) } }
原来没有和数据绑定的 dom 会放到 staticRenderFns 中,然后在 render 中以_m(0)来调用。但是并不尽然,比如上述模板去掉4a249f0d628e2318394fd9b75b4636b1,staticRenderFns 长度为 0,header 直接放到了 render 函数中。
function anonymous() { with(this) { return _c('p', [_c('header', [_v("no data binding")]), _c('section', [_v(_s(prop))])]) } }
Vue.compile 对应的源码比较复杂,上述渲染 1aa9e5d373740b65a0cc8f0a02150c53 没有放到 staticRenderFns 对应源码的核心判断如下:
// For a node to qualify as a static root, it should have children that // are not just static text. Otherwise the cost of hoisting out will // outweigh the benefits and it's better off to just always render it fresh. if (node.static && node.children.length && !( node.children.length === 1 && node.children[0].type === 3 )) { node.staticRoot = true; return } else { node.staticRoot = false; }
1aa9e5d373740b65a0cc8f0a02150c53 不符判断条件 !(node.children.length === 1 && node.children[0].type === 3), 1aa9e5d373740b65a0cc8f0a02150c53 有一个子节点 TextNode(nodeType=3)。 注释也说明了一个 node 符合静态根节点的条件。
另外官网说明了此方法只在独立构建时有效,什么是独立构建?这个官网做了详细的介绍,不再赘述。对应官网地址:对不同构建版本的解释。
仔细观察编译后的 render 方法,和我们自己写的 render 方法有很大区别。但是仍然可以直接配置到 render 配置选项上。那么里面的那些 _c()、_m() 、_v()、_s() 能调用?随便看一个 Vue 的实例的 __proto__ 就会发现:
// internal render helpers. // these are exposed on the instance prototype to reduce generated render // code size. Vue.prototype._o = markOnce; Vue.prototype._n = toNumber; Vue.prototype._s = toString; Vue.prototype._l = renderList; Vue.prototype._t = renderSlot; Vue.prototype._q = looseEqual; Vue.prototype._i = looseIndexOf; Vue.prototype._m = renderStatic; Vue.prototype._f = resolveFilter; Vue.prototype._k = checkKeyCodes; Vue.prototype._b = bindObjectProps; Vue.prototype._v = createTextVNode; Vue.prototype._e = createEmptyVNode; Vue.prototype._u = resolveScopedSlots; Vue.prototype._g = bindObjectListeners;
正如注释所说,这些方法是为了减少生成的 render 函数的体积。
全局 API 还剩 directive、filter、component、mixin,这几个比较类似,而且都对应着配置项,会在「选项」中再详细介绍。
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!