diff --git a/packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js b/packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js index 4d2328025e15ebc2185417f49c0474cc0f8cd618..e0510646277029cedb1992ea798cc34f4477ab02 100644 --- a/packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js +++ b/packages/vue-cli-plugin-uni/packages/mp-vue/dist/mp.runtime.esm.js @@ -991,7 +991,8 @@ function observe (value, asRootData) { !isServerRendering() && (Array.isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && - !value._isVue + !value._isVue && + !value.__v_isMPComponent ) { ob = new Observer(value); } @@ -5600,7 +5601,7 @@ function nextTick$1(vm, cb) { function clearInstance(key, value) { // 简易去除 Vue 和小程序组件实例 if (value) { - if (value._isVue || (value.$vm && value.$vm._isVue)) { + if (value._isVue || value.__v_isMPComponent) { return {} } } diff --git a/src/platforms/mp-alipay/runtime/index.js b/src/platforms/mp-alipay/runtime/index.js index 895b2857ad226d8cdf9079035eddaf5a266c907a..92ae71deaa4fdac371fcf9d52b4a6ab8decf329e 100644 --- a/src/platforms/mp-alipay/runtime/index.js +++ b/src/platforms/mp-alipay/runtime/index.js @@ -1,10 +1,11 @@ -import { handleProps } from './wrapper/util' +import { handleProps, markMPComponent } from './wrapper/util' const MPComponent = Component function initHook (name, options) { const oldHook = options[name] options[name] = function (...args) { + markMPComponent(this) const props = this.props if (props && props['data-com-type'] === 'wx') { handleProps(this) diff --git a/src/platforms/mp-alipay/runtime/wrapper/util.js b/src/platforms/mp-alipay/runtime/wrapper/util.js index 68ec31889a6ab744539d17556b56d45744132b19..f0f78e6543c34c9739213b7cef7ccd1c9f7adb1a 100644 --- a/src/platforms/mp-alipay/runtime/wrapper/util.js +++ b/src/platforms/mp-alipay/runtime/wrapper/util.js @@ -6,11 +6,14 @@ import { } from 'uni-shared' import { - handleLink as handleBaseLink + handleLink as handleBaseLink, + toSkip } from '../../../mp-weixin/runtime/wrapper/util' import deepEqual from './deep-equal' +export { markMPComponent } from '../../../mp-weixin/runtime/wrapper/util' + const customizeRE = /:/g const customize = cached((str) => { @@ -145,9 +148,9 @@ export function handleRef (ref) { const refName = ref.props['data-ref'] const refInForName = ref.props['data-ref-in-for'] if (refName) { - this.$vm.$refs[refName] = ref.$vm || ref + this.$vm.$refs[refName] = ref.$vm || toSkip(ref) } else if (refInForName) { - (this.$vm.$refs[refInForName] || (this.$vm.$refs[refInForName] = [])).push(ref.$vm || ref) + (this.$vm.$refs[refInForName] || (this.$vm.$refs[refInForName] = [])).push(ref.$vm || toSkip(ref)) } } diff --git a/src/platforms/mp-toutiao/runtime/wrapper/util.js b/src/platforms/mp-toutiao/runtime/wrapper/util.js index 6169f43131fc52ea5bef9f193e905540df5d43fa..aabc880d3a9971e703f2fbebbaddac950e0cf54e 100644 --- a/src/platforms/mp-toutiao/runtime/wrapper/util.js +++ b/src/platforms/mp-toutiao/runtime/wrapper/util.js @@ -1,6 +1,7 @@ import { findVmByVueId, - initRefs as initRefsBase + initRefs as initRefsBase, + toSkip } from '../../../mp-weixin/runtime/wrapper/util' export const mocks = ['__route__', '__webviewId__', '__nodeid__', '__nodeId__'] @@ -19,7 +20,7 @@ export function initRefs (vm) { mpInstance.selectAllComponents('.vue-ref', (components) => { components.forEach(component => { const ref = component.dataset.ref - vm.$refs[ref] = component.$vm || component + vm.$refs[ref] = component.$vm || toSkip(component) }) }) mpInstance.selectAllComponents('.vue-ref-in-for', (forComponents) => { @@ -28,7 +29,7 @@ export function initRefs (vm) { if (!vm.$refs[ref]) { vm.$refs[ref] = [] } - vm.$refs[ref].push(component.$vm || component) + vm.$refs[ref].push(component.$vm || toSkip(component)) }) }) } diff --git a/src/platforms/mp-weixin/runtime/index.js b/src/platforms/mp-weixin/runtime/index.js index 4012f0b42221f00a0cfdfedc7d1a3e4ee9af0055..8f23f8b34acf95c4a9287e230ec1204723aac307 100644 --- a/src/platforms/mp-weixin/runtime/index.js +++ b/src/platforms/mp-weixin/runtime/index.js @@ -2,6 +2,7 @@ import { cached, camelize } from 'uni-shared' +import { markMPComponent } from './wrapper/util' const MPPage = Page const MPComponent = Component @@ -41,13 +42,10 @@ function initHook (name, options, isComponent) { isComponent && options.lifetimes && options.lifetimes[name] && (options = options.lifetimes) } const oldHook = options[name] - if (!oldHook) { - options[name] = function () { - initTriggerEvent(this) - } - } else { - options[name] = function (...args) { - initTriggerEvent(this) + options[name] = function (...args) { + markMPComponent(this) + initTriggerEvent(this) + if (oldHook) { return oldHook.apply(this, args) } } diff --git a/src/platforms/mp-weixin/runtime/wrapper/util.js b/src/platforms/mp-weixin/runtime/wrapper/util.js index 877a1e45c84de7a525228eebbb34fb45eb465a81..25b3d4eefeffd6c6978e25b879e9ba938700701f 100644 --- a/src/platforms/mp-weixin/runtime/wrapper/util.js +++ b/src/platforms/mp-weixin/runtime/wrapper/util.js @@ -1,3 +1,7 @@ +import { + isObject +} from 'uni-shared' + export const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'] export function findVmByVueId (vm, vuePid) { @@ -35,7 +39,7 @@ function selectAllComponents (mpInstance, selector, $refs) { const components = mpInstance.selectAllComponents(selector) || [] components.forEach(component => { const ref = component.dataset.ref - $refs[ref] = component.$vm || component + $refs[ref] = component.$vm || toSkip(component) if (__PLATFORM__ === 'mp-weixin') { if (component.dataset.vueGeneric === 'scoped') { component.selectAllComponents('.scoped-ref').forEach(scopedComponent => { @@ -78,7 +82,7 @@ export function initRefs (vm) { if (!$refs[ref]) { $refs[ref] = [] } - $refs[ref].push(component.$vm || component) + $refs[ref].push(component.$vm || toSkip(component)) }) return syncRefs(refs, $refs) } @@ -102,4 +106,31 @@ export function handleLink (event) { } vueOptions.parent = parentVm -} +} + +export function markMPComponent (component) { + // 在 Vue 中标记为小程序组件 + const IS_MP = '__v_isMPComponent' + Object.defineProperty(component, IS_MP, { + configurable: true, + enumerable: false, + value: true + }) + return component +} + +export function toSkip (obj) { + const OB = '__ob__' + const SKIP = '__v_skip' + if (isObject(obj) && Object.isExtensible(obj)) { + // 避免被 @vue/composition-api 观测 + Object.defineProperty(obj, OB, { + configurable: true, + enumerable: false, + value: { + [SKIP]: true + } + }) + } + return obj +}