目录
构造一个演示框架(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有什么区别?
Reactivity API: Core | Vue.js
// import { createVNode, h } from "vue"
export const HelloWorld = () => {
// return h("h1", ["Hello world!!!"])
return Hello world!!!
}
// import type只引入type,不会执行
import type { RouteRecordRaw } from "vue-router";
// 路由类型
type MyRouteType = RouteRecordRaw & {
key: string
}
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')
})
import { RouterLink, RouterView } from "vue-router"
import { MyRouteType } from "./mytypes"
import "./layout.css"
export default (props: {
routes: MyRouteType[]
}) => {
return <>
项目实战例子哟
>
}
* {
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;
}
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}
}
}
})
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')
}
}
}
拥抱函数式,没有办法显式的提供依赖,我们不确定值,setup时候知道,但是render渲染时候,没有办法给它依赖了
const state = Vue.observable({ count: 0 })
const Demo = {
render(h) {
return h('button', {
on: { click: () => { state.count++ }}
}, `count is: ${state.count}`)
}
}
区别在于函数式
Reactive【响应式,这个组件,这个值,在任何时候,像人一样,有主动思维,知道怎么响应外部的环境,知道怎么去做】
Observable【设计模式,架构手段,就是去观察可以被观察的东西】