Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fjc0k/vue-messenger

Open more actions menu

Repository files navigation

Vue Messenger logo

Build Status Coverage Status Minified Size Minzipped Size Version License

Vue Messenger

A series of useful enhancements to Vue components props:

Install

Package

# yarn
yarn add vue-messenger

# or, npm
npm i vue-messenger --save

CDN

Available as global VueMessenger.

Usage

Install mixin

Globally

// main.js
import Vue from 'vue'
import Messenger from 'vue-messenger'

Vue.mixin(Messenger)

Locally

// Component.vue
import Messenger from 'vue-messenger'

export default {
  mixins: [Messenger],
  // ...
}

Transform props

To transform a prop, add a transform: value => transformedValue function to its descriptor, and use this.local${PropName} to get transformed prop. e.g.

😑 before

<template>
  <div>{{ normalizedMessage }}</div>
</template>

<script>
export default {
  props: {
    message: [Number, String]
  },
  computed: {
    normalizedMessage() {
      return String(this.message).trim().replace(/@/g, '(a)')
    }
  }
}
</script>

😀 after

<template>
  <div>{{ localMessage }}</div>
</template>

<script>
export default {
  props: {
    message: {
      type: [Number, String],
      transform: message => String(message).trim().replace(/@/g, '(a)')
    }
  }
}
</script>

Enum-type props

To define a enum-type prop, add a enum array to its descriptor, and its default value will be enum[0] if the descriptor doesn't contain default attribute. e.g.

😑 before

export default {
  props: {
    size: {
      type: String,
      default: 'small',
      validator: value => ['small', 'large'].indexOf(value) >= 0
    }
  }
}

😀 after

export default {
  props: {
    size: {
      type: String,
      enum: ['small', 'large']
    }
  }
}

Numeric-type props

To define a numeric-type prop, add numeric: true to its descriptor. Besides, you can set infinite to ture to allow infinite numbers, which are -Infinity and Infinity. e.g.

😑 before

export default {
  props: {
    count: {
      type: [Number, String],
      default: 0,
      validator: value => !isNaN(value - parseFloat(value))
      }
    },
    max: {
      type: [Number, String],
      default: Infinity,
      validator: value => value === Infinity || !isNaN(value - parseFloat(value))
    }
  }
}

😀 after

export default {
  props: {
    count: {
      numeric: true,
      default: 0
    },
    max: {
      numeric: true,
      infinite: true,
      default: Infinity
    }
  }
}

Listen for receiving props

To listen for receiving a prop, add on: { receive: (newValue, oldValue) => void } object to its descriptor. e.g.

😑 before

export default {
  props: {
    count: [Number, String]
  },
  watch: {
    count: {
      immediate: true,
      handler(newCount, oldCount) {
        console.log(newCount, oldCount)
      }
    }
  }
}

😀 after

export default {
  props: {
    count: {
      type: [Number, String],
      on: {
        receive(newCount, oldCount) {
          console.log(newCount, oldCount)
        }
      }
    }
  }
}

Two-way data binding props

To apply two-way data bindings on a prop, add sync: true to its descriptor. Then, you can use this.local${PropName} = newValue or this.send${PropName}(newValue) to send new value to Parent component.

If the prop is model prop, it's no need to add sync: true to its descriptor.

😑 before

<!-- // Parent.vue -->
<template>
  <Child v-model="value" :visible.sync="visible" />
</template>

<script>
import Child from './Child.vue'

export default {
  components: { Child },
  data: () => ({
    value: String,
    visible: Boolean
  })
}
</script>

<!-- // Child.vue -->
<template>
  <div v-show="curVisible">
    <input v-model="curValue" />
  </div>
</template>

<script>
export default {
  props: {
    value: String,
    visible: Boolean
  },
  computed: {
    curValue: {
      get() {
        return this.value
      },
      set(newValue) {
        if (newValue === 'hide') {
          this.curVisible = false
        }
        this.$emit('input', newValue)
      }
    },
    curVisible: {
      get() {
        return this.visible
      },
      set(newVisible) {
        this.$emit('update:visible', newVisible)
      }
    }
  }
}
</script>

😀 after

<!-- // Parent.vue -->
<template>
  <Child v-model="value" :visible.sync="visible" />
</template>

<script>
import Child from './Child.vue'

export default {
  components: { Child },
  data: () => ({
    value: String,
    visible: Boolean
  })
}
</script>

<!-- // Child.vue -->
<template>
  <div v-show="localVisible">
    <input v-model="localValue" />
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: String,
      on: {
        change(value) {
          if (value === 'hide') {
            this.localVisible = false
          }
        }
      }
    },
    visible: {
      type: Boolean,
      sync: true
    }
  }
}
</script>

About

A series of useful enhancements to Vue component props.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published
Morty Proxy This is a proxified and sanitized view of the page, visit original site.