Browse Source

feat(weex): WIP fix flow + handle errors in recycle-list template render

dev
Evan You 7 years ago
parent
commit
5c2ce0017f
  1. 4
      flow/compiler.js
  2. 15
      src/platforms/weex/compiler/index.js
  3. 4
      src/platforms/weex/compiler/modules/recycle-list/component.js
  4. 9
      src/platforms/weex/compiler/modules/recycle-list/index.js
  5. 30
      src/platforms/weex/runtime/recycle-list/render-component-template.js

4
flow/compiler.js

@ -21,9 +21,6 @@ declare type CompilerOptions = {
shouldDecodeNewlinesForHref?: boolean;
optimize?: boolean;
// support <recycle-list> in weex
recyclable?: boolean;
// for ssr optimization compiler
scopeId?: string;
@ -37,7 +34,6 @@ declare type CompilerOptions = {
declare type CompiledResult = {
ast: ?ASTElement;
render: string;
'@render'?: string;
staticRenderFns: Array<string>;
stringRenderFns?: Array<string>;
errors?: Array<string>;

15
src/platforms/weex/compiler/index.js

@ -14,7 +14,16 @@ import {
getTagNamespace
} from '../util/index'
export const baseOptions: CompilerOptions = {
export type WeexCompilerOptions = CompilerOptions & {
// whether to compile special template for <recycle-list>
recyclable?: boolean;
};
export type WeexCompiledResult = CompiledResult & {
'@render'?: string;
};
export const baseOptions: WeexCompilerOptions = {
modules,
directives,
isUnaryTag,
@ -31,8 +40,8 @@ const compiler = createCompiler(baseOptions)
export function compile (
template: string,
options?: CompilerOptions
): CompiledResult {
options?: WeexCompilerOptions
): WeexCompiledResult {
let generateAltRender = false
if (options && options.recyclable === true) {
generateAltRender = true

4
src/platforms/weex/compiler/modules/recycle-list/component.js

@ -2,10 +2,12 @@
import { addAttr } from 'compiler/helpers'
import { RECYCLE_LIST_MARKER } from 'weex/util/index'
import type { WeexCompilerOptions } from 'weex/compiler/index'
// mark components as inside recycle-list so that we know we need to invoke
// their special @render function instead of render in create-component.js
export function postTransformComponent (el: ASTElement, options: CompilerOptions) {
export function postTransformComponent (el: ASTElement, options: WeexCompilerOptions) {
// $flow-disable-line (we know isReservedTag is there)
if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
addAttr(el, RECYCLE_LIST_MARKER, true)
}

9
src/platforms/weex/compiler/modules/recycle-list/index.js

@ -1,5 +1,6 @@
/* @flow */
import type { WeexCompilerOptions } from 'weex/compiler/index'
import { postTransformComponent } from './component'
import { postTransformText } from './text'
import { preTransformVBind } from './v-bind'
@ -9,12 +10,12 @@ import { postTransformVOn } from './v-on'
let currentRecycleList = null
function shouldCompile (el: ASTElement, options: CompilerOptions) {
function shouldCompile (el: ASTElement, options: WeexCompilerOptions) {
return options.recyclable ||
(currentRecycleList && el !== currentRecycleList)
}
function preTransformNode (el: ASTElement, options: CompilerOptions) {
function preTransformNode (el: ASTElement, options: WeexCompilerOptions) {
if (el.tag === 'recycle-list') {
currentRecycleList = el
}
@ -25,13 +26,13 @@ function preTransformNode (el: ASTElement, options: CompilerOptions) {
}
}
function transformNode (el: ASTElement, options: CompilerOptions) {
function transformNode (el: ASTElement, options: WeexCompilerOptions) {
if (shouldCompile(el, options)) {
// do nothing yet
}
}
function postTransformNode (el: ASTElement, options: CompilerOptions) {
function postTransformNode (el: ASTElement, options: WeexCompilerOptions) {
if (shouldCompile(el, options)) {
postTransformComponent(el, options)
// <text>: transform children text into value attr

30
src/platforms/weex/runtime/recycle-list/render-component-template.js

@ -1,17 +1,35 @@
/* @flow */
import { warn } from 'core/util/debug'
import { handleError } from 'core/util/error'
import { RECYCLE_LIST_MARKER } from 'weex/util/index'
import { createComponentInstanceForVnode } from 'core/vdom/create-component'
export function isRecyclableComponent (vnode: VNodeWithData): boolean {
return vnode.data.attrs && (RECYCLE_LIST_MARKER in vnode.data.attrs)
return vnode.data.attrs
? (RECYCLE_LIST_MARKER in vnode.data.attrs)
: false
}
export function renderRecyclableComponentTemplate (vnode: VNodeWithData): VNode {
export function renderRecyclableComponentTemplate (vnode: MountedComponentVNode): VNode {
// TODO:
// 1. adding @isComponentRoot / @componentProps to the root node
// 2. proper error handling
// adding @isComponentRoot / @componentProps to the root node
// $flow-disable-line
delete vnode.data.attrs[RECYCLE_LIST_MARKER]
const instance = createComponentInstanceForVnode(vnode)
return instance.$options['@render'].call(instance)
const vm = createComponentInstanceForVnode(vnode)
const render = (vm.$options: any)['@render']
if (render) {
try {
return render.call(vm)
} catch (err) {
handleError(err, vm, `@render`)
}
} else {
warn(
`@render function not defined on component used in <recycle-list>. ` +
`Make sure to declare \`recyclable="true"\` on the component's template.`,
vm
)
}
}

Loading…
Cancel
Save