vue-o2c
                                
                                 vue-o2c copied to clipboard
                                
                                    vue-o2c copied to clipboard
                            
                            
                            
                        Vue 3 convert options API to composition API
vue-o2c - Vue Options API to Composition API
WORK IN PROGRESS -- the following is not done:
- bunch of stuff still not implemented (working through case by case)
- publish package correctly for CLI command to work (need to check)
- data() preamble -- if there is preamble maybe just create refs then use the function to set them
- handle setup() in options api
- allow options to configure (eg. no typescript)
- $el needs to try to rewrite part of template
- would like to maintain indentation
After running, check for FIXME comments
Composition API does not allow easy access of app.config.globalProperties like options API does.
vue-o2c takes care of some basic cases (eg. this.$router assuming vue-router) but for others, you will
see comments like the following and you must adjust the code depending on how you provide these systems.
const $primevue = inject("primevue") /* FIXME vue-o2c */
Usage
via CLI
This is not working due to a publishing issue I need to fix...
$ npx vue-o2c /path/to/sfc.vue
...
<transformed sfc code>
...
Programmatically
$ pnpm add -D vue-o2c
Please keep in mind, API is very experimental and likely will change!
import { transformPath, transform, type State } from "vue-o2c"
const s1: State = transformPath("/path/to/sfc.vue")
const s2: State = transform("<script>\nexport default {\n  props: {\n    a: String,\n  }\n}\n</script>")
// s1.transformed and s2.transformed will both contained transformed code
Example
Given the following file:
<template lang="pug">
div
  p Wonderful
</template>
<script>
export default {
  props: {
    greeting: {
      type: String,
      default: "Hello",
    },
  },
  data() {
    // this.initializing = true -- would make data() "complex" (need to improve)
    return {
      name: this.$route.query.name || 'John',
      watchMethod: 0,
      watchObject: {
        key: 1,
      },
    }
  },
  methods: {
    meth() {
      console.log(`${this.greeting} ${this.name} ${this.$el.clientHeight}`)
    },
    keyValue: async (a) => {
      await a
    },
  },
  mounted() {
    this.meth()
    this.keyValue()
    delete this.initializing // should not become `delete initializing` (so use $this)
  },
  watch: {
    ["watchMethod"](v) {
      console.log("watchMethod", v)
    },
    "watchObject.key": {
      deep: true,
      immediate: true,
      async handler(v, ov) {
        console.log("watchObject", v, ov)
      },
    },
  },
}
</script>
<style scoped>
:root {
  background: red;
}
</style>
$ git clone [email protected]:tjk/vue-o2c.git
$ cd vue-o2c
$ pnpm i
$ pnpm exec tsx index.ts ./example.vue
Will output the following:
<template lang="pug">
div(ref="$el")
  p Wonderful
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from "vue"
import { useRoute } from "vue-router"
const props = withDefaults(defineProps<{
  greeting?: string
}>(), {
  greeting: "Hello",
})
const $route = useRoute()
const $this = {}
const $el = ref<HTMLElement | undefined>()
const name = ref($route.query.name || 'John')
const watchMethod = ref(0)
const watchObject = ref({
  key: 1,
})
onMounted(() => {
  meth()
  keyValue()
  delete $this.initializing // should not become `delete initializing` (so use $this)
})
watch(() => watchMethod.value, (v) => {
  console.log("watchMethod", v)
})
watch(() => watchObject.value.key, async (v, ov) => {
  console.log("watchObject", v, ov)
}, {
  deep: true,
  immediate: true,
})
function meth() {
  console.log(`${props.greeting} ${name.value} ${$el.value.clientHeight}`)
}
async function keyValue(a) {
  await a
}
</script>
<style scoped>
:root {
  background: red;
}
</style>