2017-12-20 17 views
0

이 모든 소품을 잡아 뷰 JS와 side-nav 구성 요소, 내가 index.php를이 무엇인지 구성 요소

<div class="container"> 
    <side-nav></side-nav> 
</div> 

를 클래스를이 내가

<template> 
<div class="container"> 
    <nav-section name="General"> 
     <nav-item name="Home"> 
      <nav-child name="Dahsboard 1" url="#"></nav-child> 
      <nav-child name="Dahsboard 2" url="#"></nav-child> 
     </nav-item> 

     <nav-item name="Settings"> 
      <nav-child name="Setting 1" url="#"></nav-child> 
      <nav-child name="Setting 2" url="#"></nav-child> 
     </nav-item> 

     <nav-item name="Admin"> 
      <nav-child name="Admin 1" url="#"></nav-child> 
      <nav-child name="Admin 2" url="#"></nav-child> 
     </nav-item> 
    </nav-section> 

    <nav-section name="Data Analysis"> 
     <nav-item name="Data Source"> 
      <nav-child name="Source 1" url="#"></nav-child> 
      <nav-child name="Source 2" url="#"></nav-child> 
     </nav-item> 

     <nav-item name="Visualization"> 
      <nav-child name="Chart 1" url="#"></nav-child> 
      <nav-child name="Chart 2" url="#"></nav-child> 
     </nav-item> 

     <nav-item name="Others"> 
      <nav-child name="Other 1" url="#"></nav-child> 
      <nav-child name="Other 2" url="#"></nav-child> 
     </nav-item> 
    </nav-section> 
</div> 
</template> 

<script> 
    import NavSection from './NavSection.vue' 
    import NavItem from './NavItem.vue' 
    import NavChild from './NavChild.vue' 

    export default { 
     components: { 
      'nav-section':NavSection, 
      'nav-item': NavItem, 
      'nav-child': NavChild, 
     }, 

     data() { 
      return { 

      } 
     }, 

     mounted() { 
      console.log('Component mounted.') 
     }, 


    } 
</script> 
SideNav.vue이 무엇인지입니다 토글

이것은 내가 NavSection.vue이 무엇인지

<template> 
    <section> 
     <h6>{{ name }}</h6> 

     <ul> 
      <slot></slot> 
     </ul> 
    </section> 
</template> 

<script> 
    export default { 
     props: ['name'], 

     data() { 
      return { 

      } 
     } 
    } 

</script> 

이 내가 NavItem.vue에 무슨이다

<template> 
    <li> 
     <a @click="toggleClass">{{ name }}</a> 

     <ul :class="{ 'active': isActive}"> 
      <slot></slot> 
     </ul> 
    </li> 
</template> 

<script> 
    export default { 
     props: ['name'], 

     data() { 
      return { 
       isActive: false, 
       names: [] 
      } 
     }, 

     created() { 
      //this returns all the names in console 
      console.log(this.name) 

      //However, saving it to data->names array, only saves the clicked item 
      this.names = this.name 
     }, 

     methods: { 

      toggleClass() { 
       this.isActive = true 

       //this works, but I want the value to go back to FALSE once I clicked on another item 

       //one way I think it can be accomplished is comparing the cliked item's name prop with all the names 
       //something like this, (refer to created method) 
       this.names.forEach(element => { 
        this.isActive = (element.name == this.names) 
       }) 

      } 
     } 

    } 
</script> 

는 그리고이 각 navSection 여러 navItem을 가지고, 내가 NavChild.vue

<template> 
    <li> 
     <a :href="url">{{ name }}</a> 
    </li> 
</template> 

<script> 
    export default { 
     props: ['name', 'url'], 

     data() { 
      return { 

      } 
     } 
    } 
</script> 

당신이 볼 수 있듯이에서 무엇을하고 각 navItem 여러 navChild 구성 요소가 있습니다. 함수 toggleClass이 에있는 각 앵커 태그를 클릭하여 실행되면 isActive 속성은 해당 항목의 값을 TRUE으로 업데이트해야하고 2는 isActive이 각 섹션 내의 다른 항목을 클릭하면 False으로 돌아갑니다 .

나는 NavItem.vue 파일에 주석으로, 일할 수있는 하나의 생각을했다,하지만 불행히도 내가 잡을 수있는 방법을 찾을 could't 모든 propsname 소품의 NavItem 구성 요소에서 각 항목에 대해. 전달 된 모든 데이터를 특정 prop에 저장하고 저장하는 방법이 있습니까?

코드를 개선하거나 동일한 작업을 수행하는 다른 편리한 방법에 대한 제안은 크게 감사하겠습니다. 해피 코딩!

+0

당신은 하위 구성 요소와 동일하지 않습니다 슬롯을 사용하고 있습니다. 라디오 그룹 동작에는 NavItem과 NavSection 간의 조정이 필요하며 부모/자식으로 설정하지 않으면 어색합니다. –

+0

슬롯을 사용하지 않고 동일한 작업을 수행하는 간단한 jsfiddle 예제는 무엇입니까? 탐색 섹션에 새 항목을 추가 할 때 매우 읽기 쉽고 깨끗하게 만들었 기 때문에 슬롯을 사용했습니다. 그러나 나는 다른 깔끔한 접근법으로도 괜찮을 것입니다. @RoyJ – satancorpse

답변

2

당신은 당신의 접근 방식에서 HTML 지향적이며, Vue 접근법은 모델 지향적입니다. 따라서 HTML에서 모델 구조를 레이아웃하는 대신 원하는 계층 구조로 데이터 모델을 만들어 컴포넌트에서 렌더링하도록해야합니다.

내 앱을 섹션 수준으로 만들었습니다. 그 수준 아래에서 일어나는 일에 관심이 있기 때문입니다. 귀하의 예제의 첫 번째 섹션과 같은 데이터 모델을 만들었습니다.

선택 전용 동작의 트릭은 현재 선택된 값을 보유 할 하나의 변수가 있어야한다는 것입니다. 이 값은 부모가 소유합니다. 각 어린이는 그것이 선택된 가치인지를 말해주는 소품을 얻습니다.

자식이 선택되면 부모가 처리하는 이벤트 (이 경우 the Vue way of child-to-parent communication)를 내 보냅니다.

Vue.component('nav-child', { 
 
    template: '#nav-child-template', 
 
    props: ['name', 'url'] 
 
}); 
 

 
Vue.component('nav-item', { 
 
    template: '#nav-item-template', 
 
    props: ['name', 'children', 'isActive'], 
 
    methods: { 
 
    toggleClass() { 
 
     this.$emit('activate', this.isActive ? null : this.name); 
 
    } 
 
    } 
 
}); 
 

 
new Vue({ 
 
    el: '#nav-section', 
 
    data: { 
 
    activeItem: null, 
 
    items: [{ 
 
     name: 'Home', 
 
     children: [{ 
 
      name: 'Dashboard 1', 
 
      url: '#' 
 
      }, 
 
      { 
 
      name: 'Dashboard 2', 
 
      url: '#' 
 
      } 
 
     ] 
 
     }, 
 
     { 
 
     name: 'Settings', 
 
     children: [{ 
 
      name: 'Setting 1', 
 
      url: '#' 
 
      }, 
 
      { 
 
      name: 'Setting 2', 
 
      url: '#' 
 
      } 
 
     ] 
 
     } 
 
    ] 
 
    }, 
 
    methods: { 
 
    activate(name) { 
 
     this.activeItem = name; 
 
    } 
 
    } 
 
});
.active { 
 
    border: thin solid red; 
 
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script> 
 
<template id="nav-child-template"> 
 
    <li> 
 
     <a :href="url">{{ name }}</a> 
 
    </li> 
 
</template> 
 

 
<template id="nav-item-template"> 
 
    <li> 
 
     <a @click="toggleClass">{{ name }}</a> 
 

 
     <ul :class="{ 'active': isActive}"> 
 
      <li is="nav-child" v-for="child in children" :name="child.name" :url="child.url"></li> 
 
     </ul> 
 
    </li> 
 
</template> 
 

 
<ul id="nav-section"> 
 
    <li is="nav-item" v-for="item in items" :name="item.name" :is-active="activeItem === item.name" :children="item.children" @activate="activate"></li> 
 
</ul>

+0

고마워요!이벤트를 내보내는 대신 항목 이름 배열을 선택한 요소와 단순히 비교하는 비슷한 접근 방식으로 시작한 것입니다. 유일한 문제는 "항목 전환"효과를 얻지 만 토글 링 효과를 비활성화한다는 것입니다. 내가 필요로하는 이유는 꽤 오랜 시간 전에 개발 한 관리자 메뉴가 있었기 때문에 문자 그대로 10 초의 작업이었던 jQuery를 사용했기 때문입니다. "self toggling"기능을 손상시키지 않고 동일한 것을 달성 할 수있는 방법을 생각해 볼 수 있습니까? 내가 바보 같으면 신경 쓰지 마라. Vue의 초보자. – satancorpse

+1

물론, 코드를 업데이트했습니다. 현재 항목이 이미 활성화되어 있으면 현재 항목 대신 null을 내 보내야합니다. –

+0

귀하의 의견은 문제를 해결하고 내 이해를 풍부하게했습니다. 희망 누군가가 너무 유용 찾을 수 있습니다 :) – satancorpse