2017-01-07 5 views
1

Следующая проблема:Как получить доступ к содержимому слота в другом дочернем компоненте

У меня есть компонент Vue.js, который опирается на DOM своего родителя. Но в тот момент, когда пропущена передача, она (this.$el) не определена, вероятно, потому, что она еще не установлена.

файл шаблона вю моего компонента выглядит следующим образом:

<template> 
    <md-card> 
    <md-card-content> 
     <ol> 
     <li v-for="item in headings(content)"> 
      <a :href="`#${item.id}`">{{ item.name }}</a> 
     </li> 
     </ol> 
    </md-card-content> 
    </md-card> 
</template> 
<script> 
    export default { 
    props: ['content'], 
    methods: { 
     headings(content) { 
     // DOM element is used 
     // At this moment, `content` is undefined 
     }, 
    }, 
    }; 
</script> 

Компонент, который использует один выше, включает этот кусок кода:

<article-index :content="this.$el"></article-index> 

Я думал ждать родительского компонента, чтобы быть но таким образом я не могу сохранить шаблон, как указано выше, потому что он всегда будет пытаться получить доступ к методу (или переменной) мгновенно.

Как это решить?

Edit:

<template> 
    <div class="content"> 
    <div class="left"><article-index :content="this.$el"></article-index></div> 
    <div class="article"><slot></slot></div> 
    <div class="right"><slot name="aside"></slot></div> 
    </div> 
</template> 

Вот шаблон родительского компонента. Единственное, что мне действительно нужно, это div .article или содержимое слота.

+0

Почему вы проходя 'это $ el' в пропеллер.? – Saurabh

+0

@saurabh Поскольку мне нужно получить доступ к элементу DOM, чтобы выполнить execute querySelector. Как бы вы это сделали? – 22samuelk

+0

Я попытаюсь передать переменную vue там, вы можете добавить свой HTML родительский DOM, а также указать, что именно вы хотите получить. – Saurabh

ответ

0

С помощью @saurabh я смог узнать, что я могу получить доступ к слоту, который я передаю непосредственно ребенку.

Но основная проблема осталась: в этот момент компонент не был смонтирован.

Итак, я изменил способ доступа к пройденному слоту.

Вместо родительского элемента я теперь передаю слот по умолчанию в родительском компоненте.

С slots опорой является массив из VNode объектов, я не могу использовать какие-либо методы DOM на них. Но так как свойство elm VNode содержит фактический элемент DOM, я использую это вместо этого.

Опять же, проблема: он еще не установлен.

Именно поэтому v-for теперь указывает на данные headings, а не на удаленный метод. Вместо этого я добавил метод mounted(), который автоматически вызывается Vue при установке компонентов.

Когда этот метод вызван, слот установлен, поэтому я могу получить доступ к их свойствам elm. В моем случае есть несколько слотов по умолчанию, поэтому в массиве slots имеется более одного элемента. Чтобы дать возможность вызвать конкретный номер querySelectorAll, я добавил несколько функциональных заклинаний Array.

Редактировать: Так как имеет смысл напрямую обращаться к querySelector на визуализированном контенте, теперь я передаю атрибут $refs вместо $slots. Даже если мне нужно только $refs.article, если я передам его напрямую, я получу неопределенный. Пройдя this.$refs в целом, дочерний компонент может получить доступ к артикулу, даже если он не существует до установки.

Так что это мой новый родительский компонент:

<template> 
    <div class="content"> 
    <div class="left"> 
     <article-index :refs="this.$refs"></article-index> 
    </div> 
    <div class="article" ref="article"><slot></slot></div> 
    <div class="right"><slot name="aside"></slot></div> 
    </div> 
</template> 

и ребенок:

<template> 
    <md-card> 
    <md-card-content> 
     <ol> 
     <li v-for="item in headings"> 
      <a @click="scroll(item.id)" :href="hash"> 
      {{ item.name }} 
      </a> 
     </li> 
     </ol> 
    </md-card-content> 
    </md-card> 
</template> 
<script> 
    import dashify from 'dashify'; 

    export default { 
    props: ['refs'], 
    data:() => ({ 
     headings: {}, 
     hash: location.hash, 
    }), 
    methods: { 
     scroll(to) { 
     this.refs.article.querySelector(`#${to}`).scrollIntoView(); 
     }, 
    }, 
    mounted() { 
     const elements = Array.from(this.refs.article.querySelectorAll('h2')); 
     elements.forEach(node => node.id = dashify(node.innerText)); 

     this.headings = elements.map(node => ({ 
     name: node.innerText, 
     id: node.id, 
     })); 
    }, 
    }; 
</script> 
2

Вы можете получить его с помощью this.$slots, в функции монтирования родительского компонента вы можете получить доступ к this.$slots и назначить его некоторой переменной, которая может быть передана компоненту article-index.

После кода печатает переданные слоты:

Vue.component('wrapper', { 
    name: 'Wrapper', 
    template: `<div><slot></slot></div>`, 
    mounted() { 
    this.$slots.default.forEach(vnode => { 
     console.log(vnode) 
    }) 
    } 
}) 

Пример скрипку here.

+0

Так что я не могу использовать такие методы, как querySelector, так? – 22samuelk

+0

Вы можете получить доступ к HTML-файлу 'vnode', используя' vnode.elm'. http://jsfiddle.net/mimani/hd1n41he/1/ – Saurabh

+0

'elm' is undefined ... – 22samuelk

 Смежные вопросы

  • Нет связанных вопросов^_^