如何使用vue3获取插槽中的HTMLElements?
P粉794177659
P粉794177659 2023-09-01 17:57:52
[Vue.js讨论组]
<p>当我尝试开发 Layer 组件时发生了一些事情。代码如下:</p> <p><em>// Wrapper.vue</em></p> <pre class="brush:php;toolbar:false;">&lt;template&gt; &lt;slot v-bind=&quot;attrs&quot;&gt;&lt;/slot&gt; &lt;/template&gt; &lt;script lang=&quot;ts&quot; setup&gt; import { defineProps, ref, watch, useAttrs, onMounted, onUnmounted, getCurrentInstance, } from &quot;vue&quot;; const props = defineProps({ name: { type: String, default: &quot;&quot; }, zIndex: { type: Number, default: 0 }, }); const attrs = useAttrs(); const inst = getCurrentInstance(); const observer = ref&lt;MutationObserver | null&gt;(null); watch( () =&gt; [props.zIndex, props.name], () =&gt; { setBrothersAttrs(); } ); onMounted(() =&gt; { let el = inst?.vnode.el; if (el) { if (!observer.value) observer.value = new MutationObserver(setBrothersAttrs); observer.value.observe(el.parentElement, { childList: true }); } setBrothersAttrs(); }); onUnmounted(() =&gt; { if (observer.value) observer.value.disconnect(); }); const setBrothersAttrs = () =&gt; { let el = inst?.vnode.el; let children = el?.parentElement?.children; if (el &amp;&amp; children) { for (let i = 0; i &lt; children.length; i++) { let bro = children[i]; if (bro === el) continue; bro.style.zIndex = props.zIndex; } } }; &lt;/script&gt;</pre> <p><em>// Test.vue</em></p> <pre class="brush:php;toolbar:false;">&lt;template&gt; &lt;div class=&quot;test&quot;&gt; &lt;Wrapper name=&quot;wrapper1&quot; :z-index=&quot;1&quot;&gt; &lt;img class=&quot;picture1&quot; /&gt; &lt;div class=&quot;inner&quot;&gt; &lt;Wrapper name=&quot;wrapper2&quot; :z-index=&quot;2&quot;&gt; &lt;img class=&quot;picture2&quot; /&gt; &lt;/Wrapper&gt; &lt;/div&gt; &lt;Wrapper name=&quot;wrapper3&quot; :z-index=&quot;3&quot;&gt; &lt;img class=&quot;picture3&quot; /&gt; &lt;/Wrapper&gt; &lt;/Wrapper&gt; &lt;/div&gt; &lt;/template&gt; &lt;script lang=&quot;ts&quot; setup&gt; import Wrapper from &quot;./Wrapper.vue&quot;; &lt;/script&gt;</pre> <p><em>// HTML 格式的结果:</em></p> <pre class="brush:php;toolbar:false;">&lt;div class=&quot;test&quot;&gt; &lt;img class=&quot;picture1&quot; style=&quot;z-index: 1&quot; /&gt;&lt;!-- if no wrapper3, &quot;z-index: 3&quot; --&gt; &lt;div class=&quot;inner&quot; style=&quot;z-index: 1&quot;&gt; &lt;img class=&quot;picture2&quot; style=&quot;z-index: 2&quot; /&gt; &lt;/div&gt; &lt;img class=&quot;picture3&quot; style=&quot;z-index: 1&quot; /&gt;&lt;!-- if no wrapper3, &quot;z-index: 3&quot; --&gt; &lt;/div&gt;</pre> <blockquote> <p>如上面的代码,组件Wrapper是一个空组件。其目的是在 slot["default"] 中设置 HTMLElements 的 z-index。</p> </blockquote> <p>不幸的是,我在 useSlots()["default"] 中找不到子元素。 <strong>所以我尝试让一个突变观察者来观察父级的childList。</strong></p> <p>它单独工作得很好(<em>就像示例中的图片1和图片2</em>)。 <strong>但是当多个 Wrapper 包裹在一起时,它会相互覆盖(<em>就像示例中的图片3,由wrapper3设置的picture3的z索引被wrapper1覆盖)。</strong>这意味着它们共享相同的父级,以便父级的子级始终相同。</p> <p>所以现在问题又变成了“<strong>如何在槽中获取HTMLElements</strong>”......任何vuejs大师都可以帮我吗?</p>
P粉794177659
P粉794177659

全部回复(1)
P粉714890053

使用 Vue 渲染函数可以更简单地完成:渲染槽

const { createApp, h } = Vue;

const Wrapper = {
  props:  {
    name: { type: String, default: "" },
    zIndex: { type: Number, default: 0 },
  },
  setup(props, { slots }) {
    let children = slots.default();
    if (children) {
      for (let i = 0; i < children.length; i++) {
        children[i].props.style = `z-index: ${props.zIndex}`;
      }
    }  
    return () => slots.default()
  }
}

const App = { 
  components:  { Wrapper }
}

const app = createApp(App)
const vm = app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
<div id="app" v-cloak>
   <div class="test">
   Test
    <Wrapper name="wrapper1" :z-index="1">
      <img class="picture1" />
      <div class="inner">
        <Wrapper name="wrapper2" :z-index="2">
          <img class="picture2" />
        </Wrapper>
      </div>
      <Wrapper name="wrapper3" :z-index="3">
        <img class="picture3" />
      </Wrapper>
    </Wrapper>
  </div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号