How can I pass extra parameters to the upload-button component? Vuetify - file-upload

I'm using the vuetify-upload-button component to be able to upload files. Using the function callback fileChangedCallback that only gets the file loaded.
But, I need to have extra parameters to be able to make a logic. Is it possible to pass extra parameters to this function?
This is my code:
v-flex.listFilesUpload(v-for="(file, index) in attachments" :key="index")
p
span
| {{ index + 1 }}
.btns-upload-download
upload-btn(title="File" :fileChangedCallback="fileChanged" color="default")
import UploadButton from 'vuetify-upload-button'
export default {
[..]
methods: {
fileChanged (file) {
// Here I need my other variable file because it have the filename.
if (file) {
formData.append('filenames[]', file)
}
},
components: {
'upload-btn': UploadButton
}
}
}

Related

vue 3.0 can mount multiple elements used class name?

i want make formatted text input like below:
<input type="text" class="number-format" v-model="numberModel">
...
and mount vue that elements:
const numberInput = {
computed: {
numberModel: {
get: function() {
return new Intl.NumberFormat().format(this.value);
},
set: function(n) {
this.value = parseInt(n.replaceAll(",", ""));
}
}
},
data: function() {
return {
value: ""
}
}
}
Vue.createApp(numberInput).mount(".number-format");
but it mounted only first element of .number-format.
i want make vue root app like component(but, it is not component).
<number-format-input ........> (x)
<input type="text" ....> (o)
any possible solutions?
mount() expects its argument to resolve to a single DOM node. It can be either the DOM node itself or a CSS selector - but if multiple nodes match the CSS selector, only the first node will be replaced with the generated Vue instance.
You will need to first register a global Vue component - and then use that component in your template, presumably with v-for directive to define multiple instances of that component.

Populate VueSimpleSuggest from URL param on page load

I have this VueSimpleSuggest component in my Vue JS app:
<vue-simple-suggest
class="input-elements"
v-model="chosen"
:max-suggestions="0"
:list="getList"
:filter-by-query="true"
ref="suggestComponent"
v-on:select="updateAppDataOnSelect"
>
</vue-simple-suggest>
I have this in the script section of the vue file:
data() {
return {
chosen: ''
}
},
I am trying to pick up the URL parameter fd with the query parameter and assign it so it is effectively the default value for the simple suggest list:
mounted() {
if ("fd" in this.$route.query) {
// eslint-disable-next-line no-console
console.log('fd: ', this.$route.query.fd)
this.chosen = self.$route.query.fd
}
},
While the console.log dumps out the value of the fd parameter, the simple suggest input does not show that value.
How do I get the simple suggest to show the value passed in from the URL?
Turns out I was using the wrong parent reference. I should have had this instead of self, as demonstrated by the console.log #typo
mounted() {
if ("fd" in this.$route.query) {
// eslint-disable-next-line no-console
console.log('fd: ', this.$route.query.fd)
this.chosen = this.$route.query.fd
}
},

Vue search while typing

I have search field and I wish to have the results in real-time,
I have no issue with returning data or showing data but I need a way to send input value to back-end while user is typing it.
Code
HTML
<el-input placeholder="Type something" v-model="search">
<i slot="prefix" class="el-input__icon el-icon-search"></i>
</el-input>
Script
data() {
return {
search: '' // getting data of input field
}
},
I've tried to compute it but it didn't return data
computed : {
searchSubmit: {
get: function () {
console.log(this.search);
}
}
},
Any idea?
For side effects as calling backend you can use Watchers.
watch: {
search(value) {
yourApiCall(value)
}
}

How to directly modify v-model value using directives?

I've got form with dynamic number of input fields and i need to transliterate data, passed to this fields in 'live'. I wrote custom directive which do all job, but there is an a error -> it converts all chars except last one (should be привет->privet, while привет->priveт). This is my source code
directives: {
transliterate: {
update(element, binding) {
element.value = tr(element.value)
}
}
}
This is PUG (Jade)
input(v-model='requestHotels.travellers[index].first_name', v-transliterate='true')
tr - just function, which transliterate from ru to en
I knew why this happening, but i can't solve it by myself. Any ideas?
1) Consider using computed property instead of directive. Personally, I don't like directives because they can add alot of useless complexity to your code. But there are some complex cases where they can be really useful. But this one is not one of them.
export default {
data: () => ({
tranliteratedValue: ""
}),
computed: {
vModelValue: {
get() {
return this.tranliteratedValue;
},
set(value) {
this.tranliteratedValue = transl.transform(value);
}
}
}
};
Full example: https://codesandbox.io/s/039vvo13yv?module=%2Fsrc%2Fcomponents%2FComputedProperty.vue
2) You can use filter and transliterate during render
filters: {
transliterate(value) {
return transl.transform(value);
}
}
Then in your template:
<p>{{ value | transliterate }}</p>
Full example: https://codesandbox.io/s/039vvo13yv?module=%2Fsrc%2Fcomponents%2FFilter.vue
3) Transparent wrapper technique (using custom component)
The idea behind transparent wrapper is that you should create custom component that behave as build-in input (and accepts the same arguments) but you can intercept events and change behaviour as you'd like. In your example - tranliterate input text.
<textarea
v-bind="$attrs"
:value="value"
v-on="listeners"
/>
computed: {
listeners() {
return {
...this.$listeners,
input: event => {
const value = transl.transform(event.target.value + "");
this.$emit("input", value);
}
};
}
}
Full example: https://codesandbox.io/s/039vvo13yv?module=%2Fsrc%2Fcomponents%2Finc%2FTransliteratedInput.vue
Read more about Transparent wrapper technique here https://github.com/chrisvfritz/7-secret-patterns/blob/master/slides-2018-03-03-spotlight-export.pdf
You can check all 3 working approaches here https://codesandbox.io/s/039vvo13yv

How to change the value of a prop (or data) of a component, from OUTSIDE the component?

As the title says, I'm trying to change the value of a prop/data in a component, but the trigger is being fired from outside the component, from something that has nothing to do with Vuejs.
Currently I trying to use a Simple State Manager, based on the docs from here, like so:
var store = {
debug: true,
state: {
progress: 23
},
setProgress (uff) {
if (this.debug) console.log(uff)
this.state.progress = uff
}
}
The documentation leads me to believe that if the value of progress is mutated, the value of my Vue instance would also change if I link them accordingly. But this doesn't work in a component (my guess would be it's cause it's a function).
This is part of my component:
Vue.component('transcoding', {
data () {
return {
progress: store.state.progress
}
},
template: `
<v-progress-circular
:size="130"
:width="25"
:value="progress"
color="teal"
>
{{progress}}
</v-progress-circular>
`
})
So, when I trigger a store.setProgress(value), nothing happens. The log messages do happen, but the state isn't updated in the component.
This is the script that's currently triggering the state change:
App.cable.subscriptions.create(
{ channel: "ProgressChannel", room: "2" },
{ received: function() {
store.setProgress(arguments[0])
}}
)
It's an ActionCable websocket in Ruby on Rails. The trigger works perfectly, but I just cannot make the connection between the state change and the component.
I tried loading this script in the mounted() event for the component, thinking I could reference the value like this:
Vue.component('transcoding', {
data () {
return {
progress: 0
}
},
template: `
<v-progress-circular
:size="130"
:width="25"
:value="progress"
color="teal"
>
{{progress}}
</v-progress-circular>
`,
methods: {
setProgress: function(uff) {
this.progress = uff
}
},
mounted() {
App.cable.subscriptions.create(
{ channel: "ProgressChannel", room: "2" },
{ received: function() {
this.setProgress(arguments[0])
}}
)
}
})
But this gives me an error saying that this.setProgress is not a function, which is obvious since I'm calling it within the create method of App.cable.subscriptions.
How can I make this work? I realize I'm mixing things with my question, but I wanted to illustrate what my goal is. I simply want to know how to make the component's progress data to update, either from the outside, or from the component itself if I can make it find the function.
You are initializing your data item to the value from the store:
data () {
return {
progress: store.state.progress
}
}
Changes to the store will not propagate to your data item. You could eliminate the data item and just use store.state.progress where you need it, or you could create an computed that returns its value if you want a local single-name handle for it.