Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-app
提交
298bb93d
U
uni-app
项目概览
DCloud
/
uni-app
4 个月 前同步成功
通知
726
Star
38705
Fork
3642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
7
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
7
Issue
7
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
298bb93d
编写于
7月 21, 2020
作者:
Q
qiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: 头条小程序支持解构插槽 question/80187
上级
aaeb31e1
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
181 addition
and
4 deletion
+181
-4
packages/uni-mp-toutiao/lib/uni.compiler.js
packages/uni-mp-toutiao/lib/uni.compiler.js
+116
-2
packages/uni-template-compiler/lib/template/generate.js
packages/uni-template-compiler/lib/template/generate.js
+6
-1
packages/webpack-uni-mp-loader/lib/plugin/generate-component.js
...es/webpack-uni-mp-loader/lib/plugin/generate-component.js
+54
-1
src/core/runtime/wrapper/util.js
src/core/runtime/wrapper/util.js
+5
-0
未找到文件。
packages/uni-mp-toutiao/lib/uni.compiler.js
浏览文件 @
298bb93d
const
compiler
=
require
(
'
@dcloudio/uni-mp-weixin/lib/uni.compiler.js
'
)
const
path
=
require
(
'
path
'
)
const
t
=
require
(
'
@babel/types
'
)
function
generateJsCode
(
properties
=
'
{}
'
)
{
return
`
wx.createComponent({
generic:true,
props:
${
properties
}
,
render: function(){}
})
`
}
function
generateCssCode
(
filename
)
{
return
`
@import "./
${
filename
}
"
`
}
function
hasOwn
(
obj
,
key
)
{
return
Object
.
prototype
.
hasOwnProperty
.
call
(
obj
,
key
)
}
module
.
exports
=
Object
.
assign
({},
compiler
,
{
directive
:
'
tt:
'
directive
:
'
tt:
'
,
resolveScopedSlots
(
slotName
,
{
genCode
,
generate
,
ownerName
,
parentName
,
parentNode
,
resourcePath
,
paramExprNode
,
returnExprNodes
,
traverseExpr
},
state
)
{
if
(
!
state
.
scopedSlots
)
{
state
.
scopedSlots
=
{}
}
const
baseName
=
`
${
ownerName
}
-
${
parentName
}
-
${
slotName
}
`
let
componentName
=
baseName
if
(
!
hasOwn
(
state
.
scopedSlots
,
baseName
))
{
state
.
scopedSlots
[
baseName
]
=
0
}
if
(
state
.
scopedSlots
[
baseName
])
{
componentName
=
baseName
+
state
.
scopedSlots
[
baseName
]
}
state
.
scopedSlots
[
baseName
]
++
// parentNode.attr['generic:scoped-slots-' + slotName] = componentName
if
(
!
parentNode
.
attr
.
generic
)
{
parentNode
.
attr
.
generic
=
{}
}
parentNode
.
attr
.
generic
[
slotName
]
=
componentName
// 生成 scopedSlots 文件,包括 json,js,wxml,wxss,还需要更新 owner 的 usingComponents
if
(
!
state
.
files
)
{
state
.
files
=
{}
}
const
extname
=
path
.
extname
(
resourcePath
)
// TODO 需要存储 resourcePath 相关 json
const
templateFile
=
resourcePath
.
replace
(
ownerName
+
extname
,
componentName
+
extname
)
const
templateContent
=
generate
(
traverseExpr
(
returnExprNodes
,
state
),
state
)
state
.
files
[
templateFile
]
=
templateContent
const
jsFile
=
resourcePath
.
replace
(
ownerName
+
extname
,
componentName
+
'
.js
'
)
const
objectProperties
=
[]
if
(
t
.
isObjectPattern
(
paramExprNode
))
{
paramExprNode
.
properties
.
forEach
(
property
=>
{
const
key
=
property
.
key
const
value
=
property
.
value
const
valueObjectProperties
=
[
t
.
objectProperty
(
t
.
identifier
(
'
type
'
),
t
.
nullLiteral
())
]
if
(
t
.
isIdentifier
(
value
))
{
if
(
value
.
name
!==
key
.
name
)
{
state
.
errors
.
add
(
`解构插槽 Prop 时,不支持将
${
key
.
name
}
重命名为
${
value
.
name
}
,重命名后会影响性能`
)
}
}
else
if
(
t
.
isAssignmentPattern
(
value
))
{
valueObjectProperties
.
push
(
t
.
objectProperty
(
t
.
identifier
(
'
default
'
),
value
.
right
))
}
objectProperties
.
push
(
t
.
objectProperty
(
key
,
t
.
objectExpression
(
valueObjectProperties
)))
})
}
else
{
state
.
errors
.
add
(
`目前仅支持解构插槽
${
paramExprNode
.
name
}
,如 v-slot="{ user }"`
)
}
const
jsContent
=
generateJsCode
(
genCode
(
t
.
objectExpression
(
objectProperties
),
true
))
state
.
files
[
jsFile
]
=
jsContent
try
{
// TODO 使用 getPlatformExts 在单元测试报错,改从 state.options.platform 判断
const
{
getPlatformExts
}
=
require
(
'
@dcloudio/uni-cli-shared
'
)
const
styleExtname
=
getPlatformExts
().
style
const
styleFile
=
resourcePath
.
replace
(
ownerName
+
extname
,
componentName
+
styleExtname
)
const
styleContent
=
generateCssCode
(
ownerName
+
styleExtname
)
state
.
files
[
styleFile
]
=
styleContent
}
catch
(
error
)
{
}
// 用于后续修复字节跳动小程序不支持抽象节点导致的问题
const
fixExtname
=
'
.fix
'
const
extFile
=
resourcePath
.
replace
(
ownerName
+
extname
,
componentName
+
fixExtname
)
state
.
files
[
extFile
]
=
`
${
resourcePath
.
replace
(
ownerName
+
extname
,
ownerName
)}
,
${
parentName
}
,
${
componentName
}
,scoped-slots-
${
slotName
}
`
if
(
!
state
.
generic
)
{
state
.
generic
=
[]
}
// 存储,方便后续生成 json
state
.
generic
.
push
(
componentName
)
return
''
}
})
packages/uni-template-compiler/lib/template/generate.js
浏览文件 @
298bb93d
...
...
@@ -65,8 +65,13 @@ function processElement (ast, state, isRoot) {
Object
.
keys
(
ast
.
attr
.
generic
).
forEach
(
scopedSlotName
=>
{
slots
.
push
(
scopedSlotName
)
})
if
(
platformName
===
'
mp-toutiao
'
)
{
// 用于字节跳动小程序模拟抽象节点
ast
.
attr
.
generic
=
`{{
${
JSON
.
stringify
(
ast
.
attr
.
generic
)}
}}`
.
replace
(
/"/g
,
'
\'
'
)
}
else
{
delete
ast
.
attr
.
generic
}
}
if
(
slots
.
length
&&
platformName
!==
'
mp-alipay
'
)
{
// 标记 slots
ast
.
attr
[
'
vue-slots
'
]
=
'
{{[
'
+
slots
.
reverse
().
map
(
slotName
=>
`'
${
slotName
}
'`
).
join
(
'
,
'
)
+
'
]}}
'
}
...
...
packages/webpack-uni-mp-loader/lib/plugin/generate-component.js
浏览文件 @
298bb93d
...
...
@@ -6,7 +6,8 @@ const {
getPlatformExts
}
=
require
(
'
@dcloudio/uni-cli-shared
'
)
const
{
getComponentSet
getComponentSet
,
getJsonFile
}
=
require
(
'
@dcloudio/uni-cli-shared/lib/cache
'
)
const
{
...
...
@@ -66,6 +67,7 @@ module.exports = function generateComponent (compilation) {
const
concatenatedModules
=
modules
.
filter
(
module
=>
module
.
modules
)
const
uniModuleId
=
modules
.
find
(
module
=>
module
.
resource
&&
normalizePath
(
module
.
resource
)
===
uniPath
).
id
const
styleImports
=
{}
const
fixSlots
=
{}
Object
.
keys
(
assets
).
forEach
(
name
=>
{
if
(
components
.
has
(
name
.
replace
(
'
.js
'
,
''
)))
{
...
...
@@ -147,6 +149,57 @@ module.exports = function generateComponent (compilation) {
}
}
}
// 处理字节跳动小程序作用域插槽
const
fixExtname
=
'
.fix
'
if
(
name
.
endsWith
(
fixExtname
))
{
const
source
=
assets
[
name
].
source
()
const
[
ownerName
,
parentName
,
componentName
,
slotName
]
=
source
.
split
(
'
,
'
)
const
json
=
getJsonFile
(
ownerName
)
if
(
json
)
{
const
data
=
JSON
.
parse
(
json
)
const
usingComponents
=
data
.
usingComponents
||
{}
const
componentPath
=
path
.
relative
(
'
/
'
,
usingComponents
[
parentName
])
const
slots
=
fixSlots
[
componentPath
]
=
fixSlots
[
componentPath
]
||
{}
const
slot
=
slots
[
slotName
]
=
slots
[
slotName
]
||
{}
slot
[
componentName
]
=
'
/
'
+
name
.
replace
(
fixExtname
,
''
)
delete
assets
[
name
]
const
jsonFile
=
assets
[
`
${
componentPath
}
.json`
]
if
(
jsonFile
)
{
const
oldSource
=
jsonFile
.
__$oldSource
||
jsonFile
.
source
()
const
sourceObj
=
JSON
.
parse
(
oldSource
)
Object
.
values
(
slots
).
forEach
(
components
=>
{
const
usingComponents
=
sourceObj
.
usingComponents
=
sourceObj
.
usingComponents
||
{}
Object
.
assign
(
usingComponents
,
components
)
})
delete
sourceObj
.
componentGenerics
const
source
=
JSON
.
stringify
(
sourceObj
,
null
,
2
)
jsonFile
.
source
=
function
()
{
return
source
}
jsonFile
.
__$oldSource
=
oldSource
}
const
templateFile
=
assets
[
`
${
componentPath
}${
getPlatformExts
().
template
}
`
]
if
(
templateFile
)
{
const
oldSource
=
templateFile
.
__$oldSource
||
templateFile
.
source
()
let
templateSource
Object
.
keys
(
slots
).
forEach
(
name
=>
{
const
reg
=
new
RegExp
(
`<
${
name
}
(.+?)></
${
name
}
>`
)
templateSource
=
oldSource
.
replace
(
reg
,
string
=>
{
const
props
=
string
.
match
(
reg
)[
1
]
return
Object
.
keys
(
slots
[
name
]).
map
(
key
=>
{
return
`<block tt:if="{{generic['
${
name
.
replace
(
/^scoped-slots-/
,
''
)}
']==='
${
key
}
'}}"><
${
key
}
${
props
}
></
${
key
}
></block>`
}).
join
(
''
)
})
})
templateFile
.
source
=
function
()
{
return
templateSource
}
templateFile
.
__$oldSource
=
oldSource
}
}
}
})
}
if
(
process
.
env
.
UNI_FEATURE_OBSOLETE
!==
'
false
'
)
{
...
...
src/core/runtime/wrapper/util.js
浏览文件 @
298bb93d
...
...
@@ -229,6 +229,11 @@ export function initProperties (props, isBehavior = false, file = '') {
type
:
String
,
value
:
''
}
// 用于字节跳动小程序模拟抽象节点
properties
.
generic
=
{
type
:
Object
,
value
:
null
}
properties
.
vueSlots
=
{
// 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type
:
null
,
value
:
[],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录