vue3的api解讀之ref和reactive示例詳解
構(gòu)造一個(gè)演示框架(VUE3)
- vue-router
- rollup-context
/src/examples/Helloworld.tsx
// import { createVNode, h } from "vue" export const HelloWorld = () => { // return h("h1", ["Hello world!!!"]) return <h1>Hello world!!!</h1> }
/src/mytypes.d.ts
// import type只引入type,不會(huì)執(zhí)行 import type { RouteRecordRaw } from "vue-router"; // 路由類(lèi)型 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是沒(méi)有的 // 框架是vite3 // 獲取去所有的/examples下的.tsx【typescript + jsx】文件 const examples = import.meta.glob("./examples/**/*.tsx") // 安一個(gè)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的屬性傳過(guò)去 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 <> <header><h2>項(xiàng)目實(shí)戰(zhàn)例子喲</h2></header> <div class="body"> <ul class="menu"> {props.routes.map(x => { return <li key={x.key}> <RouterLink to={x.path}>{x.key}</RouterLink> </li> })} </ul> <div class="content"> <RouterView /> </div> </div> </> }
/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"; // 使用響應(yīng)式的值,通過(guò)defineComponent創(chuàng)建, // 不用響應(yīng)式的值的話(huà) RefExample01 = ()= { return <div>2233</div> } // 不使用defineComponent就沒(méi)有setup()可以用 export const RefExample01 = defineComponent({ setup() { // ref是個(gè)代理,通過(guò).value獲取值 const count = ref(0) console.log('setup函數(shù)只執(zhí)行一次') // 渲染函數(shù) return () => { console.log('render函數(shù)每次都執(zhí)行') return ( <div> <button onClick={() => { count.value++ }}>+</button> {count.value} </div> ) } } }) export const RefExample02 = defineComponent({ setup() { // ref是個(gè)代理,通過(guò).value獲取值 const count = ref(0) console.log('setup函數(shù)只執(zhí)行一次') // 渲染函數(shù) return () => { console.log('render函數(shù)每次都執(zhí)行') return ( <div> <button onClick={() => { count.value++ }}>+</button> </div> ) } } }) export const RefExample03 = defineComponent({ setup() { // ref是個(gè)代理,通過(guò).value獲取值 const count = ref(0) console.log('setup函數(shù)只執(zhí)行一次') // 渲染函數(shù) return () => { return ( <div> <button onClick={() => { count.value++ }}>+</button> <Count1 count={count} /> <Counter count={count} /> </div> ) } } }) const Counter = ({ count }: { count: Ref<number> }) => { return <div>{count.value}</div> } const Count1 = defineComponent({ props: { // 需要映射屬性 count: { type: Object as PropType<Ref<number>>, // 給一個(gè)別名type required: true // 寫(xiě)上這個(gè),vue可以讓你在render里拿到值 } }, setup(props) { return ( // 這樣寫(xiě)也能拿到值 // props: { // count: Ref<number> // } ) => { return <div>{props.count.value}</div> } } })
/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 <div> <div>{state.a}</div> <div>{state.b}</div> </div> } } }) 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 <div> <div>{a.value}</div> <div>{b.value}</div> </div> } } }) // 防抖的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') } } }
思考
- 是什么依賴(lài)Reactive值? 是我們的渲染在依賴(lài)它們
- 為什么不顯式指定Reactive值的依賴(lài)?
擁抱函數(shù)式,沒(méi)有辦法顯式的提供依賴(lài),我們不確定值,setup時(shí)候知道,但是render渲染時(shí)候,沒(méi)有辦法給它依賴(lài)了
Vue提供的Reactive模式和vue.observable有什么區(qū)別?
const state = Vue.observable({ count: 0 }) const Demo = { render(h) { return h('button', { on: { click: () => { state.count++ }} }, `count is: ${state.count}`) } }
區(qū)別在于函數(shù)式
- 什么是Observable? 可以被觀(guān)察的東西每個(gè) ref()的值
- Reactive === Observable ?
Reactive【響應(yīng)式,這個(gè)組件,這個(gè)值,在任何時(shí)候,像人一樣,有主動(dòng)思維,知道怎么響應(yīng)外部的環(huán)境,知道怎么去做】
Observable【設(shè)計(jì)模式,架構(gòu)手段,就是去觀(guān)察可以被觀(guān)察的東西】
到此這篇關(guān)于vue3的api解讀-ref和reactive的文章就介紹到這了,更多相關(guān)vue3 ref和reactive內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3中的ref和reactive定義數(shù)組方式
- Vue3中關(guān)于ref和reactive的區(qū)別分析
- Vue3 響應(yīng)式 API 及 reactive 和 ref 的用法示例詳解
- vue3+ts數(shù)組去重方及reactive/ref響應(yīng)式顯示流程分析
- vue3中ref和reactive的用法和解析(推薦)
- 一步步從Vue3.x源碼上理解ref和reactive的區(qū)別
- Vue3關(guān)于響應(yīng)式數(shù)據(jù)類(lèi)型詳解(ref、reactive、toRef、及toRefs)
- vue3?中ref和reactive的區(qū)別講解
- vue3使用ref和reactive的示例詳解
相關(guān)文章
Vue+ElementUI實(shí)現(xiàn)表單動(dòng)態(tài)渲染、可視化配置的方法
這篇文章主要介紹了Vue+ElementUI實(shí)現(xiàn)表單動(dòng)態(tài)渲染、可視化配置的方法,需要的朋友可以參考下2018-03-03vue實(shí)現(xiàn)節(jié)點(diǎn)增刪改功能
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)節(jié)點(diǎn)增刪改功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09Vue3全局屬性app.config.globalProperties的實(shí)現(xiàn)
Vue3中的app.config.globalProperties是一個(gè)強(qiáng)大的全局配置功能,允許我們?cè)趹?yīng)用級(jí)別設(shè)置和訪(fǎng)問(wèn)屬性,本文主要介紹了Vue3全局屬性app.config.globalProperties的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01element-ui 表格sortable排序手動(dòng)js清除方式
這篇文章主要介紹了element-ui 表格sortable排序手動(dòng)js清除方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07vue?watch監(jiān)聽(tīng)觸發(fā)優(yōu)化搜索框的性能防抖節(jié)流的比較
這篇文章主要為大家介紹了vue?watch監(jiān)聽(tīng)觸發(fā)優(yōu)化搜索框的性能防抖節(jié)流的比較,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10