Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initData() 返回非字面量的值(类型为 function)时,没有正确识别 #99

Closed
zhuguoxi opened this issue Apr 8, 2021 · 5 comments
Assignees
Labels
bug Something isn't working released

Comments

@zhuguoxi
Copy link
Member

zhuguoxi commented Apr 8, 2021

let components = {
    'x-label': defineComponent({
        template: `<div>x-laber</div>`
    })
}
module.exports = defineComponent({
    components,
    template: `<div s-if="components['x-label']"><x-label/></div>`,
    initData() {
        return {
            components
        }
    }
})

报错信息:
无输出 html string

@harttle
Copy link
Member

harttle commented Apr 12, 2021

我发现 initData 返回值只要不是 Literal 就可能有问题,比如下面的代码组件渲染结果预期是 true

let foo = { bar: {} }

const MyApp = san.defineComponent({
  template: '<div>{{foo.bar == bar}}</div>'
});

var instance = new MyApp({
  data: {
    foo: foo,
    bar: foo.bar
  }
});

如果 initData 在编译期 toString() 后 data 会变成:

{
  foo: { bar: {} },
  bar: {}
}

最终会导致渲染成 false。所以如果要支持这种场景,结论是:只有明确 initData 返回值是 Literal 的时候,才能够在编译期执行 initData。

推论1:DynamicComponent(输入为 ComponentClass 的情况)只能在运行时执行 initData,因为无法得知它的返回值是否是 Literal。
推论2:compileToRender 只能在运行时执行 initData,因为 compileToRender 只支持 DynamicComponent。
推论3:initData 任何情况都不能编译期生成,因为非 DynamicComponent 的情况 san-ssr 编译期无法执行它的代码,也无法拿到 initData 的结果。

@harttle harttle self-assigned this Apr 12, 2021
@errorrik
Copy link
Collaborator

@zhuguoxi 这么写的目的是啥,为了满足什么样的应用场景?

@zhuguoxi
Copy link
Member Author

zhuguoxi commented Apr 12, 2021

业务代码中 在使用s-is场景中做判断是否有必要渲染组件。

let components = {
    'x-label': defineComponent({
        template: `<div>x-laber</div>`
    })
}
let cmptKeys = ['x-label', 'other'];

module.exports = defineComponent({
    components,
    template: `
        <div s-for="cmptKey in cmptKeys">
            <x-cmpt
                s-is="comKey"
                s-if="components[comKey]"></x-cmpt>
        </div>
    `,
    initData() {
        return {
            components,
            cmptKeys
        }
    }
})

@errorrik
Copy link
Collaborator

errorrik commented Apr 12, 2021

let components = {};
let cmptKeys = [];

let template = '<fragment>';
cmptKeys.forEach(key => {
    if (components[key]) {
        template += `<div><x-cmpt s-is="${components[key]}" /></div>`;
    }
});
template += '</fragment>';

module.exports = defineComponent({
    components,
    template
});

组件实例化前就确定的东西,不必等到组件渲染时

@harttle harttle closed this as completed Apr 14, 2021
github-actions bot pushed a commit that referenced this issue Apr 14, 2021
## [4.6.3](v4.6.2...v4.6.3) (2021-04-14)

### Bug Fixes

* initData() 返回值不是字面量时序列化结果不正确的问题, close [#99](#99) ([17c2256](17c2256))
@github-actions
Copy link

🎉 This issue has been resolved in version 4.6.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@harttle harttle changed the title ssr 上下文不能使用 components 变量 initData() 返回非字面量的值(类型为 function)时,没有正确识别 May 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
Development

No branches or pull requests

4 participants