Передать значение accept в компонент

135
29 декабря 2020, 12:20

Необходимо, чтобы при клике на кнопку, окно загрузки файлов открывалось с определенным accept. В моем примере, accept применяется уже после того, как окно загрузки откроется. Библиотека Element-ui https://element.eleme.io/#/en-US/component/upload

new Vue({ 
  el: '#app', 
  data: function() { 
    return {  
      visible: false,  
      accept: ''  
    }; 
  }, 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> 
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> 
<script src="https://unpkg.com/element-ui/lib/index.js"></script> 
  <div id="app"> 
  <el-upload class="upload-demo" :accept="accept" action="/"> 
    <el-button size="small"  @click.native="accept = '.txt'">Upload txt</el-button> 
    <el-button size="small" @click.native="accept = '.png'">Upload png</el-button> 
  </el-upload> 
   
</div>

Answer 1

1 Вызов окна выбора файла происходит по клику на элементе el-upload. Можете убедиться в этом - между кнопками расстояние, и оно тоже кликабельное.

2 Вы изменяете свойство напрямую: accept = '.txt'. Грубо говоря - изменение попадает в очередь обновления DOM, пока не будет завершено текущее событие. Т.е. в момент открытия окна выбора файлов, DOM еще не обновился.

На всякий случай напомним, что во Vue обновление DOM выполняется асинхронно. Каждый раз, когда обнаруживается изменение в данных, создаётся очередь, которая используется в качестве буфера для этого и последующих изменений, происходящих в текущей итерации ("tick") цикла событий. ... В следующей итерации цикла событий Vue разбирает очередь и выполняет актуальные обновления. --источник

Это тот самый случай, когда можно было бы применить this.$nextTick. Но в примере ниже использовано вычисляемое свойство.

// Отключим ненужные для примера 
// сообщения в консоли. 
Vue.config.productionTip = false 
Vue.config.devtools = false 
 
new Vue({ 
  el: '#app', 
  data: { 
    accept: '' 
  }, 
 
  computed: { 
    changedAccept() { 
      return this.accept 
    } 
  }, 
 
  methods: { 
    changeAccept(type, event) { 
      this.accept = type 
    }, 
 
    applyAccept(event) { 
      // Если не выбран тип файлов, 
      // то отменяем вызов окна выбора файлов. 
      if (!this.accept) { 
        event.preventDefault() 
      } 
    } 
  } 
})
<div id="app"> 
  <el-upload class="upload-demo" :accept="changedAccept" action="/" @click.native="applyAccept"> 
    <el-button size="small" @click="changeAccept('audio/*', $event)">Upload audio</el-button> 
    <el-button size="small" @click="changeAccept('image/png', $event)">Upload png</el-button> 
  </el-upload> 
</div> 
 
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> 
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10"></script> 
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

Answer 2

Это нельзя считать ответом, однако как комментарий он слишком длинный.

Если проследить когда отрисовывается элемент, создается впечатление что каждый раз работает предварительно сгенеренная копия компонента. Т.е. первый рендер компонента происходит не по кнопке, а при первом выполнении кода, а кнопка запускает следущую генерацию компонента, но отрисовывает предыдущую. Если предполагается что это правильное поведение компонента, то предположу что для того чтобы можно было открыть одновременно несколько аплоадеров по одной кнопке. Если же одновременное открытие не предполагается, то возможно это бага ?

Будет крайне интересно если найдете ответ.

READ ALSO
Нужно создать кнопку в каждом поле таблицы HTML, которые будут взаимодейтсвовать с полями базы данных Postgresql. Делаю на Node JS

Нужно создать кнопку в каждом поле таблицы HTML, которые будут взаимодейтсвовать с полями базы данных Postgresql. Делаю на Node JS

В таблицу HTML выводятся данные из БД PostgresИ рядом с каждым полем должна выводится кнопка "Удалить клиента"

124
Сравнение числа с поля ввода, выводить сообщение на страницу

Сравнение числа с поля ввода, выводить сообщение на страницу

Посмотрите где у меня ошибка в коде, который будет проверять введенное значение, и говорить, сдали вы тест или нет

109
Яндекс карты. Путевые точки

Яндекс карты. Путевые точки

Как скрыть(не удалить) путевые точки и линию маршрута?

112