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";
// 路由類型
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")
// 安一個(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)式的值的話 RefExample01 = ()= { return <div>2233</div> }
// 不使用defineComponent就沒有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 // 寫上這個(gè),vue可以讓你在render里拿到值
}
},
setup(props) {
return (
// 這樣寫也能拿到值
// 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')
}
}
}思考
- 是什么依賴Reactive值? 是我們的渲染在依賴它們
- 為什么不顯式指定Reactive值的依賴?
擁抱函數(shù)式,沒有辦法顯式的提供依賴,我們不確定值,setup時(shí)候知道,但是render渲染時(shí)候,沒有辦法給它依賴了
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? 可以被觀察的東西每個(gè) ref()的值
- Reactive === Observable ?
Reactive【響應(yīng)式,這個(gè)組件,這個(gè)值,在任何時(shí)候,像人一樣,有主動(dòng)思維,知道怎么響應(yīng)外部的環(huán)境,知道怎么去做】
Observable【設(shè)計(jì)模式,架構(gòu)手段,就是去觀察可以被觀察的東西】
到此這篇關(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ù)類型詳解(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-03
vue實(shí)現(xiàn)節(jié)點(diǎn)增刪改功能
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)節(jié)點(diǎn)增刪改功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
Vue3全局屬性app.config.globalProperties的實(shí)現(xiàn)
Vue3中的app.config.globalProperties是一個(gè)強(qiáng)大的全局配置功能,允許我們?cè)趹?yīng)用級(jí)別設(shè)置和訪問(wèn)屬性,本文主要介紹了Vue3全局屬性app.config.globalProperties的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
element-ui 表格sortable排序手動(dòng)js清除方式
這篇文章主要介紹了element-ui 表格sortable排序手動(dòng)js清除方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
vue?watch監(jiān)聽觸發(fā)優(yōu)化搜索框的性能防抖節(jié)流的比較
這篇文章主要為大家介紹了vue?watch監(jiān)聽觸發(fā)優(yōu)化搜索框的性能防抖節(jié)流的比較,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10

