- Chrome / Firefox / Edge / IE9~IE11
- Plain-text based, no jQuery, no extra nodes
- Content-Editable / Textarea
- Avatars, custom templates
- Vite / Vue3 / Vue2 / Vue1
- Vuetify / Element UI / Element Plus
- Vue-CLI build migration
- Vite build migration
- CommonJS / UMD Support
Playground: https://we-demo.github.io/vue-at-vite-app/
Vue2 Docs: https://github.com/fritx/vue-at/tree/vue2#readme
Vue3 Docs: See below
See also: react-at
If you're using Vue2, read branch vue2 instead.
npm i vue-at@next # for Vue3 (branch vue3)
npm i [email protected] # for Vue2 (branch vue2)
npm i [email protected] # for Vue1 (branch vue1-legacy)
npm i vue1-at # for Vue1 (branch vue1-new)
<template>
<at :members="members">
<div :contenteditable="true"></div>
</at>
<at-ta :members="members">
<textarea></textarea>
</at-ta>
</template>
<script>
import At from 'vue-at' // for content-editable
import AtTa from 'vue-at/dist/vue-at-textarea' // for textarea
export default {
components: { At, AtTa },
data () {
return {
members: ['Roxie Miles', 'grace.carroll', '小浩']
}
}
}
</script>
<style>
#app .atwho-view { /* more */ }
#app .atwho-ul { /* more */ }
</style>
<!-- for Vue2 -->
<script src="//unpkg.com/vue@2"></script>
<script src="//unpkg.com/vue-at@2/dist/vue-at.umd.js"></script>
<script src="//unpkg.com/vue-at@2/dist/vue-at-textarea.umd.js"></script>
<!-- ...-->
<!-- for Vue3 -->
<script src="//unpkg.com/vue@3"></script>
<script src="//unpkg.com/vue-at@next/dist/vue-at.umd.js"></script>
<script src="//unpkg.com/vue-at@next/dist/vue-at-textarea.umd.js"></script>
<div id="app">
<at v-model:value="html">
<div contenteditable></div>
</at>
<at-textarea>
<textarea v-model="text"></textarea>
</at-textarea>
</div>
<script>
Vue.createApp({
components: { At, AtTextarea },
// ...
}).mount('#app')
</script>
With Content-Editable, use <at v-model:value="v">
With Textarea, you can use either <at-ta v-model:value="v">
or <textarea v-model="v">
<at v-model:value="html">
<div :contenteditable="true"></div>
</at>
<at-ta v-model:value="text">
<textarea></textarea>
</at-ta>
<at-ta>
<textarea v-model="text"></textarea>
</at-ta>
<template>
<at :members="members" name-key="name">
<template slot="item" slot-scope="s">
<img :src="s.item.avatar">
<span v-text="s.item.name"></span>
</template>
<div :contenteditable="true"></div>
</at>
</template>
<script>
// ...
members: [{
avatar: 'https://randomuser.me/api/portraits/men/2.jpg',
name: 'myrtie.green'
}, {
avatar: 'https://randomuser.me/api/portraits/men/8.jpg',
name: '椿木'
}]
</script>
<style>
#app .atwho-li { /* more */ }
#app .atwho-li img { /* more */ }
#app .atwho-li span { /* more */ }
</style>
There is no "scoped slot" feature in Vue 1.
Use a "normal slot" with data-
attribute instead.
<!-- vue1-at for [email protected] -->
<template slot="item">
<img data-src="item.avatar">
<span data-text="item.name"></span>
</template>
This gives you the option of changing the style of inserted tagged items. It is only supported for ContentEditable version, not Textarea.
<span slot="embeddedItem" slot-scope="s">
<span class="tag"><img :src="s.current.avatar">{{ s.current.name }}</span>
</span>
<!-- with Vue 2.6+ 'v-slot' / '#slot' directive -->
<!-- note at least two '<span>' wrapper are required to work -->
<template #embeddedItem="s">
<span><span class="tag"><img class="avatar" :src="s.current.avatar">{{ s.current.name }}</span></span>
</template>
<at-ta :members="members">
<!-- slots -->
<v-textarea v-model="text"></v-textarea>
</at-ta>
<at-ta :members="members">
<!-- slots -->
<el-input v-model="text" type="textarea"></el-input>
</at-ta>