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

wip(mp): mp-baidu

上级 7c0ef648
因为 它太大了无法显示 source diff 。你可以改为 查看blob
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
...@@ -4,28 +4,25 @@ const WXS_RE = /vue&type=wxs/ ...@@ -4,28 +4,25 @@ const WXS_RE = /vue&type=wxs/
export function isWxs(id: string) { export function isWxs(id: string) {
return WXS_RE.test(id) return WXS_RE.test(id)
} }
const SJS_RE = /vue&type=sjs/
export function isSjs(id: string) {
return SJS_RE.test(id)
}
const RENDERJS_RE = /vue&type=renderjs/ const RENDERJS_RE = /vue&type=renderjs/
export function isRenderjs(id: string) { export function isRenderjs(id: string) {
return RENDERJS_RE.test(id) return RENDERJS_RE.test(id)
} }
type FilterType = 'wxs' | 'renderjs' | 'sjs'
export function parseRenderjs(id: string) { export function parseRenderjs(id: string) {
if (isWxs(id)) { if (isWxs(id) || isRenderjs(id) || isSjs(id)) {
const { query, filename } = parseVueRequest(id) const { query, filename } = parseVueRequest(id)
return { return {
type: 'wxs', type: query.type as FilterType,
name: (query as any).name as string, name: (query as any).name as string,
filename, filename,
} as const }
}
if (isRenderjs(id)) {
const { query, filename } = parseVueRequest(id)
return {
type: 'renderjs',
name: (query as any).name as string,
filename,
} as const
} }
return { return {
type: '', type: '',
...@@ -34,7 +31,7 @@ export function parseRenderjs(id: string) { ...@@ -34,7 +31,7 @@ export function parseRenderjs(id: string) {
} as const } as const
} }
export function missingModuleName(type: 'wxs' | 'renderjs', code: string) { export function missingModuleName(type: FilterType, code: string) {
return `<script module="missing module name" lang="${type}"> return `<script module="missing module name" lang="${type}">
${code} ${code}
</script>` </script>`
......
...@@ -25,7 +25,7 @@ export interface MiniProgramCompilerOptions { ...@@ -25,7 +25,7 @@ export interface MiniProgramCompilerOptions {
} }
export interface MiniProgramFilterOptions { export interface MiniProgramFilterOptions {
id: string id: string
type: 'wxs' type: string
name: string name: string
src?: string src?: string
code: string code: string
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
...@@ -5023,6 +5023,11 @@ function decodeEntities(htmlString) { ...@@ -5023,6 +5023,11 @@ function decodeEntities(htmlString) {
return wrap.innerText || wrap.textContent; return wrap.innerText || wrap.textContent;
}); });
} }
function normlizeValue(tagName, name, value) {
if (tagName === "img" && name === "src")
return getRealPath(value);
return value;
}
function parseNodes(nodes, parentNode, scopeId) { function parseNodes(nodes, parentNode, scopeId) {
nodes.forEach(function(node) { nodes.forEach(function(node) {
if (!shared.isPlainObject(node)) { if (!shared.isPlainObject(node)) {
...@@ -5054,7 +5059,7 @@ function parseNodes(nodes, parentNode, scopeId) { ...@@ -5054,7 +5059,7 @@ function parseNodes(nodes, parentNode, scopeId) {
break; break;
default: default:
if (tagAttrs.indexOf(name) !== -1) { if (tagAttrs.indexOf(name) !== -1) {
elem.setAttribute(name, value); elem.setAttribute(name, normlizeValue(tagName, name, value));
} }
} }
}); });
......
...@@ -11467,6 +11467,11 @@ function decodeEntities(htmlString) { ...@@ -11467,6 +11467,11 @@ function decodeEntities(htmlString) {
return wrap.innerText || wrap.textContent; return wrap.innerText || wrap.textContent;
}); });
} }
function normlizeValue(tagName, name, value) {
if (tagName === "img" && name === "src")
return getRealPath(value);
return value;
}
function parseNodes(nodes, parentNode, scopeId) { function parseNodes(nodes, parentNode, scopeId) {
nodes.forEach(function(node) { nodes.forEach(function(node) {
if (!isPlainObject(node)) { if (!isPlainObject(node)) {
...@@ -11498,7 +11503,7 @@ function parseNodes(nodes, parentNode, scopeId) { ...@@ -11498,7 +11503,7 @@ function parseNodes(nodes, parentNode, scopeId) {
break; break;
default: default:
if (tagAttrs.indexOf(name) !== -1) { if (tagAttrs.indexOf(name) !== -1) {
elem.setAttribute(name, value); elem.setAttribute(name, normlizeValue(tagName, name, value));
} }
} }
}); });
......
...@@ -131,8 +131,10 @@ const MP_METHODS = [ ...@@ -131,8 +131,10 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
scope.triggerEvent(event, detail);
} }
{ {
const vnode = this.$.vnode; const vnode = this.$.vnode;
......
...@@ -2,6 +2,7 @@ import { isCustomElement, isNativeTag } from '@dcloudio/uni-shared' ...@@ -2,6 +2,7 @@ import { isCustomElement, isNativeTag } from '@dcloudio/uni-shared'
import { compile, CompilerOptions } from '@dcloudio/uni-mp-compiler' import { compile, CompilerOptions } from '@dcloudio/uni-mp-compiler'
import { transformFor } from '../src/plugin/transforms/vFor' import { transformFor } from '../src/plugin/transforms/vFor'
import { transformOn } from '../src/plugin/transforms/vOn' import { transformOn } from '../src/plugin/transforms/vOn'
import { transformModel } from '../src/plugin/transforms/vModel'
export function assert( export function assert(
template: string, template: string,
...@@ -22,6 +23,7 @@ export function assert( ...@@ -22,6 +23,7 @@ export function assert(
nodeTransforms: [transformFor], nodeTransforms: [transformFor],
directiveTransforms: { directiveTransforms: {
on: transformOn, on: transformOn,
model: transformModel,
}, },
miniProgram: { miniProgram: {
slot: { slot: {
......
import { assert } from './testUtils'
describe('mp-baidu: transform v-model', () => {
test(`component v-model`, () => {
assert(
`<Comp v-model="model" />`,
`<comp v-i="2a9ec0b0-0" eO="{{a}}" modelValue="{{b}}" bindupdateModelValue="__e"/>`,
`(_ctx, _cache) => {
return { a: { 'updateModelValue': _o($event => _ctx.model = $event) }, b: _ctx.model }
}`
)
})
test(`component v-model with cache`, () => {
assert(
`<Comp v-model="model" />`,
`<comp v-i="2a9ec0b0-0" eO="{{a}}" modelValue="{{b}}" bindupdateModelValue="__e"/>`,
`(_ctx, _cache) => {
return { a: { 'updateModelValue': _o($event => _ctx.model = $event) }, b: _ctx.model }
}`,
{
cacheHandlers: true,
}
)
})
test(`input,textarea v-model`, () => {
assert(
`<input v-model="model" />`,
`<input value="{{a}}" bindinput="{{b}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.model, b: _o($event => _ctx.model = $event.detail.value) }
}`
)
assert(
`<textarea v-model="model" />`,
`<textarea value="{{a}}" bindinput="{{b}}"/>`,
`(_ctx, _cache) => {
return { a: _ctx.model, b: _o($event => _ctx.model = $event.detail.value) }
}`
)
})
test(`input v-model + v-on`, () => {
assert(
`<input @input="input" v-model="model" />`,
`<input bindinput="{{a}}" value="{{b}}"/>`,
`(_ctx, _cache) => {
return { a: _o([$event => _ctx.model = $event.detail.value, _ctx.input]), b: _ctx.model }
}`
)
})
})
...@@ -14,7 +14,7 @@ describe('mp-baidu: transform v-on', () => { ...@@ -14,7 +14,7 @@ describe('mp-baidu: transform v-on', () => {
test(`custom event`, () => { test(`custom event`, () => {
assert( assert(
`<custom @click="click"/>`, `<custom @click="click"/>`,
`<custom bindclick="__e" v-i="2a9ec0b0-0" data-e-o="{{a}}"/>`, `<custom bindclick="__e" v-i="2a9ec0b0-0" eO="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: { 'click': _o(_ctx.click) } } return { a: { 'click': _o(_ctx.click) } }
}` }`
...@@ -23,7 +23,7 @@ describe('mp-baidu: transform v-on', () => { ...@@ -23,7 +23,7 @@ describe('mp-baidu: transform v-on', () => {
test(`multi custom event`, () => { test(`multi custom event`, () => {
assert( assert(
`<custom @unmount="unmount" @custom-mount="mount();created();"/>`, `<custom @unmount="unmount" @custom-mount="mount();created();"/>`,
`<custom bindunmount="__e" bind:custom-mount="__e" v-i="2a9ec0b0-0" data-e-o="{{a}}"/>`, `<custom bindunmount="__e" bind:custom-mount="__e" v-i="2a9ec0b0-0" eO="{{a}}"/>`,
`(_ctx, _cache) => { `(_ctx, _cache) => {
return { a: { 'custom-mount': _o($event => { _ctx.mount(); _ctx.created(); }), 'unmount': _o(_ctx.unmount) } } return { a: { 'custom-mount': _o($event => { _ctx.mount(); _ctx.created(); }), 'unmount': _o(_ctx.unmount) } }
}` }`
......
...@@ -68,20 +68,25 @@ const transformOn = (dir, node, context, augmentor) => { ...@@ -68,20 +68,25 @@ const transformOn = (dir, node, context, augmentor) => {
!uniMpCompiler.isUserComponent(node, context)) { !uniMpCompiler.isUserComponent(node, context)) {
return res; return res;
} }
// data-event-opts
const opts = compilerCore.findProp(node, ATTR_DATA_EVENT_OPTS, true);
const value = res.props[0].value; const value = res.props[0].value;
res.props[0].value = compilerCore.createSimpleExpression('__e', true); res.props[0].value = createCustomEventExpr();
addEventOpts(arg.content, value, node);
return res;
};
function createCustomEventExpr() {
return compilerCore.createSimpleExpression('__e', true);
}
function addEventOpts(event, value, node) {
const opts = compilerCore.findProp(node, ATTR_DATA_EVENT_OPTS, true);
if (!opts) { if (!opts) {
node.props.push(createDataEventOptsProp(arg.content, value)); node.props.push(createDataEventOptsProp(event, value));
} }
else { else {
const children = opts.exp.children; const children = opts.exp.children;
children.splice(children.length - 2, 0, createDataEventOptsProperty(arg.content, value)); children.splice(children.length - 2, 0, createDataEventOptsProperty(event, value));
} }
return res; }
}; const ATTR_DATA_EVENT_OPTS = 'eO';
const ATTR_DATA_EVENT_OPTS = 'data-e-o';
function createDataEventOptsProperty(event, exp) { function createDataEventOptsProperty(event, exp) {
return compilerCore.createCompoundExpression([`'${event}'`, ': ', exp, ',']); return compilerCore.createCompoundExpression([`'${event}'`, ': ', exp, ',']);
} }
...@@ -117,6 +122,26 @@ function isCustomEvent(name) { ...@@ -117,6 +122,26 @@ function isCustomEvent(name) {
return !builtInEvents.includes(name); return !builtInEvents.includes(name);
} }
/**
* 百度小程序的自定义组件,不支持动态事件绑定,故 v-model 也需要调整
* @param dir
* @param node
* @param context
* @param augmentor
* @returns
*/
const transformModel = (dir, node, context, augmentor) => {
const res = uniMpCompiler.transformModel(dir, node, context, augmentor);
const props = res.props;
if (props.length < 2 || !uniMpCompiler.isUserComponent(node, context)) {
return res;
}
const { arg, exp } = props[1];
addEventOpts(arg.content, exp, node);
props[1].exp = createCustomEventExpr();
return res;
};
const uniMiniProgramBaiduPlugin = { const uniMiniProgramBaiduPlugin = {
name: 'vite:uni-mp-baidu', name: 'vite:uni-mp-baidu',
config() { config() {
...@@ -154,7 +179,7 @@ const options = { ...@@ -154,7 +179,7 @@ const options = {
}, },
template: { template: {
filter: { filter: {
extname: '.swan', extname: '.sjs',
lang: 'sjs', lang: 'sjs',
generate(filter, filename) { generate(filter, filename) {
if (filename) { if (filename) {
...@@ -174,6 +199,7 @@ ${filter.code} ...@@ -174,6 +199,7 @@ ${filter.code}
nodeTransforms: [transformFor], nodeTransforms: [transformFor],
directiveTransforms: { directiveTransforms: {
on: transformOn, on: transformOn,
model: transformModel,
}, },
}, },
}, },
......
...@@ -129,8 +129,13 @@ const MP_METHODS = [ ...@@ -129,8 +129,13 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
{
detail.__ins__ = scope;
}
scope.triggerEvent(event, detail);
} }
return oldEmit.apply(this, [event, ...args]); return oldEmit.apply(this, [event, ...args]);
}; };
...@@ -433,6 +438,14 @@ function createObserver(name) { ...@@ -433,6 +438,14 @@ function createObserver(name) {
function initDefaultProps(isBehavior = false) { function initDefaultProps(isBehavior = false) {
const properties = {}; const properties = {};
if (!isBehavior) { if (!isBehavior) {
{
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
properties.eO = {
type: null,
value: '',
};
}
properties.vI = { properties.vI = {
type: null, type: null,
value: '', value: '',
...@@ -693,6 +706,9 @@ Page = function (options) { ...@@ -693,6 +706,9 @@ Page = function (options) {
initHook(ON_LOAD, options); initHook(ON_LOAD, options);
return MPPage(options); return MPPage(options);
}; };
{
Page.after = MPPage.after;
}
Component = function (options) { Component = function (options) {
initHook('created', options); initHook('created', options);
return MPComponent(options); return MPComponent(options);
...@@ -871,11 +887,12 @@ function parse$1(componentOptions) { ...@@ -871,11 +887,12 @@ function parse$1(componentOptions) {
__l: methods.__l, __l: methods.__l,
}; };
delete methods.__l; delete methods.__l;
// 百度小程序自定义组件,不支持绑定动态事件,故由 __e 分发
methods.__e = handleCustomEvent; methods.__e = handleCustomEvent;
} }
function handleCustomEvent(event) { function handleCustomEvent(event) {
const { type, target: { dataset: { eO: eventOpts }, }, } = event; const { type, detail: { __ins__ }, } = event;
const methodName = (eventOpts || {})[type]; const methodName = (__ins__.properties.eO || {})[type];
if (!methodName) { if (!methodName) {
return console.warn(type + ' not found'); return console.warn(type + ' not found');
} }
......
...@@ -7,6 +7,7 @@ import initMiniProgramPlugin, { ...@@ -7,6 +7,7 @@ import initMiniProgramPlugin, {
import source from './project.swan.json' import source from './project.swan.json'
import { transformFor } from './transforms/vFor' import { transformFor } from './transforms/vFor'
import { transformOn } from './transforms/vOn' import { transformOn } from './transforms/vOn'
import { transformModel } from './transforms/vModel'
const uniMiniProgramBaiduPlugin: Plugin = { const uniMiniProgramBaiduPlugin: Plugin = {
name: 'vite:uni-mp-baidu', name: 'vite:uni-mp-baidu',
...@@ -49,7 +50,7 @@ const options: UniMiniProgramPluginOptions = { ...@@ -49,7 +50,7 @@ const options: UniMiniProgramPluginOptions = {
}, },
template: { template: {
filter: { filter: {
extname: '.swan', extname: '.sjs',
lang: 'sjs', lang: 'sjs',
generate(filter, filename) { generate(filter, filename) {
if (filename) { if (filename) {
...@@ -69,6 +70,7 @@ ${filter.code} ...@@ -69,6 +70,7 @@ ${filter.code}
nodeTransforms: [transformFor], nodeTransforms: [transformFor],
directiveTransforms: { directiveTransforms: {
on: transformOn, on: transformOn,
model: transformModel,
}, },
}, },
}, },
......
import {
DirectiveNode,
DirectiveTransform,
isUserComponent,
SimpleExpressionNode,
transformModel as baseTransformModel,
} from '@dcloudio/uni-mp-compiler'
import { ComponentNode } from '@vue/compiler-core'
import { addEventOpts, createCustomEventExpr } from './vOn'
/**
* 百度小程序的自定义组件,不支持动态事件绑定,故 v-model 也需要调整
* @param dir
* @param node
* @param context
* @param augmentor
* @returns
*/
export const transformModel: DirectiveTransform = (
dir,
node,
context,
augmentor
) => {
const res = baseTransformModel(dir, node, context, augmentor)
const props = res.props as unknown as DirectiveNode[]
if (props.length < 2 || !isUserComponent(node, context)) {
return res
}
const { arg, exp } = props[1]
addEventOpts(
(arg as SimpleExpressionNode).content,
exp as SimpleExpressionNode,
node as ComponentNode
)
props[1].exp = createCustomEventExpr()
return res
}
...@@ -13,6 +13,7 @@ import { ...@@ -13,6 +13,7 @@ import {
createSimpleExpression, createSimpleExpression,
createCompoundExpression, createCompoundExpression,
CompoundExpressionNode, CompoundExpressionNode,
ComponentNode,
} from '@vue/compiler-core' } from '@vue/compiler-core'
/** /**
* 百度小程序的自定义组件,不支持动态事件绑定,故转换为静态事件 + dataset * 百度小程序的自定义组件,不支持动态事件绑定,故转换为静态事件 + dataset
...@@ -40,24 +41,35 @@ export const transformOn: DirectiveTransform = ( ...@@ -40,24 +41,35 @@ export const transformOn: DirectiveTransform = (
) { ) {
return res return res
} }
// data-event-opts
const opts = findProp(node, ATTR_DATA_EVENT_OPTS, true) as DirectiveNode
const value = res.props[0].value as ExpressionNode const value = res.props[0].value as ExpressionNode
res.props[0].value = createSimpleExpression('__e', true) res.props[0].value = createCustomEventExpr()
addEventOpts(arg.content, value, node)
return res
}
export function createCustomEventExpr() {
return createSimpleExpression('__e', true)
}
export function addEventOpts(
event: string,
value: ExpressionNode,
node: ComponentNode
) {
const opts = findProp(node, ATTR_DATA_EVENT_OPTS, true) as DirectiveNode
if (!opts) { if (!opts) {
node.props.push(createDataEventOptsProp(arg.content, value)) node.props.push(createDataEventOptsProp(event, value))
} else { } else {
const children = (opts.exp as CompoundExpressionNode).children const children = (opts.exp as CompoundExpressionNode).children
children.splice( children.splice(
children.length - 2, children.length - 2,
0, 0,
createDataEventOptsProperty(arg.content, value) createDataEventOptsProperty(event, value)
) )
} }
return res
} }
const ATTR_DATA_EVENT_OPTS = 'data-e-o' const ATTR_DATA_EVENT_OPTS = 'eO'
function createDataEventOptsProperty(event: string, exp: ExpressionNode) { function createDataEventOptsProperty(event: string, exp: ExpressionNode) {
return createCompoundExpression([`'${event}'`, ': ', exp, ',']) return createCompoundExpression([`'${event}'`, ': ', exp, ','])
......
...@@ -10,7 +10,6 @@ import { ...@@ -10,7 +10,6 @@ import {
fixSetDataStart, fixSetDataStart,
fixSetDataEnd, fixSetDataEnd,
} from '../../../uni-mp-weixin/src/runtime/fixSetData' } from '../../../uni-mp-weixin/src/runtime/fixSetData'
import { ComponentPublicInstance } from 'vue'
export { handleLink, initLifetimes } from '@dcloudio/uni-mp-weixin' export { handleLink, initLifetimes } from '@dcloudio/uni-mp-weixin'
...@@ -84,7 +83,7 @@ export function parse(componentOptions: MPComponentOptions) { ...@@ -84,7 +83,7 @@ export function parse(componentOptions: MPComponentOptions) {
__l: methods.__l, __l: methods.__l,
} }
delete methods.__l delete methods.__l
// 百度小程序自定义组件,不支持绑定动态事件,故由 __e 分发
methods.__e = handleCustomEvent methods.__e = handleCustomEvent
} }
...@@ -92,19 +91,16 @@ function handleCustomEvent( ...@@ -92,19 +91,16 @@ function handleCustomEvent(
this: MPComponentInstance, this: MPComponentInstance,
event: { event: {
type: string type: string
target: { dataset: { eO: { [name: string]: string } } }
detail: { detail: {
__args__: any[] __ins__: MPComponentInstance & { eO: Record<string, string> }
} }
} }
) { ) {
const { const {
type, type,
target: { detail: { __ins__ },
dataset: { eO: eventOpts },
},
} = event } = event
const methodName = (eventOpts || {})[type] const methodName = (__ins__.properties.eO || {})[type]
if (!methodName) { if (!methodName) {
return console.warn(type + ' not found') return console.warn(type + ' not found')
} }
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.json",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
...@@ -24,6 +24,7 @@ export { genExpr } from './codegen' ...@@ -24,6 +24,7 @@ export { genExpr } from './codegen'
export { isForElementNode } from './transforms/vFor' export { isForElementNode } from './transforms/vFor'
export { isUserComponent } from './transforms/utils' export { isUserComponent } from './transforms/utils'
export { transformOn } from './transforms/vOn' export { transformOn } from './transforms/vOn'
export { transformModel } from './transforms/vModel'
export * from './runtimeHelpers' export * from './runtimeHelpers'
export function parse(template: string, options: ParserOptions = {}): RootNode { export function parse(template: string, options: ParserOptions = {}): RootNode {
......
...@@ -25,6 +25,7 @@ import { createMPCompilerError, MPErrorCodes } from '../errors' ...@@ -25,6 +25,7 @@ import { createMPCompilerError, MPErrorCodes } from '../errors'
import { import {
BindingComponentTypes, BindingComponentTypes,
DirectiveTransform,
NodeTransform, NodeTransform,
TransformContext, TransformContext,
} from '../transform' } from '../transform'
...@@ -274,7 +275,7 @@ export function processProps( ...@@ -274,7 +275,7 @@ export function processProps(
} }
const directiveTransform = context.directiveTransforms[name] const directiveTransform = context.directiveTransforms[name]
if (directiveTransform) { if (name !== 'model' && directiveTransform) {
const { props } = directiveTransform(prop, node, context as any) const { props } = directiveTransform(prop, node, context as any)
if (props.length) { if (props.length) {
prop.exp = props[0].value as ExpressionNode prop.exp = props[0].value as ExpressionNode
...@@ -282,16 +283,25 @@ export function processProps( ...@@ -282,16 +283,25 @@ export function processProps(
} }
} }
} }
processVModel(node, context) const transformVModel = (context.directiveTransforms.model ||
transformModel) as unknown as DirectiveTransform
processVModel(node, transformVModel, context)
} }
function processVModel(node: ElementNode, context: TransformContext) { function processVModel(
node: ElementNode,
transformVModel: DirectiveTransform,
context: TransformContext
) {
const { props } = node const { props } = node
const dirs: DirectiveNode[] = [] const dirs: DirectiveNode[] = []
for (let i = 0; i < props.length; i++) { for (let i = 0; i < props.length; i++) {
const prop = props[i] const prop = props[i]
if (prop.type === NodeTypes.DIRECTIVE && prop.name === 'model') { if (prop.type === NodeTypes.DIRECTIVE && prop.name === 'model') {
dirs.push(...transformModel(prop, node, context)) dirs.push(
...(transformVModel(prop, node, context as any)
.props as unknown as DirectiveNode[])
)
props.splice(i, 1) props.splice(i, 1)
i-- i--
} }
......
...@@ -9,6 +9,8 @@ import { ...@@ -9,6 +9,8 @@ import {
ExpressionNode, ExpressionNode,
AttributeNode, AttributeNode,
createCompoundExpression, createCompoundExpression,
DirectiveTransform,
TransformContext as VueTransformContext,
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom' import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
import { camelize } from '@vue/shared' import { camelize } from '@vue/shared'
...@@ -16,17 +18,22 @@ import { V_ON } from '..' ...@@ -16,17 +18,22 @@ import { V_ON } from '..'
import { createBindDirectiveNode, createOnDirectiveNode } from '../ast' import { createBindDirectiveNode, createOnDirectiveNode } from '../ast'
import { genExpr } from '../codegen' import { genExpr } from '../codegen'
import { TransformContext } from '../transform' import { TransformContext } from '../transform'
import { DirectiveTransformResult } from './transformElement'
import { wrapperVOn } from './vOn' import { wrapperVOn } from './vOn'
export const transformModel = ( export const transformModel: DirectiveTransform = (
dir: DirectiveNode, dir: DirectiveNode,
node: ElementNode, node: ElementNode,
context: TransformContext _context: VueTransformContext
) => { ) => {
const baseResult = baseTransform(dir, node, context as any) const context = _context as unknown as TransformContext
const baseResult = baseTransform(dir, node, _context)
// base transform has errors OR component v-model (only need props) // base transform has errors OR component v-model (only need props)
if (!baseResult.props.length || node.tagType === ElementTypes.COMPONENT) { if (!baseResult.props.length || node.tagType === ElementTypes.COMPONENT) {
return transformComponentVModel(baseResult.props, context) return transformComponentVModel(
baseResult.props,
context
) as unknown as DirectiveTransformResult
} }
if (dir.arg) { if (dir.arg) {
...@@ -62,7 +69,11 @@ export const transformModel = ( ...@@ -62,7 +69,11 @@ export const transformModel = (
) )
} }
return transformElementVModel(baseResult.props, node, context) return transformElementVModel(
baseResult.props,
node,
context
) as unknown as DirectiveTransformResult
} }
function findInputDirectiveNode(props: (AttributeNode | DirectiveNode)[]) { function findInputDirectiveNode(props: (AttributeNode | DirectiveNode)[]) {
...@@ -79,7 +90,7 @@ function transformElementVModel( ...@@ -79,7 +90,7 @@ function transformElementVModel(
props: Property[], props: Property[],
node: ElementNode, node: ElementNode,
context: TransformContext context: TransformContext
): DirectiveNode[] { ) {
const dirs = transformVModel(props, context, { const dirs = transformVModel(props, context, {
binding: 'value', binding: 'value',
event: 'input', event: 'input',
...@@ -95,7 +106,7 @@ function transformElementVModel( ...@@ -95,7 +106,7 @@ function transformElementVModel(
dirs.length = 1 dirs.length = 1
} }
} }
return dirs return { props: dirs }
} }
function parseVOn(exp: ExpressionNode, context: TransformContext) { function parseVOn(exp: ExpressionNode, context: TransformContext) {
...@@ -122,12 +133,14 @@ function combineVOn( ...@@ -122,12 +133,14 @@ function combineVOn(
function transformComponentVModel( function transformComponentVModel(
props: Property[], props: Property[],
context: TransformContext context: TransformContext
): DirectiveNode[] { ) {
return transformVModel(props, context, { return {
formatEventCode(code) { props: transformVModel(props, context, {
return code formatEventCode(code) {
}, return code
}) },
}),
}
} }
function transformVModel( function transformVModel(
......
...@@ -17,8 +17,13 @@ function createEmitFn(oldEmit: Function, ctx: Record<string, any>) { ...@@ -17,8 +17,13 @@ function createEmitFn(oldEmit: Function, ctx: Record<string, any>) {
event: string, event: string,
...args: any[] ...args: any[]
) { ) {
if (ctx.$scope && event) { const scope = ctx.$scope as MPComponentInstance
;(ctx.$scope as any).triggerEvent(event, { __args__: args }) if (scope && event) {
const detail: Record<string, any> = { __args__: args }
if (__PLATFORM__ === 'mp-baidu') {
detail.__ins__ = scope
}
scope.triggerEvent(event, detail)
} }
if (__PLATFORM__ === 'mp-alipay') { if (__PLATFORM__ === 'mp-alipay') {
const vnode = this.$.vnode const vnode = this.$.vnode
......
...@@ -37,6 +37,14 @@ function createObserver(name: string) { ...@@ -37,6 +37,14 @@ function createObserver(name: string) {
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') {
// 百度小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
// event-opts
properties.eO = {
type: null,
value: '',
}
}
properties.vI = { properties.vI = {
type: null, // 均不指定类型,避免 property received type-uncompatible value 警告 type: null, // 均不指定类型,避免 property received type-uncompatible value 警告
value: '', value: '',
......
...@@ -36,7 +36,11 @@ Page = function (options) { ...@@ -36,7 +36,11 @@ Page = function (options) {
initHook(ON_LOAD, options) initHook(ON_LOAD, options)
return MPPage(options) return MPPage(options)
} }
if (__PLATFORM__ === 'mp-baidu') {
// 补充after,否则百度报:Cannot read property 'historyStack' of undefined
// https://smartprogram.baidu.com/forum/topic/show/153894
;(Page as any).after = (MPPage as any).after
}
Component = function (options) { Component = function (options) {
initHook('created', options) initHook('created', options)
return MPComponent(options) return MPComponent(options)
......
...@@ -129,8 +129,10 @@ const MP_METHODS = [ ...@@ -129,8 +129,10 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
scope.triggerEvent(event, detail);
} }
return oldEmit.apply(this, [event, ...args]); return oldEmit.apply(this, [event, ...args]);
}; };
......
...@@ -89,6 +89,10 @@ const uniMiniProgramQQPlugin = { ...@@ -89,6 +89,10 @@ const uniMiniProgramQQPlugin = {
define: { define: {
__VUE_CREATED_DEFERRED__: false, __VUE_CREATED_DEFERRED__: false,
}, },
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
}; };
}, },
writeBundle(_, bundle) { writeBundle(_, bundle) {
......
...@@ -129,8 +129,10 @@ const MP_METHODS = [ ...@@ -129,8 +129,10 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
scope.triggerEvent(event, detail);
} }
return oldEmit.apply(this, [event, ...args]); return oldEmit.apply(this, [event, ...args]);
}; };
......
...@@ -14,6 +14,10 @@ const uniMiniProgramQQPlugin: Plugin = { ...@@ -14,6 +14,10 @@ const uniMiniProgramQQPlugin: Plugin = {
define: { define: {
__VUE_CREATED_DEFERRED__: false, __VUE_CREATED_DEFERRED__: false,
}, },
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
} }
}, },
writeBundle(_, bundle) { writeBundle(_, bundle) {
......
...@@ -129,8 +129,10 @@ const MP_METHODS = [ ...@@ -129,8 +129,10 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
scope.triggerEvent(event, detail);
} }
return oldEmit.apply(this, [event, ...args]); return oldEmit.apply(this, [event, ...args]);
}; };
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
...@@ -21,7 +21,7 @@ export default (options: UniMiniProgramPluginOptions) => { ...@@ -21,7 +21,7 @@ export default (options: UniMiniProgramPluginOptions) => {
uniPagesJsonPlugin(options), uniPagesJsonPlugin(options),
uniEntryPlugin(options), uniEntryPlugin(options),
uniViteInjectPlugin(extend({}, options.vite.inject, initProvide())), uniViteInjectPlugin(extend({}, options.vite.inject, initProvide())),
uniRenderjsPlugin(), uniRenderjsPlugin({ lang: options.template.filter?.lang }),
uniMiniProgramPlugin(options), uniMiniProgramPlugin(options),
(options: { (options: {
vueOptions?: { script?: Partial<SFCScriptCompileOptions> } vueOptions?: { script?: Partial<SFCScriptCompileOptions> }
......
...@@ -33,7 +33,8 @@ export function buildOptions(): UserConfig['build'] { ...@@ -33,7 +33,8 @@ export function buildOptions(): UserConfig['build'] {
// sourcemap: 'inline', // TODO // sourcemap: 'inline', // TODO
// target: ['chrome53'], // 由小程序自己启用 es6 编译 // target: ['chrome53'], // 由小程序自己启用 es6 编译
emptyOutDir: false, // 不清空输出目录,否则会影响自定义的一些文件输出,比如wxml emptyOutDir: false, // 不清空输出目录,否则会影响自定义的一些文件输出,比如wxml
assetsInlineLimit: 40 * 1024, // 40kb // 由各个小程序控制,目前已知百度支持本地路径,其他不支持
// assetsInlineLimit: 0, // 40kb
lib: { lib: {
entry: resolveMainPathOnce(inputDir), entry: resolveMainPathOnce(inputDir),
formats: ['cjs'], formats: ['cjs'],
......
...@@ -15,7 +15,11 @@ export function getFiltersCache(resolvedConfig: ResolvedConfig) { ...@@ -15,7 +15,11 @@ export function getFiltersCache(resolvedConfig: ResolvedConfig) {
return filtersCache.get(resolvedConfig) || [] return filtersCache.get(resolvedConfig) || []
} }
export function uniRenderjsPlugin(): Plugin { const defaultCode = {
code: 'export default {}',
}
export function uniRenderjsPlugin({ lang }: { lang?: string }): Plugin {
let resolvedConfig: ResolvedConfig let resolvedConfig: ResolvedConfig
return { return {
name: 'vite:uni-mp-renderjs', name: 'vite:uni-mp-renderjs',
...@@ -31,10 +35,12 @@ export function uniRenderjsPlugin(): Plugin { ...@@ -31,10 +35,12 @@ export function uniRenderjsPlugin(): Plugin {
return return
} }
debugRenderjs(id) debugRenderjs(id)
if (type !== lang) {
return defaultCode
}
if (!name) { if (!name) {
this.error(missingModuleName(type, code)) this.error(missingModuleName(type, code))
} } else {
if (type === 'wxs') {
filtersCache.get(resolvedConfig)!.push({ filtersCache.get(resolvedConfig)!.push({
id, id,
type, type,
...@@ -42,9 +48,7 @@ export function uniRenderjsPlugin(): Plugin { ...@@ -42,9 +48,7 @@ export function uniRenderjsPlugin(): Plugin {
code, code,
}) })
} }
return { return defaultCode
code: 'export default {}',
}
}, },
} }
} }
...@@ -63,6 +63,10 @@ const uniMiniProgramWeixinPlugin = { ...@@ -63,6 +63,10 @@ const uniMiniProgramWeixinPlugin = {
define: { define: {
__VUE_CREATED_DEFERRED__: false, __VUE_CREATED_DEFERRED__: false,
}, },
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
}; };
}, },
}; };
......
...@@ -66,8 +66,10 @@ const MP_METHODS = [ ...@@ -66,8 +66,10 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
scope.triggerEvent(event, detail);
} }
return oldEmit.apply(this, [event, ...args]); return oldEmit.apply(this, [event, ...args]);
}; };
......
...@@ -13,6 +13,10 @@ const uniMiniProgramWeixinPlugin: Plugin = { ...@@ -13,6 +13,10 @@ const uniMiniProgramWeixinPlugin: Plugin = {
define: { define: {
__VUE_CREATED_DEFERRED__: false, __VUE_CREATED_DEFERRED__: false,
}, },
build: {
// css 中不支持引用本地资源
assetsInlineLimit: 40 * 1024, // 40kb
},
} }
}, },
} }
......
...@@ -129,8 +129,10 @@ const MP_METHODS = [ ...@@ -129,8 +129,10 @@ const MP_METHODS = [
]; ];
function createEmitFn(oldEmit, ctx) { function createEmitFn(oldEmit, ctx) {
return function emit(event, ...args) { return function emit(event, ...args) {
if (ctx.$scope && event) { const scope = ctx.$scope;
ctx.$scope.triggerEvent(event, { __args__: args }); if (scope && event) {
const detail = { __args__: args };
scope.triggerEvent(event, detail);
} }
return oldEmit.apply(this, [event, ...args]); return oldEmit.apply(this, [event, ...args]);
}; };
......
...@@ -8,8 +8,7 @@ ...@@ -8,8 +8,7 @@
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"files": [ "files": [
"dist/**/*.js", "dist",
"dist/**/*.d.ts",
"lib" "lib"
], ],
"repository": { "repository": {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册