Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

组件嵌套slot问题 #427

Open
yun77op opened this issue May 6, 2018 · 14 comments
Open

组件嵌套slot问题 #427

yun77op opened this issue May 6, 2018 · 14 comments
Labels
wontfix This will not be worked on

Comments

@yun77op
Copy link

yun77op commented May 6, 2018

[组件嵌套]

问题复现步骤:

<tabs>
  <tab name="First tab">This is the content of the first tab</tab>
  <tab name="Second tab">This is the content of the second tab</tab>
</tabs>

生成的模版是

// index.js
<template data="{{...$root[$p], $root}}" is="{{'data-v-7055edb2-default-2'}}"></template>

// tabs slot
<template name="data-v-7055edb2-default-2">
  <template data="{{...$root[$kk+'0'], $root, $slotdefault:'data-v-7055edb2-default-0'}}" is="Tab$c86e9360"></template>
  <template data="{{...$root[$kk+'1'], $root, $slotdefault:'data-v-7055edb2-default-1'}}" is="Tab$c86e9360"></template>
</template>

结果tab组件接收到的数据为空

问题就出在$root[$p]这里,看了mpvue-template-compiler,把L4583行的

attrsMap['data'] = "{{...$root[$p], $root}}";

改成

attrsMap['data'] = "{{...$root[$k], $root}}";

就可以

所以我就不明白了,是我使用姿势不对,还是确实是mpvue本身有问题

具体demo在https://github.com/yun77op/vue-wechat-web/blob/master/src/pages/index/index.vue

@F-loat
Copy link
Contributor

F-loat commented May 8, 2018

感觉是 mpvue 的问题,@anchengjian

@shawtung
Copy link

这问题我昨晚也遇到了, 看生成的模板排查到凌晨也定位到了这里, 原来已经有issue了😖😖.
借宝地一问, 组件内input闪烁的问题, 下个release是否打算修复~ @F-loat

@Stupidism
Copy link
Contributor

Stupidism commented May 12, 2018

实测无误 @F-loat 上下文为:


  convertComponent: function convertComponent (ast, components, slotName) {
    var attrsMap = ast.attrsMap;
    var tag = ast.tag;
    var mpcomid = ast.mpcomid;
    var slots = ast.slots;
    if (slotName) {
      attrsMap['data'] = "{{...$root[$k], $root}}";
      attrsMap['is'] = "{{" + slotName + "}}";
    } else {
      var slotsName = getSlotsName(slots);
      var restSlotsName = slotsName ? (", " + slotsName) : '';
      attrsMap['data'] = "{{...$root[$kk+" + mpcomid + "], $root" + restSlotsName + "}}";
      attrsMap['is'] = components[tag].name;
    }
    return ast
  }

PR 已提交 #458,
第一次接触mpvue源码, 还不熟悉, 只修改了我能用github搜到的相关的一处代码和两处测试

@Stupidism
Copy link
Contributor

@shawtung input闪烁的问题是双向绑定机制的问题, 我弄了个workaround #241 (comment)

@XieShangxu
Copy link

这个修改会带来另外一个问题。具体Demo如下:

pages/index/index.vue

<template>
  <div class="container">
    <child>
      <view>{{product.desc}}</view>
    </child>
    <child>
      <flag :text="product.name" />
    </child>
  </div>
</template>

<script>
import child from '@/components/child'
import flag from '@/components/flag'

export default {
  data () {
    return {
      product: {
        desc: '',
        name: ''
      }
    }
  },

  components: {
    child,
    flag
  },

  methods: {
  },

  created () {
    setTimeout(() => {
      this.product.desc = 'desc'
      this.product.name = 'name'
    }, 2000)
  }
}
</script>

child.vue

<template>
  <div>
    <div class="child">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {}
  }
}
</script>

flag.vue

<template>
  <div class="text">{{text}}</div>
</template>

<script>
export default {
  props: ['text'],
  data () {
    return {}
  }
}
</script>

在fix之前,会只显示"desc",这是已知问题。
在fix之后,会只显示"name",原来正常显示的"desc"不显示了。

希望能看看这个问题。谢谢

@Stupidism
Copy link
Contributor

@XieShangxu 那你试试这样?

      attrsMap['data'] = "{{...$root[$k], ...$root[$p], $root}}";

@XieShangxu
Copy link

@Stupidism 还是不行,跟fix之前是一样的

@zsodur
Copy link

zsodur commented May 18, 2018

@XieShangxu 这样
attrsMap['data'] = "{{...$root[$p],...$root[$k] ,$root}}";

aOrz added a commit that referenced this issue May 19, 2018
@Stupidism
Copy link
Contributor

@XieShangxu 这样行了吗?

@shawtung
Copy link

@Stupidism 先p再k是对的, 我测试过了. 先k再p导致($k, $kk, $p)变成了其父组件的值, 相当于这一组件层级往上移了一级, 导致它里面的组件也会错位, 就找不到相应的组件data了.
所以很尴尬的是, 1.0.12版本的template-compiler改动的那一行代码, 其实还是错的.

@F-loat
Copy link
Contributor

F-loat commented May 21, 2018

@shawtung 所以是应该改成什么?这里组件嵌套可能会导致差异,目前的改法有嵌套时应该是正确的,当时有测过

@shawtung
Copy link

shawtung commented May 21, 2018

@F-loat
改成这样: attrsMap['data'] = "{{...$root[$p], ...$root[$k] ,$root}}";

我的场景是把组件B放进组件A的slot里, 1.0.12把"{{...$root[$p], $root}}"改成"{{...$root[$k], $root}}"之后, 不但我这个场景里组件B依然读不到它自己的数据, 连最基本的<text slot="children">{{confirmBtnText}}</text>这种用法也会失效.

改成开头说的那样之后, 就都OK了.

不过我还没有试组件循环引用的场景... 我再去试试.

@steinslin
Copy link

steinslin commented May 21, 2018

这个好像真不好改

<child>
  <div>{{product.desc}}</div>
</child>

这里编译后的slot用的作用域应该是父的,所以要$p
下面这种情况是用本身的作用域

<child>
  <flag :text="product.name" />
</child>

这里的slot是个组件,flag组件在渲染时要用本身的作用域,传入应该是$k,但是两个都依赖同一个template

<template data="{{...$root[$p], $root}}" is="{{$slotdefault || 'default'}}"></template>

@shawtung 按照你的改法也不行吧,当前的作用域会覆盖父的作用域吧,这样还是可能会有问题

@cc616
Copy link

cc616 commented Jul 2, 2019

并没有解决slot的问题吧,依旧还是存在
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

9 participants