UNPKG

@mpxjs/core

Version:

mpx runtime core

135 lines (128 loc) 4.23 kB
import { walkChildren, parseSelector, error, hasOwn, collectDataset } from '@mpxjs/utils' import { createSelectorQuery, createIntersectionObserver } from '@mpxjs/api-proxy' import { EffectScope } from 'vue' import { PausedState } from '../../helper/const' const hackEffectScope = () => { EffectScope.prototype.pause = function () { if (this.active) { let i, l for (i = 0, l = this.effects.length; i < l; i++) { const effect = this.effects[i] // vue2.7中存在对于watcher实例方法的重写(doWatch),因此无法通过修改Watcher.prototype统一实现pause和resume,只能逐个实例修改实现 if (!hasOwn(effect, 'pausedState')) { effect.pausedState = PausedState.resumed const rawUpdate = effect.update effect.update = function () { if (effect.pausedState !== PausedState.resumed) { effect.pausedState = PausedState.dirty } else { rawUpdate.call(effect) } } } if (effect.pausedState !== PausedState.dirty) { effect.pausedState = PausedState.paused } } if (this.scopes) { for (i = 0, l = this.scopes.length; i < l; i++) { this.scopes[i].pause() } } } } EffectScope.prototype.resume = function (ignoreDirty = false) { if (this.active) { let i, l for (i = 0, l = this.effects.length; i < l; i++) { const effect = this.effects[i] if (hasOwn(effect, 'pausedState')) { const lastPausedState = effect.pausedState effect.pausedState = PausedState.resumed if (!ignoreDirty && lastPausedState === PausedState.dirty) { effect.update() } } } if (this.scopes) { for (i = 0, l = this.scopes.length; i < l; i++) { this.scopes[i].resume(ignoreDirty) } } } } } export default function install (Vue) { Object.defineProperties(Vue.prototype, { data: { get () { return Object.assign({}, this.$props, this.$data) }, enumerable: true, configurable: true }, dataset: { get () { return collectDataset(this.$attrs, true) }, enumerable: true, configurable: true }, id: { get () { return this.$attrs.id || '' }, enumerable: true, configurable: true } }) Vue.prototype.__ensureString = function (val) { if (typeof val === 'string') { return val } return JSON.stringify(val) + 'MpxEscape' } Vue.prototype.triggerEvent = function (eventName, eventDetail) { // 输出Web时自定义组件绑定click事件会和web原生事件冲突,组件内部triggerEvent时会导致事件执行两次,将click事件改为_click来规避此问题 const escapeEvents = ['click'] if (escapeEvents.includes(eventName)) { eventName = '_' + eventName } let eventObj = {} const dataset = this.dataset const id = this.id const timeStamp = +new Date() eventObj = { type: eventName, timeStamp, target: { id, dataset, targetDataset: dataset }, currentTarget: { id, dataset }, detail: eventDetail } return this.$emit(eventName, eventObj) } Vue.prototype.selectComponent = function (selector, all) { const result = [] if (/[>\s]/.test(selector)) { const location = this.__mpxProxy.options.mpxFileResource error('The selectComponent or selectAllComponents only supports the basic selector, the relation selector is not supported.', location) } else { const selectorGroups = parseSelector(selector) walkChildren(this, selectorGroups, this, result, all) } return all ? result : result[0] } Vue.prototype.selectAllComponents = function (selector) { return this.selectComponent(selector, true) } Vue.prototype.createSelectorQuery = function () { return createSelectorQuery().in(this) } Vue.prototype.createIntersectionObserver = function (options) { return createIntersectionObserver(this, options) } Vue.prototype.getPageId = function () { return this.__pageId } hackEffectScope() }