vue3的api解读-ref和reactive

目录

构造一个演示框架(VUE3)

/src/examples/Helloworld.tsx

/src/mytypes.d.ts

/src/main.ts

/src/App.tsx

/src/layout.css

/src/examples/RefExample.tsx

/src/examples/ReactiveExample.tsx

思考

Vue提供的Reactive模式和vue.observable有什么区别?


构造一个演示框架(VUE3)

  • vue-router
  • rollup-context

Reactivity API: Core | Vue.js

/src/examples/Helloworld.tsx

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

Hello world!!!

}

/src/mytypes.d.ts

// import type只引入type,不会执行
import type { RouteRecordRaw } from "vue-router";
// 路由类型
type MyRouteType = RouteRecordRaw & {
  key: string
}

/src/main.ts

import { createApp } from 'vue'
import { createWebHashHistory, createRouter } from 'vue-router'
import App from './App'
import { MyRouteType } from './mytypes'
// rollup-context能力,webpack是没有的
// 框架是vite3
// 获取去所有的/examples下的.tsx【typescript + jsx】文件
const examples = import.meta.glob("./examples/**/*.tsx")
// 安一个vue-router@next
// npm add vue-router@next
const routes: MyRouteType[] = []
const examplePromises = Object.keys(examples)
  .map(x => examples[x])
  .map(f => f())
// examplePromises全部解析好
Promise.all(examplePromises)
  .then(list => {
    for (let module of list) {
      for (let key in module) {
        const Component = module[key]
        routes.push({
          path: "/" + key.toLocaleLowerCase(),
          key,
          component: Component
        })
      }
    }
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    // 把routes作为App的属性传过去
    const app = createApp(App, { routes })
    app.use(router)
    app.mount('#app')
  })

/src/App.tsx

import { RouterLink, RouterView } from "vue-router"
import { MyRouteType } from "./mytypes"
import "./layout.css"
export default (props: {
  routes: MyRouteType[]
}) => {
  return <>
    

项目实战例子哟

   
           
             
   
  }

/src/layout.css

* {
  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/RefExample.tsx

import { defineComponent, PropType, Ref, ref } from "vue";
// 使用响应式的值,通过defineComponent创建,
// 不用响应式的值的话 RefExample01 = ()= { return 
2233
} // 不使用defineComponent就没有setup()可以用 export const RefExample01 = defineComponent({   setup() {     // ref是个代理,通过.value获取值     const count = ref(0)     console.log('setup函数只执行一次')     // 渲染函数     return () => {       console.log('render函数每次都执行')       return (        
                    {count.value}        
      )     }   } }) export const RefExample02 = defineComponent({   setup() {     // ref是个代理,通过.value获取值     const count = ref(0)     console.log('setup函数只执行一次')     // 渲染函数     return () => {       console.log('render函数每次都执行')       return (        
                 
      )     }   } }) export const RefExample03 = defineComponent({   setup() {     // ref是个代理,通过.value获取值     const count = ref(0)     console.log('setup函数只执行一次')     // 渲染函数     return () => {       return (        
                                     
      )     }   } }) const Counter = ({ count }: {   count: Ref }) => {   return
{count.value}
} const Count1 = defineComponent({   props: { // 需要映射属性     count: {       type: Object as PropType>, // 给一个别名type       required: true // 写上这个,vue可以让你在render里拿到值     }   },   setup(props) {     return (       // 这样写也能拿到值       // props: {       //   count: Ref       // }     ) => {       return
{props.count.value}
    }   } })

/src/examples/ReactiveExample.tsx

import {
  customRef,
  defineComponent,
  reactive,
  toRefs,
  unref,
  isRef,
} from "vue";
// https://v3.vuejs.org/api/refs-api.html
export const ReactiveExample01 = defineComponent({
  setup() {
    const state = reactive({
      a: "123",
      b: 2
    })
    setTimeout(() => {
      state.a = "456"
    }, 1000)
    setTimeout(() => {
      state.b = 100
    }, 2000)
    return () => {
      return 
       
{state.a}
       
{state.b}
     
    }   } }) 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) // 批量ref     setTimeout(() => {       // state.a = "456" // reactive使用法       a.value = "456" // ref使用法     }, 1000)     setTimeout(() => {       // state.b = 100       b.value = 100     }, 2000)     return () => {       return
       
{a.value}
       
{b.value}
     
    }   } }) // 防抖的customRef function useDebouncedRef(value: string, delay = 200) {   let timeout: number | undefined   return customRef((track: () => void, trigger: () => void) => {     return {       get() {         track()         return value       },       set(newValue: any) {         clearTimeout(timeout)         timeout = setTimeout(() => {           value = newValue           trigger()         }, delay)       }     }   }) } export default {   setup() {     return {       text: useDebouncedRef('hello')     }   } }

思考

  • 是什么依赖Reactive值? 是我们的渲染在依赖它们
  • 为什么不显式指定Reactive值的依赖?

拥抱函数式,没有办法显式的提供依赖,我们不确定值,setup时候知道,但是render渲染时候,没有办法给它依赖了

Vue提供的Reactive模式和vue.observable有什么区别?

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

区别在于函数式

  • 什么是Observable? 可以被观察的东西每个 ref()的值
  • Reactive === Observable ?

Reactive【响应式,这个组件,这个值,在任何时候,像人一样,有主动思维,知道怎么响应外部的环境,知道怎么去做】

Observable【设计模式,架构手段,就是去观察可以被观察的东西】

你可能感兴趣的:(vue相关,#,vue3的api解读,vue.js,javascript,前端,typescript)