Skip to content

Commit

Permalink
wip: vue3 support -- #137
Browse files Browse the repository at this point in the history
  • Loading branch information
fritx committed Aug 3, 2022
1 parent 29e662f commit 43382bc
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 184 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ See also: [react-at](https://github.com/fritx/react-at)
Finally I ended up creating this.

```plain
npm i vue-at@3.0.0-alpha.0 # for Vue3 (🚧 Working in Progress...)
npm i vue-at@2.x # for Vue2 <----
npm i vue-at@1.x # for Vue1 (branch vue1-legacy)
npm i vue1-at # for Vue1 (branch vue1-new)
Expand All @@ -40,7 +42,7 @@ npm i vue1-at # for Vue1 (branch vue1-new)
```vue
<template>
<at :members="members">
<div contenteditable></div>
<div :contenteditable="true"></div>
</at>
</template>
Expand Down Expand Up @@ -69,12 +71,12 @@ With Content-Editable, `v-model` should be bound in `<at>` container.<br>
With Textarea, `v-model` should be bound in `<textarea>` itself.

```vue
<at v-model="html">
<div contenteditable></div>
<at v-model:value="html">
<div :contenteditable="true"></div>
</at>
<at-ta>
<textarea v-model="text"></textarea>
<textarea v-model:value="text"></textarea>
</at-ta>
```

Expand Down Expand Up @@ -112,7 +114,7 @@ npm i -S textarea-caret # also, for textarea
<img :src="s.item.avatar">
<span v-text="s.item.name"></span>
</template>
<div contenteditable></div>
<div :contenteditable="true"></div>
</at>
</template>
Expand Down Expand Up @@ -170,7 +172,7 @@ This gives you the option of changing the style of inserted tagged items. It is
```vue
<at-ta :members="members">
<!-- slots -->
<v-textarea v-model="text"></v-textarea>
<v-textarea v-model:value="text"></v-textarea>
</at-ta>
```

Expand All @@ -179,6 +181,6 @@ This gives you the option of changing the style of inserted tagged items. It is
```vue
<at-ta :members="members">
<!-- slots -->
<el-input v-model="text" type="textarea"></el-input>
<el-input v-model:value="text" type="textarea"></el-input>
</at-ta>
```
25 changes: 15 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
{
"name": "vue-at",
"description": "At.js for Vue",
"version": "2.5.0-beta.2",
"version": "3.0.0-alpha.0",
"author": "Fritz Lin <uxfritz@163.com>",
"repository": "https://github.com/fritx/vue-at",
"scripts": {
"dev": "webpack serve --config webpack/demo --open --inline --hot --mode development",
"demo": "webpack --config webpack/demo --progress --mode development",
"build": "webpack --config webpack/prod --progress --mode production",
"dev": "vue-cli-service serve",
"demo": "vue-cli-service build",
"build:at": "vue-cli-service build ./src/At.vue --target lib --name vue-at",
"build:at-ta": "vue-cli-service build ./src/AtTextarea.vue --target lib --name vue-at-textarea",
"build": "rimraf dist && run-p build:at build:at-ta && rimraf dist/demo.html",
"prepublish": "npm run build"
},
"main": "dist/vue-at.js",
"engines": {
"node": "14.x"
},
"peerDependencies": {
"vue": "2.x"
"vue": "3.x"
},
"devDependencies": {
"@babel/core": "^7.18.9",
Expand All @@ -36,23 +38,26 @@
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/preset-env": "^7.18.9",
"@vue/cli-service": "^5.0.8",
"@vue/compat": "^3.1.0",
"@vue/compiler-sfc": "^3.1.0",
"babel-loader": "^8.2.5",
"babel-preset-minify": "^0.5.2",
"cross-env": "^7.0.3",
"css-loader": "^0.28.11",
"element-ui": "^2.15.9",
"file-loader": "^6.2.0",
"npm-run-all": "^4.1.5",
"rimraf": "^3.0.2",
"sass": "^1.53.0",
"sass-loader": "^13.0.2",
"style-loader": "^3.3.1",
"style-resources-loader": "^1.5.0",
"terser-webpack-plugin": "^5.3.3",
"textarea-caret": "^3.1.0",
"url-loader": "^4.1.1",
"vue": "^2.7.8",
"vue-loader": "^14.2.4",
"vue": "^3.1.0",
"vue-loader": "^16.0.0",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.7.8",
"vuetify": "^2.6.7",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^3.11.0"
Expand Down
File renamed without changes
File renamed without changes
44 changes: 27 additions & 17 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<template>
<div id="app">
<at :members="members" name-key="name" v-model="html">

<!--
migration.2
fix: [Vue warn]: (deprecation COMPONENT_V_MODEL) v-model usage on component has changed in Vue 3. Component that expects to work with v-model should now use the "modelValue" prop and emit the "update:modelValue" event. You can update the usage and then opt-in to Vue 3 behavior on a per-component basis with `compatConfig: { COMPONENT_V_MODEL: false }`.
Details: https://v3-migration.vuejs.org/breaking-changes/v-model.html
-->
<at :members="members" name-key="name" v-model:value="html">
<!-- custom: same as default slot -->
<!-- <template v-slot:item="s">
<span v-text="s.item"></span>
Expand All @@ -12,11 +18,16 @@
<span v-text="s.item.name"></span>
</template>

<div class="editor"
contenteditable></div>
<!--
migration.4
fix: [Vue warn]: (deprecation ATTR_ENUMERATED_COERCION) Enumerated attribute "contenteditable" with v-bind value `` will render the value as-is instead of coercing the value to "true" in Vue 3. Always use explicit "true" or "false" values for enumerated attributes. If the usage is intended, you can disable the compat behavior and suppress this warning with:
configureCompat({ ATTR_ENUMERATED_COERCION: false })
Details: https://v3-migration.vuejs.org/breaking-changes/attribute-coercion.html
-->
<div class="editor" :contenteditable="true"></div>
</at>

<at :members="members" name-key="name" v-model="html2">
<at :members="members" name-key="name" v-model:value="html2">
<template v-slot:embeddedItem="s">
<span><span class="tag"><img class="avatar" :src="s.current.avatar">{{ s.current.name }}</span></span>
</template>
Expand All @@ -27,13 +38,12 @@
<span v-text="s.item.name"></span>
</template>

<div class="editor"
contenteditable></div>
<div class="editor" :contenteditable="true"></div>
</at>

<br />

<at-ta :members="members" name-key="name" v-model="text">
<at-ta :members="members" name-key="name" v-model:value="text">
<!-- custom: with avatars -->
<template v-slot:item="s">
<img :src="s.item.avatar">
Expand All @@ -43,34 +53,34 @@
<textarea class="editor"></textarea>
</at-ta>

<at-ta :members="members" name-key="name">
<!-- custom: with avatars -->
<!-- <at-ta :members="members" name-key="name">
<!- custom: with avatars ->
<template v-slot:item="s">
<img :src="s.item.avatar">
<span v-text="s.item.name"></span>
</template>
<v-textarea class="vuetify-editor" v-model="text2"></v-textarea>
<v-textarea class="vuetify-editor" v-model:value="text2"></v-textarea>
</at-ta>
<br />
<at-ta :members="members" name-key="name">
<!-- custom: with avatars -->
<!- custom: with avatars ->
<template v-slot:item="s">
<img :src="s.item.avatar">
<span v-text="s.item.name"></span>
</template>
<el-input type="textarea" v-model="text3" class="element-editor"></el-input>
</at-ta>
<el-input type="textarea" v-model:value="text3" class="element-editor"></el-input>
</at-ta> -->
</div>
</template>

<script>
// import At from 'vue-at'
// import At from '../dist/vue-at'
// import AtTa from '../dist/vue-at-textarea'
// import At from '../dist/vue-at.common'
// import AtTa from '../dist/vue-at-textarea.common'
import At from './At.vue'
import AtTa from './AtTextarea.vue'
Expand Down Expand Up @@ -121,8 +131,8 @@ Playback - Video player.
`.trim(), // fix trailing abnormal nodes
html: `
<div>&lt;&lt;&lt; Content Editable Div &gt;&gt;&gt;</div><div>Awesome Electron&nbsp;
<img src="static/awesome.svg"></div><div><img style="max-width: 50px;" src="static/electron.svg"></div><div>Useful resources for creating apps with&nbsp;Electron</div><div>Inspired by the&nbsp;awesome&nbsp;list thing. You might also like&nbsp;awesome-nodejs.</div><div>Example apps</div><div>Some good apps written with Electron.</div><div>Open Source</div><div>Atom&nbsp;- Code editor.</div><div>Nuclide&nbsp;- Unified IDE.</div><div>Playback&nbsp;- Video player.</div>
<div>&lt;&lt;&lt; Content Editable Div &gt;&gt;&gt;</div><div>Awesome Electron&nbsp;<img style="max-width: 50px;" src="static/awesome.svg"></div><div><img style="max-width: 50px;" src="static/electron.svg"></div><div>Useful resources for creating apps with&nbsp;Electron</div><div>Inspired by the&nbsp;awesome&nbsp;list thing. You might also like&nbsp;awesome-nodejs.</div><div>Example apps</div><div>Some good apps written with Electron.</div><div>Open Source</div><div>Atom&nbsp;- Code editor.</div><div>Nuclide&nbsp;- Unified IDE.</div><div>Playback&nbsp;- Video player.</div>
<img src="awesome.svg"></div><div><img style="max-width: 50px;" src="electron.svg"></div><div>Useful resources for creating apps with&nbsp;Electron</div><div>Inspired by the&nbsp;awesome&nbsp;list thing. You might also like&nbsp;awesome-nodejs.</div><div>Example apps</div><div>Some good apps written with Electron.</div><div>Open Source</div><div>Atom&nbsp;- Code editor.</div><div>Nuclide&nbsp;- Unified IDE.</div><div>Playback&nbsp;- Video player.</div>
<div>&lt;&lt;&lt; Content Editable Div &gt;&gt;&gt;</div><div>Awesome Electron&nbsp;<img style="max-width: 50px;" src="awesome.svg"></div><div><img style="max-width: 50px;" src="electron.svg"></div><div>Useful resources for creating apps with&nbsp;Electron</div><div>Inspired by the&nbsp;awesome&nbsp;list thing. You might also like&nbsp;awesome-nodejs.</div><div>Example apps</div><div>Some good apps written with Electron.</div><div>Open Source</div><div>Atom&nbsp;- Code editor.</div><div>Nuclide&nbsp;- Unified IDE.</div><div>Playback&nbsp;- Video player.</div>
`.trim() // fix trailing abnormal nodes
}
data.text2 = data.text
Expand Down
12 changes: 11 additions & 1 deletion src/At.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<script>
// fixme: todo: migration.6
// [Vue warn]: Missing ref owner context. ref cannot be used on hoisted vnodes.
// A vnode with ref must be created inside the render function.
// at selectByMouse
// at handleItemHover
import {
closest, getOffset, getPrecedingRange,
getRange, applyRange,
Expand Down Expand Up @@ -134,7 +141,10 @@ export default {
}
},
mounted () {
if (this.$scopedSlots.embeddedItem) {
// migration.5
// [Vue warn]: (deprecation INSTANCE_SCOPED_SLOTS) vm.$scopedSlots has been removed. Use vm.$slots instead.
// Details: https://v3-migration.vuejs.org/breaking-changes/slots-unification.html
if (this.$slots.embeddedItem) {
this.customsEmbedded = true
}
if (this.bindsValue) {
Expand Down
35 changes: 25 additions & 10 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
import 'element-ui/lib/theme-chalk/index.css'
import 'vuetify/dist/vuetify.min.css'
import Vuetify from 'vuetify'
import ElementUI from 'element-ui'
import Vue from 'vue'
// import 'element-ui/lib/theme-chalk/index.css'
// import 'vuetify/dist/vuetify.min.css'
// import Vuetify from 'vuetify'
// import ElementUI from 'element-ui'
import { createApp, configureCompat } from 'vue'
import App from './App.vue'

Vue.use(Vuetify)
Vue.use(ElementUI)
// Vue.use(Vuetify)
// Vue.use(ElementUI)

new Vue({
el: '#app',
render: h => h(App)
configureCompat({
// migration.3
// fix: [Vue warn]: (deprecation WATCH_ARRAY) "watch" option or vm.$watch on an array value will no longer trigger on array mutation unless the "deep" option is specified. If current usage is intended, you can disable the compat behavior and suppress this warning with:
// configureCompat({ WATCH_ARRAY: false })
// Details: https://v3-migration.vuejs.org/breaking-changes/watch.html
WATCH_ARRAY: false,

// migration.4
// fix: [Vue warn]: (deprecation ATTR_ENUMERATED_COERCION) Enumerated attribute "contenteditable" with v-bind value `` will render the value as-is instead of coercing the value to "true" in Vue 3. Always use explicit "true" or "false" values for enumerated attributes. If the usage is intended, you can disable the compat behavior and suppress this warning with:
// configureCompat({ ATTR_ENUMERATED_COERCION: false })
// Details: https://v3-migration.vuejs.org/breaking-changes/attribute-coercion.html
ATTR_ENUMERATED_COERCION: false,
})

// migration.1
// fix: [Vue warn]: (deprecation GLOBAL_MOUNT) The global app bootstrapping API has changed: vm.$mount() and the "el" option have been removed. Use createApp(RootComponent).mount() instead.
// Details: https://v3-migration.vuejs.org/breaking-changes/global-api.html#mounting-app-instance
let app = createApp(App)
app.mount('#app')
38 changes: 38 additions & 0 deletions vue.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var webpack = require('webpack')

module.exports = {
css: {
extract: false, // inline css into js
loaderOptions: {
sass: {},
scss: {}
}
},
configureWebpack: {
plugins: [
// migration.6 externalize optional dependencies
// fixme: todo:
// Uncaught ReferenceError: require is not defined
// at textarea-caret (app.js:281:1)
// at __webpack_require__ (app.js:310:33)
// new webpack.ExternalsPlugin('commonjs2', ['textarea-caret'])
]
},
chainWebpack: config => {
config.resolve.alias.set('vue', '@vue/compat')

config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
return {
...options,
compilerOptions: {
compatConfig: {
MODE: 2
}
}
}
})
}
}
60 changes: 0 additions & 60 deletions webpack/base.js

This file was deleted.

0 comments on commit 43382bc

Please sign in to comment.