Skip to content

Instantly share code, notes, and snippets.

@ctf0
Last active December 10, 2019 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctf0/cad83c683767a96e432c0a92a3f8fe43 to your computer and use it in GitHub Desktop.
Save ctf0/cad83c683767a96e432c0a92a3f8fe43 to your computer and use it in GitHub Desktop.

Js

  • 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
                    }, {})

Vue

  • 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)


  • 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, add v-cloak on it to avoid premature render of the component content

// 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 using v-model="item[0]"
  • we can use v-model with v-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
    }
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment