feat: v-once

Note: only compiler transform is tested - integration with runtime
still needs to be tested.
This commit is contained in:
Evan You
2019-10-09 17:32:58 -04:00
parent 5dfb271551
commit 93c6aa4c90
7 changed files with 63 additions and 13 deletions

View File

@@ -0,0 +1,30 @@
import { parse, transform, ElementNode, CallExpression } from '../../src'
import { transformOnce } from '../../src/transforms/vOnce'
import { transformElement } from '../../src/transforms/transformElement'
import { createObjectMatcher } from '../testUtils'
function transformWithCloak(template: string) {
const ast = parse(template)
transform(ast, {
nodeTransforms: [transformElement],
directiveTransforms: {
once: transformOnce
}
})
return ast.children[0] as ElementNode
}
describe('compiler: v-once transform', () => {
test('should add no props to DOM', () => {
const node = transformWithCloak(`<div v-once />`)
const codegenArgs = (node.codegenNode as CallExpression).arguments
// As v-cloak adds no properties the codegen should be identical to
// rendering a div with no props or reactive data (so just the tag as the arg)
expect(codegenArgs[1]).toMatchObject(
createObjectMatcher({
$once: `[true]`
})
)
})
})

View File

@@ -13,6 +13,7 @@ import { transformBind } from './transforms/vBind'
import { defaultOnError, createCompilerError, ErrorCodes } from './errors'
import { trackSlotScopes, trackVForSlotScopes } from './transforms/vSlot'
import { optimizeText } from './transforms/optimizeText'
import { transformOnce } from './transforms/vOnce'
export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions
@@ -60,6 +61,7 @@ export function baseCompile(
directiveTransforms: {
on: transformOn,
bind: transformBind,
once: transformOnce,
...(options.directiveTransforms || {}) // user transforms
}
})

View File

@@ -0,0 +1,15 @@
import {
DirectiveTransform,
createObjectProperty,
createSimpleExpression
} from '@vue/compiler-core'
export const transformOnce: DirectiveTransform = dir => {
return {
props: createObjectProperty(
createSimpleExpression(`$once`, true, dir.loc),
createSimpleExpression('true', false)
),
needRuntime: false
}
}

View File

@@ -63,7 +63,7 @@ export const walkJS: typeof walk = (ast, walker) => {
}
export const isSimpleIdentifier = (name: string): boolean =>
!/^\d|[^\w]/.test(name)
!/^\d|[^\$\w]/.test(name)
export function getInnerRange(
loc: SourceLocation,