提交 9f13c0fd 编写于 作者: fxy060608's avatar fxy060608

fix(v3): v-for without child element #1206

上级 cddc9e83
......@@ -250,6 +250,10 @@ var serviceContext = (function () {
return typeof fn === 'function'
}
function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
function isPlainObject (obj) {
return _toString.call(obj) === '[object Object]'
}
......@@ -258,7 +262,7 @@ var serviceContext = (function () {
return hasOwnProperty.call(obj, key)
}
function noop () { }
function noop () {}
function toRawType (val) {
return _toString.call(val).slice(8, -1)
......@@ -2718,7 +2722,7 @@ var serviceContext = (function () {
}
return page.$page.meta.isTabBar
}
const route = __uniRoutes.find(route => route.path.slice(1) === path);
const route = __uniRoutes.find(route => route.path.replace(/^\//, '') === path.replace(/^\//, ''));
return route && route.meta.isTabBar
} catch (e) {
if (process.env.NODE_ENV !== 'production') {
......@@ -12760,11 +12764,29 @@ var serviceContext = (function () {
return ((this._$newData[id] || (this._$newData[id] = {}))[name] = value)
}
function fillVForData (forItems, vForData) {
let i, l;
if (Array.isArray(forItems) || typeof forItems === 'string') {
for (i = 0, l = forItems.length; i < l; i++) {
vForData[i] = i;
}
} else if (typeof forItems === 'number') {
for (i = 0; i < forItems; i++) {
vForData[i] = i;
}
} else if (isObject(forItems)) {
for (i = 0, l = Object.keys(forItems).length; i < l; i++) {
vForData[i] = i;
}
}
}
function setForData (id, value) {
const diffData = this._$newData[id] || (this._$newData[id] = {});
const vForData = diffData[V_FOR] || (diffData[V_FOR] = []);
if (value.forItems) {
value.fill && fillVForData(value.forItems, vForData);
return value.forItems
}
......
......@@ -44,11 +44,11 @@ describe('codegen', () => {
)
assertCodegen(
'<div><template v-for="item in items">text</template></div>',
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items})),function(item,$10,$20,$30){return void 0})],2)}`
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items,fill:true})),function(item,$10,$20,$30){return void 0})],2)}`
)
assertCodegen(
'<div><template v-for="item in items">{{text}}</template></div>',
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items})),function(item,$10,$20,$30){return [_v((_$s(("1-"+$30),'t0',_s(text))))]})],2)}`
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items,fill:true})),function(item,$10,$20,$30){return [_v((_$s(("1-"+$30),'t0',_s(text))))]})],2)}`
)
assertCodegen(
'<div><template v-for="item in items"><span></span>{{text}}</template></div>',
......@@ -56,12 +56,20 @@ describe('codegen', () => {
)
assertCodegen(
'<div><template v-for="item in items">a {{text1}} b {{text2}}</template></div>',
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items})),function(item,$10,$20,$30){return [_v((_$s(("1-"+$30),'t0',_s(text1)))+(_$s(("1-"+$30),'t1',_s(text2))))]})],2)}`
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items,fill:true})),function(item,$10,$20,$30){return [_v((_$s(("1-"+$30),'t0',_s(text1)))+(_$s(("1-"+$30),'t1',_s(text2))))]})],2)}`
)
assertCodegen(
'<div><template v-for="item in items"><span v-if="item.sub"></span></template></div>',
`with(this){return _c('div',[_l((_$s(1,'f',{forItems:items})),function(item,$10,$20,$30){return [(_$s(("2-"+$30),'i',item.sub))?_c('span',{key:_$s(1,'f',{forIndex:$20,keyIndex:0,key:1+'-0'+$30})}):_e()]})],2)}`
)
)
assertCodegen(
'<view><template v-for="(item, index) in arr">{{item}}</template></view>',
`with(this){return _c('view',[_l((_$s(1,'f',{forItems:arr,fill:true})),function(item,index,$20,$30){return [_v((_$s(("1-"+$30),'t0',_s(item))))]})],2)}`
)
assertCodegen(
'<view><block v-for="(item, index) in arr" v-bind:key="index">{{item}}</block></view>',
`with(this){return _c('view',[_l((_$s(1,'f',{forItems:arr,fill:true})),function(item,index,$20,$30){return [_v((_$s(("1-"+$30),'t0',_s(item))))]})],2)}`
)
})
it('generate text with multiple statements', () => {
assertCodegen(
......
......@@ -625,7 +625,7 @@ describe('codegen', () => {
// normalize type: 2
assertCodegen(
'<div><child></child><template v-for="item in list">{{ item }}</template></div>',
`with(this){return _c('div',[_c('child',{attrs:{"_i":1}}),_l((_$s(2,'f',{forItems:list})),function(item,$10,$20,$30){return [_v((_$s(("2-"+$30),'t0',_s(item))))]})],2)}`
`with(this){return _c('div',[_c('child',{attrs:{"_i":1}}),_l((_$s(2,'f',{forItems:list,fill:true})),function(item,$10,$20,$30){return [_v((_$s(("2-"+$30),'t0',_s(item))))]})],2)}`
)
})
......
const compiler = require('../lib')
const res = compiler.compile(
`
<view><page-meta/><view><button></button></view></view>
<div><template v-for="item in items">text</template></div>
`, {
miniprogram: true,
resourcePath: '/User/fxy/Documents/test.wxml',
......@@ -14,9 +14,9 @@ const res = compiler.compile(
mp: {
platform: 'mp-weixin'
},
filterModules: ['swipe']
// service: true,
// view: true
filterModules: ['swipe'],
service: true,
view: true
})
console.log(require('util').inspect(res, {
......
......@@ -33,9 +33,14 @@ function parseIf (el, createGenVar, isScopedSlot) {
el.if = createGenVar(el.attrsMap[ID], isScopedSlot)(V_IF, el.if)
}
function parseFor (el, createGenVar, isScopedSlot) {
function parseFor (el, createGenVar, isScopedSlot, fill = false) {
if (el.for && isVar(el.for)) {
el.for = createGenVar(el.forId, isScopedSlot)(V_FOR, `{forItems:${el.for}}`)
el.for = createGenVar(el.forId, isScopedSlot)(
V_FOR,
fill
? `{forItems:${el.for},fill:true}`
: `{forItems:${el.for}}`
)
return true
}
}
......
......@@ -85,6 +85,20 @@ function parseComponentAttrs (el, genVar) {
})
}
function checkAutoFill (el) {
if (
el.for &&
(
el.tag === 'template' ||
el.tag === 'block'
) &&
!el.children.find(child => child.type === 1)
) {
return true
}
return false
}
function transformNode (el, parent, state, isScopedSlot) {
if (el.type === 3) {
return
......@@ -111,7 +125,7 @@ function transformNode (el, parent, state, isScopedSlot) {
const genVar = createGenVar(el.attrsMap[ID], isScopedSlot)
parseIs(el, genVar)
parseFor(el, createGenVar, isScopedSlot)
parseFor(el, createGenVar, isScopedSlot, checkAutoFill(el))
parseKey(el, isScopedSlot)
parseIf(el, createGenVar, isScopedSlot)
......
......@@ -170,9 +170,15 @@ function processForKey (el) {
const keyIndex = forEl.children.indexOf(el)
el.key = `${forEl.forId}+'-${keyIndex}'+${it}`
} else { // 当 template 下只有文本节点
if (el.children && el.children.length && !el.children.find(child => child.key)) {
if (
el.children &&
el.children.length &&
!el.children.find(child => child.type === 1)
) {
el.children[0].parent = el
el.children[0].key = `${forEl.forId}+'-0'+${it}`
if (!el.children.find(child => child.key)) {
el.children[0].key = `${forEl.forId}+'-0'+${it}`
}
return true
}
}
......@@ -219,8 +225,6 @@ function removeRawAttr (el, name) {
function removeRawBindingAttr (el, name) {
removeRawAttr(el, ':' + name)
removeRawAttr(el, 'v-bind:' + name)
console.log(el)
throw new Error('123')
}
function addHandler (el, name, value, important) {
......
import {
guid,
hasOwn,
isObject,
camelize
} from 'uni-shared'
......@@ -164,11 +165,29 @@ function setData (id, name, value) {
return ((this._$newData[id] || (this._$newData[id] = {}))[name] = value)
}
function fillVForData (forItems, vForData) {
let i, l
if (Array.isArray(forItems) || typeof forItems === 'string') {
for (i = 0, l = forItems.length; i < l; i++) {
vForData[i] = i
}
} else if (typeof forItems === 'number') {
for (i = 0; i < forItems; i++) {
vForData[i] = i
}
} else if (isObject(forItems)) {
for (i = 0, l = Object.keys(forItems).length; i < l; i++) {
vForData[i] = i
}
}
}
function setForData (id, value) {
const diffData = this._$newData[id] || (this._$newData[id] = {})
const vForData = diffData[V_FOR] || (diffData[V_FOR] = [])
if (value.forItems) {
value.fill && fillVForData(value.forItems, vForData)
return value.forItems
}
......
......@@ -13,6 +13,10 @@ export function isStr (str) {
return typeof str === 'string'
}
export function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
export function isPlainObject (obj) {
return _toString.call(obj) === '[object Object]'
}
......@@ -21,7 +25,7 @@ export function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}
export function noop () { }
export function noop () {}
export function toRawType (val) {
return _toString.call(val).slice(8, -1)
......@@ -91,4 +95,4 @@ export function debounce (fn, delay) {
export function kebabCase (string) {
return string.replace(/[A-Z]/g, str => '-' + str.toLowerCase())
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册