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

wip(app): nvue v-model

上级 4927ba04
......@@ -16855,7 +16855,7 @@ function addCurrentPage(page) {
return pages.push(page);
}
// 开发阶段热刷新需要移除旧的相同 id 的 page
const index = pages.findIndex((page) => page.$page.id === page.$page.id);
const index = pages.findIndex((p) => p.$page.id === page.$page.id);
if (index > -1) {
pages.splice(index, 1, page);
}
......
......@@ -11,7 +11,7 @@ export function addCurrentPage(page: ComponentPublicInstance) {
return pages.push(page)
}
// 开发阶段热刷新需要移除旧的相同 id 的 page
const index = pages.findIndex((page) => page.$page.id === page.$page.id)
const index = pages.findIndex((p) => p.$page.id === page.$page.id)
if (index > -1) {
pages.splice(index, 1, page)
} else {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`app-nvue: compiler <input v-model="text"/> 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
const _hoisted_1 = [\\"modelValue\\"]
export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock(\\"u-input\\", {
modelValue: _ctx.text,
\\"onUpdate:modelValue\\": _cache[0] || (_cache[0] = $event => ((_ctx.text) = $event))
}, null, 8 /* PROPS */, _hoisted_1))
}"
`;
exports[`app-nvue: compiler <textarea v-model="text"/> 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
const _hoisted_1 = [\\"modelValue\\"]
export function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock(\\"u-textarea\\", {
modelValue: _ctx.text,
\\"onUpdate:modelValue\\": _cache[0] || (_cache[0] = $event => ((_ctx.text) = $event))
}, null, 8 /* PROPS */, _hoisted_1))
}"
`;
exports[`app-nvue: compiler <video></video> 1`] = `
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
......
......@@ -38,6 +38,8 @@ const codes = [
`<view>hello{{a}}<view>aaa{{a}}</view>{{b}}</view>`,
`<video></video>`,
`<video><view></view></video>`,
`<input v-model="text"/>`,
`<textarea v-model="text"/>`,
]
describe('app-nvue: compiler', () => {
......
import {
transformModel as baseTransform,
DirectiveTransform,
ElementTypes,
findProp,
NodeTypes,
hasDynamicKeyVBind,
} from '@vue/compiler-core'
import { createDOMCompilerError, DOMErrorCodes } from '@vue/compiler-dom'
import { createNVueCompilerError, NVueErrorCodes } from './errors'
// 所有的 v-model 均走自定义组件的实现逻辑,包括 input,textarea
export const transformModel: DirectiveTransform = (dir, node, context) => {
const baseResult = baseTransform(dir, node, context)
// base transform has errors OR component v-model (only need props)
if (!baseResult.props.length || node.tagType === ElementTypes.COMPONENT) {
return baseResult
}
if (dir.arg) {
context.onError(
createDOMCompilerError(
DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT,
dir.arg.loc
)
)
}
function checkDuplicatedValue() {
const value = findProp(node, 'value')
if (value) {
context.onError(
createDOMCompilerError(
DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE,
value.loc
)
)
}
}
const { tag } = node
const isCustomElement = context.isCustomElement(tag)
if (
tag === 'input' ||
tag === 'u-input' ||
tag === 'textarea' ||
tag === 'u-textarea' ||
isCustomElement
) {
if (tag === 'input' || tag === 'u-input' || isCustomElement) {
const type = findProp(node, `type`)
if (type) {
if (type.type === NodeTypes.DIRECTIVE) {
// :type="foo"
context.onError(
createNVueCompilerError(
NVueErrorCodes.X_V_MODEL_DYNAMIC_TYPE,
dir.loc
)
)
} else if (type.value) {
checkDuplicatedValue()
}
} else if (hasDynamicKeyVBind(node)) {
// element has bindings with dynamic keys, which can possibly contain
// "type".
// directiveToUse = V_MODEL_DYNAMIC
context.onError(
createNVueCompilerError(NVueErrorCodes.X_V_MODEL_AND_V_BIND, dir.loc)
)
} else {
// text type
checkDuplicatedValue()
}
} else {
// textarea
checkDuplicatedValue()
}
} else {
context.onError(
createDOMCompilerError(
DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT,
dir.loc
)
)
}
// native vmodel doesn't need the `modelValue` props since they are also
// passed to the runtime as `binding.value`. removing it reduces code size.
baseResult.props = baseResult.props.filter(
(p) =>
!(
p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
p.key.content === 'modelValue'
)
)
return baseResult
return baseTransform(dir, node, context)
}
......@@ -9467,9 +9467,7 @@ function patchAttr(el, key, value) {
[key, value] = transformAttr(el, key, value, instance);
}
if (value == null) ;else {
el.setAttr(key, value);
}
el.setAttr(key, value);
}
var ATTR_HOVER_CLASS = 'hoverClass';
......@@ -9694,6 +9692,8 @@ function patchStyle(el, prev, next) {
el.setStyles(batchedStyles);
}
var vModelTags = ['u-input', 'u-textarea'];
var patchProp = function (el, key, prevValue, nextValue) {
var isSVG = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var prevChildren = arguments.length > 5 ? arguments[5] : undefined;
......@@ -9710,6 +9710,12 @@ var patchProp = function (el, key, prevValue, nextValue) {
if (!isModelListener(key)) {
patchEvent(el, key, prevValue, nextValue, parentComponent);
}
} else if (key === 'modelValue' && vModelTags.includes(el.type)) {
// v-model 时,原生 input 和 textarea 接收的是 value
el.setAttrs({
modelValue: nextValue,
value: nextValue
});
} else {
patchAttr(el, key, nextValue, parentComponent);
}
......
......@@ -7734,9 +7734,7 @@ function patchAttr(el, key, value) {
[key, value] = transformAttr(el, key, value, instance);
}
if (value == null) ;else {
el.setAttr(key, value);
}
el.setAttr(key, value);
}
var ATTR_HOVER_CLASS = 'hoverClass';
......@@ -7961,6 +7959,8 @@ function patchStyle(el, prev, next) {
el.setStyles(batchedStyles);
}
var vModelTags = ['u-input', 'u-textarea'];
var patchProp = function (el, key, prevValue, nextValue) {
var isSVG = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var prevChildren = arguments.length > 5 ? arguments[5] : undefined;
......@@ -7977,6 +7977,12 @@ var patchProp = function (el, key, prevValue, nextValue) {
if (!isModelListener(key)) {
patchEvent(el, key, prevValue, nextValue, parentComponent);
}
} else if (key === 'modelValue' && vModelTags.includes(el.type)) {
// v-model 时,原生 input 和 textarea 接收的是 value
el.setAttrs({
modelValue: nextValue,
value: nextValue
});
} else {
patchAttr(el, key, nextValue, parentComponent);
}
......
......@@ -7919,10 +7919,7 @@ function patchAttr(el, key, value, instance = null) {
if (instance) {
[key, value] = transformAttr(el, key, value, instance);
}
if (value == null) ;
else {
el.setAttr(key, value);
}
el.setAttr(key, value);
}
const ATTR_HOVER_CLASS = 'hoverClass';
const ATTR_PLACEHOLDER_CLASS = 'placeholderClass';
......@@ -8109,6 +8106,7 @@ function patchStyle(el, prev, next) {
el.setStyles(batchedStyles);
}
const vModelTags = ['u-input', 'u-textarea'];
const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
if (key === 'class') {
patchClass(el, prevValue, nextValue, parentComponent);
......@@ -8122,6 +8120,10 @@ const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, p
patchEvent(el, key, prevValue, nextValue, parentComponent);
}
}
else if (key === 'modelValue' && vModelTags.includes(el.type)) {
// v-model 时,原生 input 和 textarea 接收的是 value
el.setAttrs({ modelValue: nextValue, value: nextValue });
}
else {
patchAttr(el, key, nextValue, parentComponent);
}
......
......@@ -56,7 +56,7 @@
"vite": "^2.8.4"
},
"uni-app": {
"compilerVersion": "3.3.8"
"compilerVersion": "3.3.11"
},
"gitHead": "33e807d66e1fe47e2ee08ad9c59247e37b8884da"
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册