feat(compiler): ensure interpolation expressions are wrapped with toString()

This commit is contained in:
Evan You
2019-09-23 15:36:30 -04:00
parent e09e887219
commit b3b67b8c7d
23 changed files with 148 additions and 50 deletions

View File

@@ -17,7 +17,7 @@ import {
import { isArray } from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors'
import {
CREATE_ELEMENT,
CREATE_VNODE,
APPLY_DIRECTIVES,
RESOLVE_DIRECTIVE,
RESOLVE_COMPONENT
@@ -67,8 +67,8 @@ export const prepareElementForCodegen: NodeTransform = (node, context) => {
}
const { loc } = node
context.imports.add(CREATE_ELEMENT)
const vnode = createCallExpression(CREATE_ELEMENT, args, loc)
context.imports.add(CREATE_VNODE)
const vnode = createCallExpression(CREATE_VNODE, args, loc)
if (runtimeDirectives && runtimeDirectives.length) {
context.imports.add(APPLY_DIRECTIVES)

View File

@@ -40,6 +40,9 @@ const simpleIdRE = /^[a-zA-Z$_][\w$]*$/
let _parseScript: typeof parseScript
let _walk: typeof walk
// Important: since this function uses Node.js only dependencies, it should
// always be used with a leading !__BROWSER__ check so that it can be
// tree-shaken from the browser build.
export function processExpression(
node: ExpressionNode,
context: TransformContext
@@ -73,7 +76,7 @@ export function processExpression(
if (node.type === 'Identifier') {
if (ids.indexOf(node) === -1) {
ids.push(node)
if (!knownIds[node.name] && shouldPrependContext(node, parent)) {
if (!knownIds[node.name] && shouldPrefix(node, parent)) {
node.name = `_ctx.${node.name}`
}
}
@@ -141,7 +144,7 @@ const globals = new Set(
const isFunction = (node: Node): node is Function =>
/Function(Expression|Declaration)$/.test(node.type)
function shouldPrependContext(identifier: Identifier, parent: Node) {
function shouldPrefix(identifier: Identifier, parent: Node) {
if (
// not id of a FunctionDeclaration
!(parent.type === 'FunctionDeclaration' && parent.id === identifier) &&

View File

@@ -1 +0,0 @@
// TODO

View File

@@ -1 +0,0 @@
// TODO

View File

@@ -0,0 +1,9 @@
// Optimizations
// - b -> normalize(b)
// - ['foo', b] -> 'foo' + normalize(b)
// - { a, b: c } -> (a ? a : '') + (b ? c : '')
// - ['a', b, { c }] -> 'a' + normalize(b) + (c ? c : '')
// Also merge dynamic and static class into a single prop
// Attach CLASS patchFlag if necessary

View File

@@ -0,0 +1,14 @@
// Optimizations
// The compiler pre-compiles static string styles into static objects
// + detects and hoists inline static objects
// e.g. `style="color: red"` and `:style="{ color: 'red' }"` both get hoisted as
// ``` js
// const style = { color: 'red' }
// render() { return e('div', { style }) }
// ```
// Also nerge dynamic and static style into a single prop
// Attach STYLE patchFlag if necessary

View File

@@ -21,10 +21,10 @@ export const transformFor = createStructuralDirectiveTransform(
'for',
(node, dir, context) => {
if (dir.exp) {
context.imports.add(RENDER_LIST)
const parseResult = parseForExpression(dir.exp, context)
if (parseResult) {
context.imports.add(RENDER_LIST)
const { source, value, key, index } = parseResult
context.replaceNode({