내용이 있는 경우에만 슬롯 표시
내용이 있는 슬롯만 표시할 수 있는 방법이 있나요?
예를 들어, 나는 심플한 빌딩을 만들고 있다.Card.vue
다음 내용이 있는 경우에만 바닥글을 표시합니다.
템플릿:
<template>
<div class="panel" :class="panelType">
<div class="panel-heading">
<h3 class="panel-title">
<slot name="title">
Default Title
</slot>
</h3>
</div>
<div class="panel-body">
<slot name="body"></slot>
<p class="category">
<slot name="category"></slot>
</p>
</div>
<div class="panel-footer" v-if="hasFooterSlot">
<slot name="footer"></slot>
</div>
</div>
</template>
스크립트:
<script>
export default {
props: {
active: true,
type: {
type: String,
default: 'default',
},
},
computed: {
panelType() {
return `panel-${this.type}`;
},
hasFooterSlot() {
return this.$slots['footer']
}
}
}
</script>
표시 내용:
<card type="success"></card>
위 구성요소는 바닥글을 포함하지 않으므로 렌더링되지 않아야 하지만 렌더링됩니다.
사용해보았습니다.this.$slots['footer']
단, 정의되지 않은 값이 반환됩니다.
누구 팁 있는 사람?
다음 사이트에서 입수할 수 있습니다.
this.$slots.footer
이게 효과가 있을 거야
hasFooterSlot() {
return !!this.$slots.footer;
}
예.
확인하셔야 합니다vm.$slots
그리고 또vm.$scopedSlots
할 수 있을 것 같아요.
hasSlot (name = 'default') {
return !!this.$slots[ name ] || !!this.$scopedSlots[ name ];
}
나는 비슷한 문제에 부딪혔지만 광범위한 코드 베이스에 걸쳐서 원자 설계 구조화된 컴포넌트를 만들 때 쓰는 것은 피곤할 수 있다.hasSlot()
TDD에 관한 한 항상 테스트하는 또 하나의 방법...그렇게 말하면, 당신은 언제나 원초적인 논리를 넣을 수 있습니다.v-if
특히 새로운 개발자가 코드 구조를 체크할 경우 템플릿이 어수선하고 읽기 어려울 수 있습니다.
부모를 제거하는 방법을 알아내는 임무를 맡았습니다div
슬롯이 제공되지 않은 경우 슬롯의 수
문제:
<template>
<div>
<div class="hello">
<slot name="foo" />
</div>
<div class="world">
<slot name="bar" />
</div>
</div>
</template>
//instantiation
<my-component>
<span slot="foo">show me</span>
</my-component>
//renders
<div>
<div class="hello">
<span slot="foo">show me</span>
</div>
<div class="world"></div>
</div>
보다시피, 문제는 컴포넌트 작성자가 필요없다고 판단했을 때 스타일링 문제를 제공할 수 있는 거의 '불필요한' div를 가지고 있다는 것입니다.bar
슬롯을 클릭합니다.
물론 갈 수 있다<div v-if="$slots.bar">...</div>
또는<div v-if="hasBar()">...</div>
하지만 내가 말했듯이, 그것은 지루해지고 결국 읽기가 더 어려워질 수 있다.
솔루션
제 해결책은 일반적인 것을 만드는 것이었습니다.slot
주변 div가 있는 슬롯을 만든 컴포넌트...를 참조해 주세요.
//slot component
<template>
<div v-if="!!$slots.default">
<slot />
</div>
</template>
//usage within <my-component/>
<template>
<div>
<slot-component class="hello">
<slot name="foo"/>
</slot-component>
<slot-component class="world">
<slot name="bar"/>
</slot-component>
</div>
</template>
//instantiation
<my-component>
<span slot="foo">show me</span>
</my-component>
//renders
<div>
<div class="hello">
<span>show me</span>
</div>
</div>
저는 이 아이디어를 시도할 때 유스케이스 문제에 부딪혔고, 때로는 이 접근방식의 이점을 위해 마크업 구조를 변경해야 했습니다.이 방법을 사용하면 각 컴포넌트 템플릿 내에서 작은 슬롯체크를 할 필요가 줄어듭니다.이 컴포넌트는 이 컴포넌트를<conditional-div />
컴포넌트...
또, 어트리뷰트를 적용하는 것도 주의할 필요가 있습니다.slot-component
인스턴스화(<slot-component class="myClass" data-random="randomshjhsa" />
Atribut이 contain div of the contained div로 흘러들어가기 때문에)는 괜찮습니다.slot-component
템플릿입니다.
이게 도움이 됐으면 좋겠다.
UPDATE 이 플러그 인을 썼기 때문에 Import의 필요성custom-slot
각 컨슈머 컴포넌트의 컴포넌트는 더 이상 필요하지 않으며 main.js 인스턴스화에 Vue.use(SlotPlugin)만 입력하면 됩니다.(아래 참조)
const SLOT_COMPONENT = {
name: 'custom-slot',
template: `
<div v-if="$slots.default">
<slot />
</div>
`
}
const SLOT_PLUGIN = {
install (Vue) {
Vue.component(SLOT_COMPONENT.name, SLOT_COMPONENT)
}
}
export default SLOT_PLUGIN
//main.js
import SlotPlugin from 'path/to/plugin'
Vue.use(SlotPlugin)
//...rest of code
즉, 이것은 인라인으로 실시합니다.
<template lang="pug">
div
h2(v-if="$slots.title")
slot(name="title")
h3(v-if="$slots['sub-title']")
slot(name="sub-title")
</template>
CSS는 이를 대폭 간소화합니다.다음 코드를 사용하여 voila!
.panel-footer:empty {
display: none;
}
다음은 Vue 3 구성 API의 솔루션입니다.
<template>
<div class="md:grid md:grid-cols-5 md:gap-6">
<!-- Here, you hide the wrapper if there is no used slot or empty -->
<div class="md:col-span-2" v-if="hasTitle">
<slot name="title"></slot>
</div>
<div class="mt-5 md:mt-0"
:class="{'md:col-span-3': hasTitle, 'md:col-span-5': !hasTitle}">
<div class="bg-white rounded-md shadow">
<div class="py-7">
<slot></slot>
</div>
</div>
</div>
</div>
</template>
<script>
import {ref} from "vue";
export default {
setup(props, {slots}) {
const hasTitle = ref(false)
// Check if the slot exists by name and has content.
// It returns an empty array if it's empty.
if (slots.title && slots.title().length) {
hasTitle.value = true
}
return {
hasTitle
}
}
}
</script>
처음에는 https://stackoverflow.com/a/50096300/752916이 작동한다고 생각했지만, $1200 때문에 좀 더 확장해야 했습니다.슬롯은 반환값에 관계없이 항상 truthy한 함수를 반환합니다.이것이 나의 해결책이지만, 이 질문에 대한 진짜 답은 "이렇게 하는 것은 반작용이며 가능하면 피해야 한다"는 결론에 도달했다.예를 들어 슬롯에 넣을 수 있는 별도의 바닥글 구성 요소를 만듭니다.
해키 솔루션
hasFooterSlot() {
const ss = this.$scopedSlots;
const footerNodes = ss && ss.footer && ss.footer();
return footerNodes && footerNodes.length;
}
베스트 프랙티스(바닥글에 도움이 되는 컴포넌트)
const panelComponent = {
template: `
<div class="nice-panel">
<div class="nice-panel-content">
<!-- Slot for main content -->
<slot />
</div>
<!-- Slot for optional footer -->
<slot name="footer"></slot>
</div>
`
}
const footerComponent = {
template: `
<div class="nice-panel-footer">
<slot />
</div>
`
}
var app = new Vue({
el: '#app',
components: {
panelComponent,
footerComponent
},
data() {
return {
name: 'Vue'
}
}
})
.nice-panel {
max-width: 200px;
border: 1px solid lightgray;
}
.nice-panel-content {
padding: 30px;
}
.nice-panel-footer {
background-color: lightgray;
padding: 5px 30px;
text-align: center;
}
<script src="https://unpkg.com/vue@2.6.11/dist/vue.min.js"></script>
<div id="app">
<h1>Panel with footer</h1>
<panel-component>
lorem ipsum
<template #footer>
<footer-component> Some Footer Content</footer-component>
</template>
</panel-component>
<h1>Panel without footer</h1>
<panel-component>
lorem ipsum
</panel-component>
</div>
제가 제대로 이해했으면 좋겠어요. " " " " " " " " " " " " " " " " " " " 를 하면 안 요?<template>
태그: 슬롯이 비어 있는 경우 렌더링되지 않습니다.
<slot name="foo"></slot>
다음과 같이 사용합니다.
<template slot="foo">
...
</template>
@Bert 답변은 다음과 같은 동적 템플릿에서는 작동하지 않는 것 같습니다.<template v-slot:foo="{data}"> ... </template>
을 사용하게 되었습니다. 결국 다음을 사용하게 되었습니다.
return (
Boolean(this.$slots.foo) ||
Boolean(typeof this.$scopedSlots.foo == 'function')
);
테스트 완료
vue 3에서는 다음과 같이 동작합니다.
먼저 onMounted를 사용하여 값을 가져오고 다음으로 onUpdate를 사용하여 값을 업데이트합니다.
<template>
<div v-if="content" class="w-1/2">
<slot name="content"></slot>
</div>
</template>
<script>
import { ref, onMounted, defineComponent, onUpdated } from "vue";
export default defineComponent({
setup(props, { slots }) {
const content = ref()
onMounted(() => {
if (slots.content && slots.content().length) {
content.value = true
}
})
onUpdated(() => {
content.value = slots.content().length
console.log('CHECK VALUE', content.value)
})
})
</script>
언급URL : https://stackoverflow.com/questions/44077277/only-show-slot-if-it-has-content
'programing' 카테고리의 다른 글
Clojure에서 GUI를 실행하는 가장 좋은 방법은 무엇입니까? (0) | 2022.08.29 |
---|---|
Vuex는 변환 핸들러 외부의 vuex 저장소 상태를 변환하지 않음 - Vuetify (0) | 2022.08.29 |
exec 출력을 버퍼 또는 파일로 재연결 (0) | 2022.08.29 |
Eclipse에서 TODO 태그 찾기 (0) | 2022.08.29 |
VeValidate 'required_if:' 규칙 확인 (0) | 2022.08.29 |