2021-12-12 00:04:38 +08:00
# @vue/reactivity-transform
2021-08-23 10:21:42 +08:00
> ⚠️ This is experimental and currently only provided for testing and feedback. It may break during patches or even be removed. Use at your own risk!
>
> Follow https://github.com/vuejs/rfcs/discussions/369 for details and updates.
## Basic Rules
2021-12-12 00:04:38 +08:00
- Ref-creating APIs have `$` -prefixed versions that create reactive variables instead. They also do not need to be explicitly imported. These include:
- `ref`
- `computed`
- `shallowRef`
- `customRef`
- `toRef`
- `$()` can be used to destructure an object into reactive variables, or turn existing refs into reactive variables
- `$$()` to "escape" the transform, which allows access to underlying refs
2021-08-23 10:21:42 +08:00
```js
2021-12-12 00:04:38 +08:00
import { watchEffect } from 'vue'
2021-08-23 10:21:42 +08:00
// bind ref as a variable
2021-12-12 00:04:38 +08:00
let count = $ref(0)
2021-08-23 10:21:42 +08:00
2021-12-12 00:04:38 +08:00
watchEffect(() => {
// no need for .value
console.log(count)
})
2021-08-23 10:21:42 +08:00
// assignments are reactive
count++
2021-12-12 00:04:38 +08:00
// get the actual ref
console.log($$(count)) // { value: 1 }
```
Macros can be optionally imported to make it more explicit:
```js
// not necessary, but also works
import { $, $ref } from 'vue/macros'
let count = $ref(0)
const { x, y } = $(useMouse())
2021-08-23 10:21:42 +08:00
```
2021-12-12 00:04:38 +08:00
### Global Types
2021-08-23 10:21:42 +08:00
2021-12-12 00:04:38 +08:00
To enable types for the macros globally, include the following in a `.d.ts` file:
2021-08-23 10:21:42 +08:00
2021-12-12 00:04:38 +08:00
```ts
/// < reference types = "vue/macros-global" / >
```
2021-08-23 10:21:42 +08:00
## API
This package is the lower-level transform that can be used standalone. Higher-level tooling (e.g. `@vitejs/plugin-vue` and `vue-loader` ) will provide integration via options.
2021-08-23 22:45:58 +08:00
### `shouldTransform`
Can be used to do a cheap check to determine whether full transform should be performed.
```js
2021-12-12 00:04:38 +08:00
import { shouldTransform } from '@vue/reactivity-transform'
2021-08-23 22:45:58 +08:00
shouldTransform(`let a = ref(0)`) // false
shouldTransform(`let a = $ref(0)`) // true
```
2021-08-23 10:21:42 +08:00
### `transform`
```js
2021-12-12 00:04:38 +08:00
import { transform } from '@vue/reactivity-transform'
2021-08-23 10:21:42 +08:00
const src = `let a = $ref(0); a++`
const {
code, // import { ref as _ref } from 'vue'; let a = (ref(0)); a.value++"
map
} = transform(src, {
filename: 'foo.ts',
sourceMap: true,
2021-08-24 00:20:53 +08:00
// @babel/parser plugins to enable.
// 'typescript' and 'jsx' will be auto-inferred from filename if provided,
// so in most cases explicit parserPlugins are not necessary
2021-09-28 02:24:21 +08:00
parserPlugins: [
/* ... */
]
2021-08-23 10:21:42 +08:00
})
```
**Options**
```ts
interface RefTransformOptions {
filename?: string
sourceMap?: boolean // default: false
parserPlugins?: ParserPlugin[]
importHelpersFrom?: string // default: "vue"
}
```
### `transformAST`
2021-08-23 22:45:58 +08:00
Transform with an existing Babel AST + MagicString instance. This is used internally by `@vue/compiler-sfc` to avoid double parse/transform cost.
2021-08-23 10:21:42 +08:00
```js
2021-12-12 00:04:38 +08:00
import { transformAST } from '@vue/reactivity-transform'
2021-08-23 10:21:42 +08:00
import { parse } from '@babel/parser'
import MagicString from 'magic-string'
const src = `let a = $ref(0); a++`
const ast = parse(src, { sourceType: 'module' })
const s = new MagicString(src)
const {
2021-09-28 02:24:21 +08:00
rootRefs, // ['a']
2021-08-23 10:21:42 +08:00
importedHelpers // ['ref']
} = transformAST(ast, s)
console.log(s.toString()) // let a = _ref(0); a.value++
```