SoFunction
Updated on 2025-04-04

Detailed explanation of the API interpretation of Vue3's ref and reactive examples

Construct a demo framework (VUE3)

  • vue-router
  • rollup-context

Reactivity API: Core |

/src/examples/

// import { createVNode, h } from "vue"
export const HelloWorld = () => {
  // return h("h1", ["Hello world!!!"])
  return <h1>Hello world!!!</h1>
}

/src/

// import type only introduces type and will not executeimport type { RouteRecordRaw } from "vue-router";
//Route typetype MyRouteType = RouteRecordRaw &amp; {
  key: string
}

/src/

import { createApp } from 'vue'
import { createWebHashHistory, createRouter } from 'vue-router'
import App from './App'
import { MyRouteType } from './mytypes'
// rollup-context capability, webpack does not have// The framework is vite3// Get all .tsx【typescript + jsx】 files under /examplesconst examples = ("./examples/**/*.tsx")
// Install a vue-router@next// npm add vue-router@next
const routes: MyRouteType[] = []
const examplePromises = (examples)
  .map(x =&gt; examples[x])
  .map(f =&gt; f())
// All examplePromises are resolved(examplePromises)
  .then(list =&gt; {
    for (let module of list) {
      for (let key in module) {
        const Component = module[key]
        ({
          path: "/" + (),
          key,
          component: Component
        })
      }
    }
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    // Pass routes as the App property    const app = createApp(App, { routes })
    (router)
    ('#app')
  })

/src/

import { RouterLink, RouterView } from "vue-router"
import { MyRouteType } from "./mytypes"
import "./"
export default (props: {
  routes: MyRouteType[]
}) =&gt; {
  return &lt;&gt;
    &lt;header&gt;&lt;h2&gt;Project practical examples&lt;/h2&gt;&lt;/header&gt;
    &lt;div class="body"&gt;
      &lt;ul class="menu"&gt;
        {(x =&gt; {
          return &lt;li key={}&gt;
            &lt;RouterLink to={}&gt;{}&lt;/RouterLink&gt;
          &lt;/li&gt;
        })}
      &lt;/ul&gt;
      &lt;div class="content"&gt;
        &lt;RouterView /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/&gt;
}

/src/

* {
  margin : 0;
}
html, body {
  height : 100%;
}
#app {
  height: 100%;
}
header {
  height : 60px;
  line-height: 60px;
  padding-left: 20px;
  width : 100%;
  background-color: black;
  color : white;
}
.body {
  display: flex;
  width : 100%;
  height : 100%;
}
.menu {
  padding-top : 20px;
  width : 200px;
  border-right:  1px solid #f2f3f4;
  min-height: 100%;
}
.menu li a{
  text-decoration: none;
  color : #2377de;
}
.menu li a:visited {
  text-decoration: none;
  color : #2377de;
}
.menu li {
  list-style: none;
}
.content {
  margin : 10px;
  position: relative;
}

/src/examples/

import { defineComponent, PropType, Ref, ref } from "vue";
// Use responsive values ​​to create through defineComponent,// If you do not use the responsive value RefExample01 = ()= { return <div>2233</div> }// Without using defineComponent, there is no setup() to useexport const RefExample01 = defineComponent({
  setup() {
    // ref is a proxy, gets the value through .value    const count = ref(0)
    ('The setup function is executed only once')
    // Rendering function    return () =&gt; {
      ('render function executes every time')
      return (
        &lt;div&gt;
          &lt;button onClick={() =&gt; {
            ++
          }}&gt;+&lt;/button&gt;
          {}
        &lt;/div&gt;
      )
    }
  }
})
export const RefExample02 = defineComponent({
  setup() {
    // ref is a proxy, gets the value through .value    const count = ref(0)
    ('The setup function is executed only once')
    // Rendering function    return () =&gt; {
      ('render function executes every time')
      return (
        &lt;div&gt;
          &lt;button onClick={() =&gt; {
            ++
          }}&gt;+&lt;/button&gt;
        &lt;/div&gt;
      )
    }
  }
})
export const RefExample03 = defineComponent({
  setup() {
    // ref is a proxy, gets the value through .value    const count = ref(0)
    ('The setup function is executed only once')
    // Rendering function    return () =&gt; {
      return (
        &lt;div&gt;
          &lt;button onClick={() =&gt; {
            ++
          }}&gt;+&lt;/button&gt;
          &lt;Count1 count={count} /&gt;
          &lt;Counter count={count} /&gt;
        &lt;/div&gt;
      )
    }
  }
})
const Counter = ({ count }: {
  count: Ref&lt;number&gt;
}) =&gt; {
  return &lt;div&gt;{}&lt;/div&gt;
}
const Count1 = defineComponent({
  props: { // Mapping attributes are required    count: {
      type: Object as PropType&lt;Ref&lt;number&gt;&gt;, // Give an alias type      required: true // Write this, vue can let you get the value in render    }
  },
  setup(props) {
    return (
      // You can get value by writing this way      // props: {
      //   count: Ref&lt;number&gt;
      // }
    ) =&gt; {
      return &lt;div&gt;{}&lt;/div&gt;
    }
  }
})

/src/examples/

import {
  customRef,
  defineComponent,
  reactive,
  toRefs,
  unref,
  isRef,
} from "vue";
// /api/
export const ReactiveExample01 = defineComponent({
  setup() {
    const state = reactive({
      a: "123",
      b: 2
    })
    setTimeout(() =&gt; {
       = "456"
    }, 1000)
    setTimeout(() =&gt; {
       = 100
    }, 2000)
    return () =&gt; {
      return &lt;div&gt;
        &lt;div&gt;{}&lt;/div&gt;
        &lt;div&gt;{}&lt;/div&gt;
      &lt;/div&gt;
    }
  }
})
function getState() {
  const state = reactive({
    a: "123",
    b: 2
  })
  return toRefs(state)
}
export const ReactiveExample02 = defineComponent({
  setup() {
    const { a, b } = getState()
    // const { a, b } = toRefs(state) // batch ref    setTimeout(() =&gt; {
      // = "456" // reactive usage       = "456" // Ref usage    }, 1000)
    setTimeout(() =&gt; {
      //  = 100
       = 100
    }, 2000)
    return () =&gt; {
      return &lt;div&gt;
        &lt;div&gt;{}&lt;/div&gt;
        &lt;div&gt;{}&lt;/div&gt;
      &lt;/div&gt;
    }
  }
})
// Anti-shake customReffunction useDebouncedRef(value: string, delay = 200) {
  let timeout: number | undefined
  return customRef((track: () =&gt; void, trigger: () =&gt; void) =&gt; {
    return {
      get() {
        track()
        return value
      },
      set(newValue: any) {
        clearTimeout(timeout)
        timeout = setTimeout(() =&gt; {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}
export default {
  setup() {
    return {
      text: useDebouncedRef('hello')
    }
  }
}

think

  • What depends on Reactive value? It is our rendering that depends on them
  • Why not explicitly specify the dependency of Reactive value?

Embrace functional, there is no way to explicitly provide dependencies. We are not sure about the value, we know when setting up, but when rendering, there is no way to give it dependencies.

What is the difference between the Reactive mode provided by Vue?

const state = ({ count: 0 })
const Demo = {
    render(h) {
        return h('button', {
            on: { click: () => { ++ }}        
        }, `count is: ${}`)    
    }
}

The difference is the function

  • What is Observable? The value of each ref() that can be observed
  • Reactive === Observable ?

Reactive [Responsive, this component, this value, at any time, like a human, has active thinking, knows how to respond to external environments, and knows how to do it]

Observable [Design mode, architectural means, are to observe things that can be observed]

This is the end of this article about Vue3's API interpretation - ref and reactive. For more related vue3 ref and reactive content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!