提交 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 { 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 作为插槽名称
const SLOT_DEFAULT_NAME = 'd';
......@@ -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) {
const properties = {};
if (!isBehavior) {
// 均不指定类型,避免微信小程序 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: '',
};
builtInProps.forEach((name) => {
properties[name] = {
type: null,
value: '',
};
});
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
......@@ -501,6 +499,22 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -815,7 +829,7 @@ const handleLink = (function () {
function createVueComponent(mpType, mpInstance, vueOptions, parent) {
return $createComponent({
type: vueOptions,
props: findComponentPropsData(mpInstance.props && mpInstance.props.uP) || {},
props: findPropsData(mpInstance.props, mpType === 'page'),
}, {
mpType,
mpInstance,
......
......@@ -9,7 +9,7 @@ import {
} from 'vue'
// @ts-ignore EMPTY_OBJ 不能从 @vue/shared 中引入,从 vue 中导入,保持一致
import { findComponentPropsData, EMPTY_OBJ, setTemplateRef } from 'vue'
import { EMPTY_OBJ, setTemplateRef } from 'vue'
import {
initMocks,
......@@ -18,6 +18,7 @@ import {
CreateComponentOptions,
updateComponentProps,
findRefValue,
findPropsData,
} from '@dcloudio/uni-mp-core'
import { handleLink as handleBaseLink } from '@dcloudio/uni-mp-weixin'
......@@ -265,8 +266,7 @@ export function createVueComponent(
return $createComponent(
{
type: vueOptions,
props:
findComponentPropsData(mpInstance.props && mpInstance.props.uP) || {},
props: findPropsData(mpInstance.props, mpType === 'page'),
},
{
mpType,
......
......@@ -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) {
const properties = {};
if (!isBehavior) {
{
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
properties.eO = {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
builtInProps.forEach((name) => {
properties[name] = {
type: null,
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
properties.uS = {
type: null,
......@@ -644,6 +634,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -814,6 +843,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -951,7 +981,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, isMiniProgramPage),
}, {
mpType: isMiniProgramPage ? 'page' : 'component',
mpInstance,
......
......@@ -11,6 +11,7 @@ export { initCreateApp, initCreateSubpackageApp } from './runtime/app'
export { initCreatePage } from './runtime/page'
export { initCreateComponent } from './runtime/component'
export { initCreatePluginApp } from './runtime/plugin'
export { findPropsData } from './runtime/componentProps'
export { initUni } from './api/index'
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'
// @ts-ignore
import { findComponentPropsData } from 'vue'
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) {
const properties: Component.PropertyOption = {}
if (!isBehavior) {
if (__PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-kuaishou') {
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
properties.eO = {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
builtInProps.forEach((name) => {
properties[name] = {
type: null,
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
properties.uS = {
type: null,
......@@ -70,3 +64,51 @@ export function initProps(mpComponentOptions: MPComponentOptions) {
}
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 {
CustomComponentInstanceProperty,
} from './component'
import { PAGE_HOOKS, initHooks, initUnknownHooks } from './componentHooks'
import { initPageProps } from './componentProps'
function parsePage(
vueOptions: ComponentOptions,
......@@ -23,6 +24,11 @@ function parsePage(
initLifetimes,
})
initPageProps(
miniProgramPageOptions,
(vueOptions.default || vueOptions).props
)
const methods =
miniProgramPageOptions.methods as WechatMiniprogram.Component.MethodOption
......
......@@ -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) {
const properties = {};
if (!isBehavior) {
{
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
properties.eO = {
// 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
builtInProps.forEach((name) => {
properties[name] = {
type: null,
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
properties.uS = {
type: null,
......@@ -639,6 +629,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -809,6 +838,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -889,7 +919,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, isMiniProgramPage),
}, {
mpType: isMiniProgramPage ? 'page' : 'component',
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) {
const properties = {};
if (!isBehavior) {
// 均不指定类型,避免微信小程序 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: '',
};
builtInProps.forEach((name) => {
properties[name] = {
type: null,
value: '',
};
});
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
......@@ -604,6 +602,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -774,6 +811,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -940,7 +978,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
}
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, mpType === 'page'),
}, {
mpType,
mpInstance,
......
......@@ -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) {
const properties = {};
if (!isBehavior) {
// 均不指定类型,避免微信小程序 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: '',
};
builtInProps.forEach((name) => {
properties[name] = {
type: null,
value: '',
};
});
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
......@@ -590,6 +588,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -763,6 +800,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -845,7 +883,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, isMiniProgramPage),
}, {
mpType: isMiniProgramPage ? 'page' : 'component',
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) {
const properties = {};
if (!isBehavior) {
// 均不指定类型,避免微信小程序 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: '',
};
builtInProps.forEach((name) => {
properties[name] = {
type: null,
value: '',
};
});
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
......@@ -604,6 +602,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -774,6 +811,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -945,7 +983,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
}
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, mpType === 'page'),
}, {
mpType,
mpInstance,
......
import { ComponentInternalInstance, ComponentPublicInstance } from 'vue'
// @ts-ignore
import { findComponentPropsData, pruneComponentPropsCache } from 'vue'
import { pruneComponentPropsCache } from 'vue'
import {
RelationOptions,
MPComponentInstance,
CreateComponentOptions,
CreateLifetimesOptions,
initSetRef,
findPropsData,
} from '@dcloudio/uni-mp-core'
import {
......@@ -49,7 +50,7 @@ export function initLifetimes({
this.$vm = $createComponent(
{
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, mpType === 'page'),
},
{
mpType,
......
......@@ -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) {
const properties = {};
if (!isBehavior) {
// 均不指定类型,避免微信小程序 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: '',
};
builtInProps.forEach((name) => {
properties[name] = {
type: null,
value: '',
};
});
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
......@@ -462,6 +460,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -635,6 +672,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -719,7 +757,7 @@ function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
const isMiniProgramPage = isPage(mpInstance);
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, isMiniProgramPage),
}, {
mpType: isMiniProgramPage ? 'page' : 'component',
mpInstance,
......
import { ComponentInternalInstance, ComponentPublicInstance } from 'vue'
// @ts-ignore
import { findComponentPropsData, pruneComponentPropsCache } from 'vue'
import { pruneComponentPropsCache } from 'vue'
import {
RelationOptions,
MPComponentInstance,
CreateComponentOptions,
CreateLifetimesOptions,
findPropsData,
} from '@dcloudio/uni-mp-core'
import {
......@@ -49,7 +50,7 @@ export function initLifetimes({
this.$vm = $createComponent(
{
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, isMiniProgramPage),
},
{
mpType: isMiniProgramPage ? 'page' : 'component',
......
......@@ -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) {
const properties = {};
if (!isBehavior) {
// 均不指定类型,避免微信小程序 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: '',
};
builtInProps.forEach((name) => {
properties[name] = {
type: null,
value: '',
};
});
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
properties.uS = {
type: null,
......@@ -582,6 +580,45 @@ function initProps(mpComponentOptions) {
mpComponentOptions.properties = {};
}
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(_) {
......@@ -752,6 +789,7 @@ function parsePage(vueOptions, parseOptions) {
handleLink,
initLifetimes,
});
initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props);
const methods = miniProgramPageOptions.methods;
methods.onLoad = function (query) {
this.options = query;
......@@ -914,7 +952,7 @@ function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
}
this.$vm = $createComponent({
type: vueOptions,
props: findComponentPropsData(properties.uP) || {},
props: findPropsData(properties, mpType === 'page'),
}, {
mpType,
mpInstance,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册