使用 Dropzone.js 和 Vue.js
Use Dropzone.js with Vue.js
我正在尝试在通过 Vue.js 生成的 Rails 表单中使用 Dropzone.js。我已将 dropzone.js 文件放在 app/assets/javascripts/.
然后我创建了一个单文件 components/dropzone.vue 组件:
<template>
<div id="image-drop"></div>
</template>
<script>
export default {
data() {
return {
greeting: 'blah'
}
},
created: function() {
var myDropzone = new Dropzone("div#image-drop", { url: "/file/post"});
}
}
</script>
<style></style>
我从我的主 vue 文件调用这个组件:
import Vue from 'vue/dist/vue.esm';
import dropzone from 'components/dropzone';
document.addEventListener('DOMContentLoaded', () => {
const listingForm = new Vue({
el: '#listing-multistep',
data: {
activeStep: 0
},
components: { dropzone }
})
})
在我的Rails_form.html.erb部分我有
<fieldset class="listing-step" v-if="activeStep === 0">
...
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 1">
...
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 2">
...
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 3">
<h2>Images</h2>
<div class="form-group">
<dropzone></dropzone>
</div>
</fieldset>
...
<button type="reset" @click="activeStep--" :disabled="activeStep === 0"/>
Previous
</button>
<button type="reset" @click="activeStep++" :disabled="activeStep === stepList.length - 1"/>
Next
</button>
但 Dropzone 未在 <div id="image-drop">
上初始化。
知道我可能做错了什么吗?
提前致谢
初读这个问题时,我以为你已经创建了一个包装器组件,因为它使用了<dropzone></dropzone>
。但从下面链接的 fiddle 来看,情况似乎并非如此。在 Vue 中使用外部库时,通常您希望将外部库功能包装在 Vue 组件中。这是一个非常的基本示例。
Vue.component("dropzone",{
template: `<div></div>`,
mounted(){
new Dropzone(this.$el, {
url: "/file/post"
})
}
})
Here is a pen 演示组件。
Dropzone 发射 many events,您可能希望自定义此基本组件以监听并发射到 Vue,以便它了解发生的事情。
原答案
创建组件时,div#image-drop
还不存在。
使用mounted
.
如下所述,由于您隐藏了部分模板,您可能需要切换到 v-show
而不是 v-if
。不同之处在于 v-show
将隐藏元素呈现给 DOM,但隐藏它们,而 v-if
直到需要它们时才呈现它们。
如果您想坚持使用 v-if
,则需要将 watch
添加到 activeStep
。
watch:{
activeStep(newVal){
if (3 == newVal)
this.$nextTick(() => new Dropzone("div#image-drop", { url: "/file/post"}))
}
}
我正在尝试在通过 Vue.js 生成的 Rails 表单中使用 Dropzone.js。我已将 dropzone.js 文件放在 app/assets/javascripts/.
然后我创建了一个单文件 components/dropzone.vue 组件:
<template>
<div id="image-drop"></div>
</template>
<script>
export default {
data() {
return {
greeting: 'blah'
}
},
created: function() {
var myDropzone = new Dropzone("div#image-drop", { url: "/file/post"});
}
}
</script>
<style></style>
我从我的主 vue 文件调用这个组件:
import Vue from 'vue/dist/vue.esm';
import dropzone from 'components/dropzone';
document.addEventListener('DOMContentLoaded', () => {
const listingForm = new Vue({
el: '#listing-multistep',
data: {
activeStep: 0
},
components: { dropzone }
})
})
在我的Rails_form.html.erb部分我有
<fieldset class="listing-step" v-if="activeStep === 0">
...
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 1">
...
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 2">
...
</fieldset>
<fieldset class="listing-step" v-if="activeStep === 3">
<h2>Images</h2>
<div class="form-group">
<dropzone></dropzone>
</div>
</fieldset>
...
<button type="reset" @click="activeStep--" :disabled="activeStep === 0"/>
Previous
</button>
<button type="reset" @click="activeStep++" :disabled="activeStep === stepList.length - 1"/>
Next
</button>
但 Dropzone 未在 <div id="image-drop">
上初始化。
知道我可能做错了什么吗?
提前致谢
初读这个问题时,我以为你已经创建了一个包装器组件,因为它使用了<dropzone></dropzone>
。但从下面链接的 fiddle 来看,情况似乎并非如此。在 Vue 中使用外部库时,通常您希望将外部库功能包装在 Vue 组件中。这是一个非常的基本示例。
Vue.component("dropzone",{
template: `<div></div>`,
mounted(){
new Dropzone(this.$el, {
url: "/file/post"
})
}
})
Here is a pen 演示组件。
Dropzone 发射 many events,您可能希望自定义此基本组件以监听并发射到 Vue,以便它了解发生的事情。
原答案
创建组件时,div#image-drop
还不存在。
使用mounted
.
如下所述,由于您隐藏了部分模板,您可能需要切换到 v-show
而不是 v-if
。不同之处在于 v-show
将隐藏元素呈现给 DOM,但隐藏它们,而 v-if
直到需要它们时才呈现它们。
如果您想坚持使用 v-if
,则需要将 watch
添加到 activeStep
。
watch:{
activeStep(newVal){
if (3 == newVal)
this.$nextTick(() => new Dropzone("div#image-drop", { url: "/file/post"}))
}
}