From 9f13c0fd1d9b7d3b6e532da99bf828acdd0110b9 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Thu, 2 Jan 2020 18:48:26 +0800 Subject: [PATCH] fix(v3): v-for without child element #1206 --- packages/uni-app-plus/dist/index.v3.js | 26 +++++++++++++++++-- .../compiler-app-plus-extra.service.spec.js | 16 +++++++++--- .../compiler-app-plus.service.spec.js | 2 +- .../uni-template-compiler/__tests__/demo.js | 8 +++--- .../lib/app/parser/base-parser.js | 9 +++++-- .../uni-template-compiler/lib/app/service.js | 16 +++++++++++- .../uni-template-compiler/lib/app/util.js | 12 ++++++--- .../service/framework/plugins/data.js | 19 ++++++++++++++ src/shared/util.js | 8 ++++-- 9 files changed, 96 insertions(+), 20 deletions(-) diff --git a/packages/uni-app-plus/dist/index.v3.js b/packages/uni-app-plus/dist/index.v3.js index cb4c00c72..4422cf0ac 100644 --- a/packages/uni-app-plus/dist/index.v3.js +++ b/packages/uni-app-plus/dist/index.v3.js @@ -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 } diff --git a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js index 628cfa296..9e7a6a4b3 100644 --- a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js @@ -44,11 +44,11 @@ describe('codegen', () => { ) assertCodegen( '
', - `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( '
', - `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( '
', @@ -56,12 +56,20 @@ describe('codegen', () => { ) assertCodegen( '
', - `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( '
', `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( + '', + `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( + '{{item}}', + `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( diff --git a/packages/uni-template-compiler/__tests__/compiler-app-plus.service.spec.js b/packages/uni-template-compiler/__tests__/compiler-app-plus.service.spec.js index 9d10884d4..5db90d294 100644 --- a/packages/uni-template-compiler/__tests__/compiler-app-plus.service.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-app-plus.service.spec.js @@ -625,7 +625,7 @@ describe('codegen', () => { // normalize type: 2 assertCodegen( '
', - `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)}` ) }) diff --git a/packages/uni-template-compiler/__tests__/demo.js b/packages/uni-template-compiler/__tests__/demo.js index fafffcea9..22f6166f5 100644 --- a/packages/uni-template-compiler/__tests__/demo.js +++ b/packages/uni-template-compiler/__tests__/demo.js @@ -1,7 +1,7 @@ const compiler = require('../lib') const res = compiler.compile( ` - +
`, { 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, { diff --git a/packages/uni-template-compiler/lib/app/parser/base-parser.js b/packages/uni-template-compiler/lib/app/parser/base-parser.js index 6896d0efa..30fe8da69 100644 --- a/packages/uni-template-compiler/lib/app/parser/base-parser.js +++ b/packages/uni-template-compiler/lib/app/parser/base-parser.js @@ -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 } } diff --git a/packages/uni-template-compiler/lib/app/service.js b/packages/uni-template-compiler/lib/app/service.js index 5a2cb13bf..4f07200c5 100644 --- a/packages/uni-template-compiler/lib/app/service.js +++ b/packages/uni-template-compiler/lib/app/service.js @@ -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) diff --git a/packages/uni-template-compiler/lib/app/util.js b/packages/uni-template-compiler/lib/app/util.js index 025483c62..259a46b5d 100644 --- a/packages/uni-template-compiler/lib/app/util.js +++ b/packages/uni-template-compiler/lib/app/util.js @@ -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) { diff --git a/src/platforms/app-plus/service/framework/plugins/data.js b/src/platforms/app-plus/service/framework/plugins/data.js index bebdde124..d6535f0e6 100644 --- a/src/platforms/app-plus/service/framework/plugins/data.js +++ b/src/platforms/app-plus/service/framework/plugins/data.js @@ -1,6 +1,7 @@ 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 } diff --git a/src/shared/util.js b/src/shared/util.js index e820cda16..846722155 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -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()) -} +} -- GitLab