提交 a56313ae 编写于 作者: fxy060608's avatar fxy060608

fix(mp-weixin): Page with props (#3079)

上级 8e35ab62
import { isPlainObject, hasOwn, isArray, capitalize, isFunction, extend, isString, camelize } from '@vue/shared'; import { isPlainObject, hasOwn, isArray, capitalize, isFunction, extend, isString, camelize } from '@vue/shared';
import { injectHook, ref, getExposeProxy, toRaw, findComponentPropsData, updateProps, invalidateJob, EMPTY_OBJ, isRef, setTemplateRef, pruneComponentPropsCache } from 'vue'; import { injectHook, ref, getExposeProxy, findComponentPropsData, toRaw, updateProps, invalidateJob, EMPTY_OBJ, isRef, setTemplateRef, pruneComponentPropsCache } from 'vue';
// quickapp-webview 不能使用 default 作为插槽名称 // quickapp-webview 不能使用 default 作为插槽名称
const SLOT_DEFAULT_NAME = 'd'; const SLOT_DEFAULT_NAME = 'd';
...@@ -444,35 +444,33 @@ function findVmByVueId(instance, vuePid) { ...@@ -444,35 +444,33 @@ function findVmByVueId(instance, vuePid) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref builtInProps.forEach((name) => {
properties.uR = { properties[name] = {
type: null, type: null,
value: '', value: '',
}; };
// 组件 ref-in-for });
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -501,6 +499,22 @@ function initProps(mpComponentOptions) { ...@@ -501,6 +499,22 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -815,7 +829,7 @@ const handleLink = (function () { ...@@ -815,7 +829,7 @@ const handleLink = (function () {
function createVueComponent(mpType, mpInstance, vueOptions, parent) { function createVueComponent(mpType, mpInstance, vueOptions, parent) {
return $createComponent({ return $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(mpInstance.props && mpInstance.props.uP) || {}, props: findPropsData(mpInstance.props, mpType === 'page'),
}, { }, {
mpType, mpType,
mpInstance, mpInstance,
......
...@@ -9,7 +9,7 @@ import { ...@@ -9,7 +9,7 @@ import {
} from 'vue' } from 'vue'
// @ts-ignore EMPTY_OBJ 不能从 @vue/shared 中引入,从 vue 中导入,保持一致 // @ts-ignore EMPTY_OBJ 不能从 @vue/shared 中引入,从 vue 中导入,保持一致
import { findComponentPropsData, EMPTY_OBJ, setTemplateRef } from 'vue' import { EMPTY_OBJ, setTemplateRef } from 'vue'
import { import {
initMocks, initMocks,
...@@ -18,6 +18,7 @@ import { ...@@ -18,6 +18,7 @@ import {
CreateComponentOptions, CreateComponentOptions,
updateComponentProps, updateComponentProps,
findRefValue, findRefValue,
findPropsData,
} from '@dcloudio/uni-mp-core' } from '@dcloudio/uni-mp-core'
import { handleLink as handleBaseLink } from '@dcloudio/uni-mp-weixin' import { handleLink as handleBaseLink } from '@dcloudio/uni-mp-weixin'
...@@ -265,8 +266,7 @@ export function createVueComponent( ...@@ -265,8 +266,7 @@ export function createVueComponent(
return $createComponent( return $createComponent(
{ {
type: vueOptions, type: vueOptions,
props: props: findPropsData(mpInstance.props, mpType === 'page'),
findComponentPropsData(mpInstance.props && mpInstance.props.uP) || {},
}, },
{ {
mpType, mpType,
......
...@@ -579,43 +579,33 @@ function initSetRef(mpInstance) { ...@@ -579,43 +579,33 @@ function initSetRef(mpInstance) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
{ // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息 builtInProps.forEach((name) => {
// event-opts properties[name] = {
properties.eO = {
type: null, type: null,
value: '', value: '',
}; };
} });
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref
properties.uR = {
type: null,
value: '',
};
// 组件 ref-in-for
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -644,6 +634,45 @@ function initProps(mpComponentOptions) { ...@@ -644,6 +634,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -814,6 +843,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -814,6 +843,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -951,7 +981,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -951,7 +981,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance); const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, isMiniProgramPage),
}, { }, {
mpType: isMiniProgramPage ? 'page' : 'component', mpType: isMiniProgramPage ? 'page' : 'component',
mpInstance, mpInstance,
......
...@@ -11,6 +11,7 @@ export { initCreateApp, initCreateSubpackageApp } from './runtime/app' ...@@ -11,6 +11,7 @@ export { initCreateApp, initCreateSubpackageApp } from './runtime/app'
export { initCreatePage } from './runtime/page' export { initCreatePage } from './runtime/page'
export { initCreateComponent } from './runtime/component' export { initCreateComponent } from './runtime/component'
export { initCreatePluginApp } from './runtime/plugin' export { initCreatePluginApp } from './runtime/plugin'
export { findPropsData } from './runtime/componentProps'
export { initUni } from './api/index' export { initUni } from './api/index'
export { initGetProvider } from './api/shims' export { initGetProvider } from './api/shims'
......
import { onBeforeMount, ComponentPropsOptions } from 'vue'
import { isArray, isPlainObject, isFunction } from '@vue/shared'
import { MPComponentOptions, MPComponentInstance } from './component'
import Component = WechatMiniprogram.Component
const PROP_TYPES = [String, Number, Boolean, Object, Array, null]
function createObserver(name: string) {
return function observer(this: MPComponentInstance, newVal: unknown) {
const { $vm } = this
if ($vm) {
// 为了触发其他非 render watcher
const instance = $vm.$
// 飞书小程序初始化太慢,导致 observer 触发时,vue 组件的 created 可能还没触发,此时开发者可能已经定义了 watch
// 但因为 created 还没触发,导致部分组件出错,如 uni-collapse,在 created 中初始化了 this.children
// 自定义 watch 中使用了 this.children
if (__PLATFORM__ === 'mp-lark') {
if (instance.isMounted) {
instance.props[name] = newVal
} else {
onBeforeMount(() => (instance.props[name] = newVal), instance)
}
} else {
instance.props[name] = newVal
}
}
}
}
function parsePropType(type: unknown, defaultValue: unknown) {
// [String]=>String
if (isArray(type) && type.length === 1) {
return type[0]
}
if (__PLATFORM__ === 'mp-baidu') {
if (
// [String,Boolean]=>Boolean
defaultValue === false &&
isArray(type) &&
type.length === 2 &&
type.indexOf(String) !== -1 &&
type.indexOf(Boolean) !== -1
) {
return Boolean
}
}
return type
}
function normalizePropType(type: unknown, defaultValue: unknown) {
if (__PLATFORM__ === 'mp-weixin') {
// 不再生成具体的 type 类型,因为微信首次初始化,值为 undefined 时,会告警:property received type-uncompatible value
return null
}
const res = parsePropType(type, defaultValue)
return PROP_TYPES.indexOf(res) !== -1 ? res : null
}
function initDefaultProps(isBehavior: boolean = false) {
const properties: Component.PropertyOption = {}
if (!isBehavior) {
if (__PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-kuaishou') {
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
properties.eO = {
type: null,
value: '',
}
}
// 组件 ref
properties.uR = {
type: null,
value: '',
}
// 组件 ref-in-for
properties.uRIF = {
type: null,
value: '',
}
// 组件 id
properties.uI = {
type: null, // 均不指定类型,避免 property received type-uncompatible value 警告
value: '',
}
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
value: [],
observer: function (this: MPComponentInstance, newVal) {
const $slots = Object.create(null)
newVal &&
newVal.forEach((slotName: string) => {
$slots[slotName] = true
})
this.setData({
$slots,
})
},
}
}
return properties
}
function createProperty(key: string, prop: any) {
if (__PLATFORM__ === 'mp-alipay') {
return prop
}
prop.observer = createObserver(key)
return prop
}
/**
*
* @param mpComponentOptions
* @param rawProps
* @param isBehavior
*/
export function initProps(
mpComponentOptions: MPComponentOptions,
rawProps: ComponentPropsOptions | null,
isBehavior: boolean = false
) {
const properties = initDefaultProps(isBehavior)
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = createProperty(key, {
type: null,
})
})
} else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
const opts = rawProps[key]
if (isPlainObject(opts)) {
// title:{type:String,default:''}
let value = (opts as any).default
if (isFunction(value)) {
value = value()
}
const type = (opts as any).type as any
;(opts as any).type = normalizePropType(type, value)
properties[key] = createProperty(key, {
type: (opts as any).type,
value,
})
} else {
// content:String
properties[key] = createProperty(key, {
type: normalizePropType(opts, null),
})
}
})
}
mpComponentOptions.properties = properties
}
import { extend } from '@vue/shared' import { ComponentPropsOptions } from '@vue/runtime-core'
import { extend, isArray, isPlainObject } from '@vue/shared'
import type { MPComponentOptions, MPComponentInstance } from './component' import type { MPComponentOptions, MPComponentInstance } from './component'
// @ts-ignore
import { findComponentPropsData } from 'vue'
import Component = WechatMiniprogram.Component import Component = WechatMiniprogram.Component
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
]
function initDefaultProps(isBehavior: boolean = false) { function initDefaultProps(isBehavior: boolean = false) {
const properties: Component.PropertyOption = {} const properties: Component.PropertyOption = {}
if (!isBehavior) { if (!isBehavior) {
if (__PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-kuaishou') { // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息 builtInProps.forEach((name) => {
// event-opts properties[name] = {
properties.eO = {
type: null, type: null,
value: '', value: '',
} }
} })
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref
properties.uR = {
type: null,
value: '',
}
// 组件 ref-in-for
properties.uRIF = {
type: null,
value: '',
}
// 组件 id
properties.uI = {
type: null,
value: '',
}
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
}
// 组件 props
properties.uP = {
type: null,
value: '',
}
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -70,3 +64,51 @@ export function initProps(mpComponentOptions: MPComponentOptions) { ...@@ -70,3 +64,51 @@ export function initProps(mpComponentOptions: MPComponentOptions) {
} }
extend(mpComponentOptions.properties, initDefaultProps()) extend(mpComponentOptions.properties, initDefaultProps())
} }
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
export function initPageProps(
{ properties }: MPComponentOptions,
rawProps: ComponentPropsOptions | null
) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties![key] = {
type: String,
value: '',
}
})
} else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties![key] = {
type: String,
value: '',
}
})
}
}
export function findPropsData(
properties: Record<string, any>,
isPage: boolean
) {
return (
(isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {}
)
}
function findPagePropsData(properties: Record<string, any>) {
const propsData: Record<string, any> = {}
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = (properties as Record<string, any>)[name]
}
})
}
return propsData
}
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
CustomComponentInstanceProperty, CustomComponentInstanceProperty,
} from './component' } from './component'
import { PAGE_HOOKS, initHooks, initUnknownHooks } from './componentHooks' import { PAGE_HOOKS, initHooks, initUnknownHooks } from './componentHooks'
import { initPageProps } from './componentProps'
function parsePage( function parsePage(
vueOptions: ComponentOptions, vueOptions: ComponentOptions,
...@@ -23,6 +24,11 @@ function parsePage( ...@@ -23,6 +24,11 @@ function parsePage(
initLifetimes, initLifetimes,
}) })
initPageProps(
miniProgramPageOptions,
(vueOptions.default || vueOptions).props
)
const methods = const methods =
miniProgramPageOptions.methods as WechatMiniprogram.Component.MethodOption miniProgramPageOptions.methods as WechatMiniprogram.Component.MethodOption
......
...@@ -574,43 +574,33 @@ function initSetRef(mpInstance) { ...@@ -574,43 +574,33 @@ function initSetRef(mpInstance) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
{ // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息 builtInProps.forEach((name) => {
// event-opts properties[name] = {
properties.eO = {
type: null, type: null,
value: '', value: '',
}; };
} });
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref
properties.uR = {
type: null,
value: '',
};
// 组件 ref-in-for
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -639,6 +629,45 @@ function initProps(mpComponentOptions) { ...@@ -639,6 +629,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -809,6 +838,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -809,6 +838,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -889,7 +919,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -889,7 +919,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance); const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, isMiniProgramPage),
}, { }, {
mpType: isMiniProgramPage ? 'page' : 'component', mpType: isMiniProgramPage ? 'page' : 'component',
mpInstance, mpInstance,
......
...@@ -547,35 +547,33 @@ function initSetRef(mpInstance) { ...@@ -547,35 +547,33 @@ function initSetRef(mpInstance) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref builtInProps.forEach((name) => {
properties.uR = { properties[name] = {
type: null, type: null,
value: '', value: '',
}; };
// 组件 ref-in-for });
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -604,6 +602,45 @@ function initProps(mpComponentOptions) { ...@@ -604,6 +602,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -774,6 +811,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -774,6 +811,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -940,7 +978,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -940,7 +978,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
} }
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, mpType === 'page'),
}, { }, {
mpType, mpType,
mpInstance, mpInstance,
......
...@@ -533,35 +533,33 @@ function findVmByVueId(instance, vuePid) { ...@@ -533,35 +533,33 @@ function findVmByVueId(instance, vuePid) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref builtInProps.forEach((name) => {
properties.uR = { properties[name] = {
type: null, type: null,
value: '', value: '',
}; };
// 组件 ref-in-for });
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -590,6 +588,45 @@ function initProps(mpComponentOptions) { ...@@ -590,6 +588,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -763,6 +800,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -763,6 +800,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -845,7 +883,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -845,7 +883,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance); const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, isMiniProgramPage),
}, { }, {
mpType: isMiniProgramPage ? 'page' : 'component', mpType: isMiniProgramPage ? 'page' : 'component',
mpInstance, mpInstance,
......
...@@ -547,35 +547,33 @@ function initSetRef(mpInstance) { ...@@ -547,35 +547,33 @@ function initSetRef(mpInstance) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref builtInProps.forEach((name) => {
properties.uR = { properties[name] = {
type: null, type: null,
value: '', value: '',
}; };
// 组件 ref-in-for });
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -604,6 +602,45 @@ function initProps(mpComponentOptions) { ...@@ -604,6 +602,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -774,6 +811,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -774,6 +811,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -945,7 +983,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -945,7 +983,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
} }
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, mpType === 'page'),
}, { }, {
mpType, mpType,
mpInstance, mpInstance,
......
import { ComponentInternalInstance, ComponentPublicInstance } from 'vue' import { ComponentInternalInstance, ComponentPublicInstance } from 'vue'
// @ts-ignore // @ts-ignore
import { findComponentPropsData, pruneComponentPropsCache } from 'vue' import { pruneComponentPropsCache } from 'vue'
import { import {
RelationOptions, RelationOptions,
MPComponentInstance, MPComponentInstance,
CreateComponentOptions, CreateComponentOptions,
CreateLifetimesOptions, CreateLifetimesOptions,
initSetRef, initSetRef,
findPropsData,
} from '@dcloudio/uni-mp-core' } from '@dcloudio/uni-mp-core'
import { import {
...@@ -49,7 +50,7 @@ export function initLifetimes({ ...@@ -49,7 +50,7 @@ export function initLifetimes({
this.$vm = $createComponent( this.$vm = $createComponent(
{ {
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, mpType === 'page'),
}, },
{ {
mpType, mpType,
......
...@@ -405,35 +405,33 @@ function findVmByVueId(instance, vuePid) { ...@@ -405,35 +405,33 @@ function findVmByVueId(instance, vuePid) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref builtInProps.forEach((name) => {
properties.uR = { properties[name] = {
type: null, type: null,
value: '', value: '',
}; };
// 组件 ref-in-for });
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -462,6 +460,45 @@ function initProps(mpComponentOptions) { ...@@ -462,6 +460,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -635,6 +672,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -635,6 +672,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -719,7 +757,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -719,7 +757,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance); const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, isMiniProgramPage),
}, { }, {
mpType: isMiniProgramPage ? 'page' : 'component', mpType: isMiniProgramPage ? 'page' : 'component',
mpInstance, mpInstance,
......
import { ComponentInternalInstance, ComponentPublicInstance } from 'vue' import { ComponentInternalInstance, ComponentPublicInstance } from 'vue'
// @ts-ignore // @ts-ignore
import { findComponentPropsData, pruneComponentPropsCache } from 'vue' import { pruneComponentPropsCache } from 'vue'
import { import {
RelationOptions, RelationOptions,
MPComponentInstance, MPComponentInstance,
CreateComponentOptions, CreateComponentOptions,
CreateLifetimesOptions, CreateLifetimesOptions,
findPropsData,
} from '@dcloudio/uni-mp-core' } from '@dcloudio/uni-mp-core'
import { import {
...@@ -49,7 +50,7 @@ export function initLifetimes({ ...@@ -49,7 +50,7 @@ export function initLifetimes({
this.$vm = $createComponent( this.$vm = $createComponent(
{ {
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, isMiniProgramPage),
}, },
{ {
mpType: isMiniProgramPage ? 'page' : 'component', mpType: isMiniProgramPage ? 'page' : 'component',
......
...@@ -525,35 +525,33 @@ function initSetRef(mpInstance) { ...@@ -525,35 +525,33 @@ function initSetRef(mpInstance) {
} }
} }
const builtInProps = [
// 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
'eO',
// 组件 ref
'uR',
// 组件 ref-in-for
'uRIF',
// 组件 id
'uI',
// 组件类型 m: 小程序组件
'uT',
// 组件 props
'uP',
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
'uS',
];
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
// 组件 ref builtInProps.forEach((name) => {
properties.uR = { properties[name] = {
type: null, type: null,
value: '', value: '',
}; };
// 组件 ref-in-for });
properties.uRIF = {
type: null,
value: '',
};
// 组件 id
properties.uI = {
type: null,
value: '',
};
// 组件类型 m: 小程序组件
properties.uT = {
type: null,
value: '',
};
// 组件 props
properties.uP = {
type: null,
value: '',
};
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = { properties.uS = {
type: null, type: null,
...@@ -582,6 +580,45 @@ function initProps(mpComponentOptions) { ...@@ -582,6 +580,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {}; mpComponentOptions.properties = {};
} }
extend(mpComponentOptions.properties, initDefaultProps()); extend(mpComponentOptions.properties, initDefaultProps());
}
/**
* 初始化页面 props,方便接收页面参数,类型均为String,默认值均为''
* @param param
* @param rawProps
*/
function initPageProps({ properties }, rawProps) {
if (isArray(rawProps)) {
rawProps.forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
else if (isPlainObject(rawProps)) {
Object.keys(rawProps).forEach((key) => {
properties[key] = {
type: String,
value: '',
};
});
}
}
function findPropsData(properties, isPage) {
return ((isPage
? findPagePropsData(properties)
: findComponentPropsData(properties.uP)) || {});
}
function findPagePropsData(properties) {
const propsData = {};
if (isPlainObject(properties)) {
Object.keys(properties).forEach((name) => {
if (builtInProps.indexOf(name) === -1) {
propsData[name] = properties[name];
}
});
}
return propsData;
} }
function initData(_) { function initData(_) {
...@@ -752,6 +789,7 @@ function parsePage(vueOptions, parseOptions) { ...@@ -752,6 +789,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink, handleLink,
initLifetimes, initLifetimes,
}); });
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods; const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) { methods.onLoad = function (query) {
this.options = query; this.options = query;
...@@ -914,7 +952,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) { ...@@ -914,7 +952,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
} }
this.$vm = $createComponent({ this.$vm = $createComponent({
type: vueOptions, type: vueOptions,
props: findComponentPropsData(properties.uP) || {}, props: findPropsData(properties, mpType === 'page'),
}, { }, {
mpType, mpType,
mpInstance, mpInstance,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册