在使用 vue jsx 写法 完成 el-upload uploadList插槽遇到问题
//模板使用没问题
<div slot="file" slot-scope="{file}">
<el-link>{{file}}el-link>
div>
//jsx尝试几种皆无法实现
//1.
render(h){
return
<el-upload>
<div
slot={'file'}
{...{
scopedSlots: {
file: scope => {
<el-link> {scope}el-link>
}
}
}
}
>
div>
el-upload>
}
//2.
render(h){
return
<el-upload>
<div
v-slots={{
file: () => (
<el-link> {scope}el-link>
)}}
>
div>
el-upload>
}
//3.
render(h){
return h('el-upload',
h('div',{
scopedSlots:{
file: props =>{
return <el-link>hhhhel-link>
}
},
})
)
}
以上是我能想到的替代方法皆不能实现,还请大家指出问题所在,和解决办法 感谢
let scopedSlots = {
//defaul 默认具名插槽
file: props => {
return (
// props 就相当于 slot-scope="{title}" 里面的值
<div class="preview_img_list" onClick={e=> this.previewImgList(img_arr,props.file.url)}>
<img src={props.file.url}/>
</div>
);
}
}
<el-upload
action=""
{...{ scopedSlots }}>
</el-upload>
引用chatGPT作答,根据您提供的代码,第一个尝试的实现方式存在一些语法错误。可以尝试修改如下:
render(h) {
return (
<el-upload>
<div slot="file" slot-scope="{ file }">
<el-link>{file.name}</el-link>
</div>
</el-upload>
);
}
在第一个尝试的代码中,使用了 scopedSlots,但是没有返回任何内容。应该在 scopedSlots 中的回调函数中返回需要渲染的内容。
第二个尝试中,您使用了 v-slots 的语法,但是 v-slots 是 Vue 3 中的语法,不适用于 Vue 2。如果您正在使用 Vue 2,应该使用 scopedSlots。
第三个尝试中,您的 h 函数的参数有误。您需要将 scopedSlots 作为 h 函数的第三个参数,而不是在 div 中使用。可以尝试如下代码:
render(h) {
return h(
"el-upload",
{},
[
h("div", {
scopedSlots: {
file: (props) => h("el-link", props.file.name),
},
}),
]
);
}
这样应该就能够在 Vue JSX 中实现 el-upload 的 uploadList 插槽了。
不知道你这个问题是否已经解决, 如果还没有解决的话:3个List组件内容差不多,不同的在于背景色和名称,关于里面的settings数据,下面会讲到
<template>
<div class="box" @click="onItemClick(settings.clickFunc,settings)">{{settings.name}}--{{settings.age}}--{{settings.addr}}</div>
</template>
<script>
export default{
name:"List01",
props:{
settings:{
type:Object,
equired:true,
default:()=>{}
}
},
data(){
return{
}
},
methods:{
onItemClick(func,settings){
if(func && settings){
alert(`${settings.name}--${settings.age}--${settings.addr}`)
return false;
}
}
}
}
</script>
<style scoped="scoped">
.box{
width: 500px;
height: 50px;
background-color: #DC4D41;
color: #fff;
text-align: center;
line-height: 50px;
border-radius:9px;
margin:10px;
}
</style>
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
您好,您的第三种方法已经很接近正确的写法了,但是还缺少一个关键的属性slot
,以下是正确的 JSX 写法:
render(h) {
return (
<el-upload>
<div slot="file" scopedSlots={
{
file: (props) => <el-link>{props.file.name}</el-link>
}
}></div>
</el-upload>
)
}
需要注意的有以下几点:
scopedSlots
是一个对象,它的键是插槽的名称,对应模板中的slot
属性的值,值为一个函数,接收该插槽的数据对象。<el-link>
组件,props.file
表示当前文件的信息。<div>
标签上添加 slot
属性,值为 file
。希望能够帮到您。
如果我的回答解决了您的问题,请采纳!
render(h) {
return (
{scope.file.name}
);
}
render(h) {
return (
{props.file.name}
);
}
render(h) {
return h('el-upload', [
h('div', {
scopedSlots: {
file: props => h('el-link', {}, props.file.name)
}
})
]);
}
该答案引用ChatGPT的部分内容:
在你提供的代码中,第二个示例中似乎有一些语法错误,正确的写法应该是这样的:
render(h){
return (
<el-upload>
<div v-slot:file="{ file }">
<el-link>{file.name}</el-link>
</div>
</el-upload>
);
}
在这个示例中,我们使用了 Vue 3 中的新插槽语法 v-slot,并且使用了对象解构来获取 file 属性。我们也使用了 JSX 中的花括号来嵌入 JavaScript 表达式,以便在插槽中使用 file.name。
另外两个示例也有一些问题。在第一个示例中,你应该在 file 插槽中返回一个 VNode,否则插槽内容将为空。正确的写法应该是这样的:
render(h){
return (
<el-upload>
<div
slot={'file'}
{...{
scopedSlots: {
file: scope => {
return <el-link>{scope.file.name}</el-link>
}
}
}}
></div>
</el-upload>
);
}
在第三个示例中,你的 h 函数调用中有一个额外的逗号,而且你在 scopedSlots 中应该使用 props,而不是 scope。正确的写法应该是这样的:
render(h){
return h('el-upload', {}, [
h('div', {
scopedSlots: {
file: props => {
return h('el-link', {}, props.file.name)
}
}
})
]);
}
这应该能够解决你的问题。记得在使用 Vue JSX 时,需要确保你已经正确地导入了 vue 和 @vue/babel-plugin-jsx。