[TIL] 221230

EllaDev·2022년 12월 30일
0

Today I Learn

목록 보기
7/13

이슈 : 공통 컴포넌트화

  • 문제1 : Modal Common에서 버튼의 액션을 부모가 제어할 수 없다. 그럼 부모에서 관련 데이터값을 모두 가지고 있어야한다. 그게… 복잡한 구현이 될 것이므로 다르게 좀더 깔끔하게 가져다 쓸 수있으려면….은?
  • 해결방안1 : 데이터만 갖는 컨테이너 파일를 만들어서 거기서 모달을 호출하는 방식으로 해결한다.
    <!-- @/pages/index.vue **/ -->
    <template>
      <div>
        <BaseButtonsText
          v-if="userStore.user"
          :label="'Create Post'"
          :theme="'primary-yellow'"
          @click="createModal = !createModal"
        />
    
        <PostCreate
          :is-open="createModal"
        />
      </div>
    </template>
    <script>
    export default defineComponent({
      components: {
        BaseButtonsText,
        PostCreate
        // BoxModalsModalCreatePost
      },
      setup() {
    	const handleOnOpenModalPostCreate = () => {
          $vfm.toggle('modal-create-post-test', true).then(hook => {
            console.log(hook)
          })
          console.log($vfm.get('modal-create-post-test'))
        }
        return { createModal, handleOnOpenModalPostCreate }
      }
    })
    </script>
    
    <!-- @/component/box/modal/PostCreate/index.vue -->
    <template>
      <div></div>
    </template>
    
    <script lang='ts'>
    
    export default defineComponent({
      name: 'PostCreate',
      props: {
        isOpen: {
          required: true,
          type: Boolean
        }
      },
      setup(props) {
        const isOpen = toRefs(props).isOpen
    
        watch(isOpen,(current)=> {
          if (current) handleOnCreatePostModal()
        })
    
        const handleOnCreatePostModal = () => {
          $vfm.show({
            component: ModalCommon,
            bind: {
              name: 'modalCommon',
              showCloseBtn: true
            },
            on: {...},
            slots: {
              title: '포스트작성',
              contents: { component: PostCreateContent },
              actions: {
                component: BaseButtonsText
              }
            }
          })
        }
        return{}
      }
    })
    </script>
    
    <!-- @/component/base/modal/ModalCommon.vue **/ -->
    <template>
      <vue-final-modal
        v-slot="{ params, close }"
        v-bind="$attrs"
        classes="modal-container"
        content-class="modal-content"
      >
        <div v-if="slots.title || $attrs.showCloseBtn" class="modal-header">
          <h4 v-if="slots.title" class="title">
            <slot name="title"></slot>
          </h4>
    
          <div v-if="$attrs.showCloseBtn" class="close-wrap" @click="close">
            <BaseButtonsIcon
              :icon="{ type: 'outline', name: 'close-extend' }"
              class="btn-close"
            />
          </div>
        </div>
    
        <ScrollContainer
          v-if="slots.contents"
          class="modal-contents modal-scroll-container"
        >
          <slot name="contents" :params="params"></slot>
        </ScrollContainer>
    
        <div v-if="slots.btnCancel || slots.btnConfirm || slots.btnOptional" class="modal-actions">
          <slot name="btnCancel" ></slot>
          <slot name="btnConfirm" ></slot>
          <slot name="btnOptional" ></slot>
        </div>
      </vue-final-modal>
    </template>
    <script lang="ts">
    import { defineComponent , useSlots } from 'vue'
    
    export default defineComponent({
      name: 'ModalCommon',
      inheritAttrs: false,
      emits: {
        confirm: (_evt: any) => true,
        cancel: (_evt: any) => true
      },
      setup() {
        const slots = useSlots()
    
        return { slots }
      }
    })
    </script>
  • 해결방안2: CustomModal 형태로 여기서 제공하는 것들을 커스터마이징해서 만들어서 사용한다. Recommended usage
profile
Frontend Developer

0개의 댓글