- clones
// to clone an object
this.x = Object.assign({}, this.y)
// to clone an array
this.x = this.y.slice(0)
// dont use this to clone as it will produce side effects.
this.x = this.y
- filter object by another
const difference = Object.keys(main_obj)
.filter((key) => !Object.keys(other_obj).includes(key))
.reduce((obj, key) => {
obj[key] = main_obj[key]
return obj
}, {})
- to send a data along with its type correctly to vue, it have to be in
'...'
, ex.
<div :some-prop="{{ 'true', 'false', 'null', '[]' }}"></div>
// for json_encode() it works without any issues
<div :some-prop="{{ json_encode($some_var) }}"></div>
now vue will render it exactly as the sent type.
- if you hate that u have to use v-model for everything, u can instead use
ref
// make the ref == name for easier workflow
<input type="text" name="something" ref="something" value="some pre text"/>
// in js
console.log(vm.$refs.something.value) // 'some pre text'
vm.$refs.something.value = 'abc'
console.log(vm.$refs.something.value) // 'abc'
// in html "using any kind of elements & any kind of events"
<button @click="$refs.something.value = 'abc'">bla</button>
- you can conditionally render components through a function too
// html
<component :is="getName(some dynamic prop)"></component>
//js
getName(dynamic) {
switch (dynamic) {
case 'a':
return 'component-a'
case 'b':
return 'component-b'
case 'c':
return 'component-c'
default:
return 'component-default'
}
}
keep-alive
can be used on the same component, like having a shared component that uses the same operations but hold different data
<transition>
<keep-alive>
<some-comp key="1" v-if="..." inline-template><div>a</div></some-comp>
<some-comp key="2" v-if="..." inline-template><div>b</div></some-comp>
<some-comp key="3" v-if="..." inline-template><div>c</div></some-comp>
// ...
</keep-alive>
</transition>
just make sure that each component has a key so vue can track which is which or you would end up getting the same data across all.
- to name the component dynamically
beforeMount() {
this.$options.name = `${this.someProp}`
},
- when using laravel
route()
with vue, you will get an error if that route requires a param so to get around that use a placeholder param
// any number or whatever so we can replace it later
<some-comp url="{{ route('some.name', 1) }}">...</some-comp>
// now replace the ph with the actual param for the ajax call
let url = this.url.replace(1, this.item.id)
- watch multiple props vuejs/vue#844 (comment)
- to make sure the DOM has finished updating use debounce with $nexttick
import debounce from 'lodash/debounce'
// on updated
updated: debounce(function() {
this.$nextTick(() => {
// fires once
})
}, 500),
// normal
this.$nextTick(debounce(() => {
// do stuff after all DOM changes are made
}, 250))
- if you have any
inline-template
component, addv-cloak
on it to avoid premature render of the component content
- debounce input https://vuejs.org/v2/examples/index.html & https://stackoverflow.com/questions/42199956/how-to-implement-debounce-in-vue2
// html
<input @input="debounceInput">
// js
import debounce from 'lodash/debounce'
methods: {
debounceInput: debounce(function({target}) {
this.searchFor = target.value
}, 250)
}
but note that the cloned $data && $props
wont be reactive.
- you can append a dynamic value to the v-for list ex
<ul>
<li v-for="item in list" :key="item">{{ abc ? `${abc}-${item}` : item }}</li>
</ul>
<input v-model="abc">
- to check if an input is focused try
// if we have a ref
// this is ofcourse inside an "eventListener"
isFocused(item, e) {
return this.$refs[item].contains(e.target)
},
// or by a data-something
document.activeElement.dataset.search == undefined
- when removing item from a list, it usually end up animating the wrong item, thats because of the
:key
so never use index for the key, instead use a unique identifier and add
/* anim-name = anything u want */
.anim-name-move,
.anim-name-enter-active,
.anim-name-leave-active {
transition: all 0.3s ease;
}
/* only when needed */
.anim-name-leave-active {
position: absolute;
}
- we can inforce
v-model
to save in array by usingv-model="item[0]"
- we can use
v-model
withv-for
by
<li v-for="item in items" :key="item.id">
<input v-model="items[getIndex(items, item.id)].value">
</li>
getIndex(list, id) {
return list.findIndex((e) => e.id == id)
},
- yes we can also use the index from the
v-for
but it might produce some side effects, so 2xcheck b4 settling with it
<li v-for="(item, i) in items" :key="item.id">
<input v-model="items[i].value">
</li>
- if you have some pending jobs & you want to give the best UX , then make sure to use
// when use refresh or navigate away
window.addEventListener('beforeunload', (event) => {
if (some_condition) {
event.returnValue = 'are u sure'
}
})
// on confirm
window.addEventListener('unload', (event) => {
if (some_condition) {
// do cleanup
}
})