useSignal,虽然让我想起来了熟悉地SolidJS,但是看写法,这不就是vue3的ref吗?是的,看起来很像,那有没有类似reactive呢?
最近我又又双学习了一个新框架,qwik
真的没完没了了,
不过作为"前端娱乐圈战地记者",我继续帮大家踩雷。
💡 同系列阅读
- 学不完的框架,🐔啄不完的米,SolidJS,你到底爱谁?😘
- 🔥超级简单的Svelte,学不会你来打我
- 真心希望不会有烧不断地锁这篇文章!!!
💎 初识qwik
废话不多说,我们先上代码。一个简单的计数器功能
🚀useSignal
const App = component$(() => {
const count = useSignal(0);
return (
<>
<button onClick$={() => count.value++}>+</button>
<div>{count.value}</div>
</>
);
});
让我们给这个计数器加上监听事件(后面会详细讲)
useVisibleTask$(({ track }) => {
track(() => console.log(count.value))
})
sigal.gif
useSignal,虽然让我想起来了熟悉地SolidJS,但是看写法,这不就是vue3的ref吗?是的,看起来很像,那有没有类似reactive呢?
🚀useStore
当然有啊,useSignal是针对基本变量的。对于非基本类型可以使用useStore。
const App = component$(() => {
const data = useStore({count: 0})
return (
<>
<button onClick$={() => data.count++}>+</button>
<p>{data.count}</p>
</>
);
});
sigal.gif
useStore可以提供方法,不过比较复杂:
import {
$,
type QRL
} from "@builder.io/qwik";
type Store = {
count: number
add: QRL<(this: Store) => void>
}
const App = component$(() => {
const data = useStore<Store>({
count: 0,
add: $(function(this) {
this.count++;
})
})
return (
<>
<button onClick$={() => data.add()}>+</button>
<p>{data.count}</p>
</>
);
}
sigal.gif
🚀useComputed$
reactive有了,computed是不是也应该有啊,来了,它就是useComputed$
const capitalizedName = useComputed$(() => {
return count.value + 'mmdctjj';
});
useVisibleTask$(({ track }) => {
track(() => console.log(capitalizedName.value))
})
computer.gif
🚀useContext
那依赖注入有没有啊?抱歉,没有,因为qwik是基于jsx的框架,所以只有拿useContext来将就了
type Store = {
count: number
add: QRL<(this: Store) => void>
}
// 🚗 创建全局的上下文
const context = createContextId<Store>('uuid')
const App = component$(() => {
const data = useStore<Store>({
count: 0,
add: $(function(this)
this.count++;
})
})
// 🚗 provider数据
useContextProvider(context, data);
return (
<>
<button onClick$={() => data.add()}>+</button>
<p>{data.count}</p>
</>
);
}
const Child = component$(() => {
// 🚗 消费上下文
const data = useContext(context)
return (
<>
<Child />
</>
);
}
好吧,接下来我们说些不一样的
🚀useTask$oruseVisibleTask$
上面的例子中,我们所有的监听事件都是通过useVisibleTask$实现的。虽然它看起来和useEffect类似,但是却有着很大的区别。
这得从qwik的架构说起,首先qwik是个服务端渲染的框架,相当于Next.js(基于React服务端渲染框架)、Nuxt.js(基于Vue地服务端渲染框架),换句话说,它天生支持服务端渲染的前端框架。所以一个组件的生命周期是从服务器开始的。
useTask$ -------> RENDER ---> useVisibleTask$
|| --- SERVER or BROWSER --- | ----- BROWSER ----- ||
pause|resume
它们都是用来注册任务的钩子函数,这个任务在服务端仅仅执行一次,在客户端可能多次渲染。
下面是具体的区别
👉useTask$
useTask$首先在服务端执行一次,如果客户端使用track订阅依赖了,那么当客户端渲染之后触发更新时,任务会在客户端再次执行。如果没有track,那么仅仅在客户端执行一次。
const App = component$(() => {
const count = useSignal(0);
useTask$(({ track }) => {
track(() => console.log(count.value))
})
return (
<>
<button onClick$={() => count.value++}>+</button>
<div>{count.value}</div>
</>
);
});
task.gif
页面刷新后服务端也执行了一次任务
👉useVisibleTask$
useVisibleTask$:仅仅在浏览器执行,渲染之后立马执行,当订阅的参数发生改变时,任务会被再次执行。
const App = component$(() => {
const count = useSignal(0);
useVisibleTask$(({ track }) => {
track(() => console.log(count.value))
})
return (
<>
<button onClick$={() => count.value++}>+</button>
<div>{count.value}</div>
</>
);
});
taskvis.gif
它们还有一个特别重要的参数cleanup,每次新的任务被触发时,都会执行上次任务的cleanup。另外组件被移除时也会被执行。
useVisibleTask$(({ track, cleanup }) => {
// console.log('I am excuted!')
track(() => console.log(count.value))
cleanup(() => console.log('last'))
})
cleanup.gif
我们可以看到,每次任务触发都是先打印last,然后才是最新的count.value
另外,还有一个重要的配置项:{ strategy: 'document-ready' },此时,会在页面加载完毕立马执行。
useVisibleTask$(() => {
// 渲染完毕之后执行
console.log(2222)
})
useVisibleTask$(() => {
// document-ready立马执行
console.log(1111)
}, { strategy: 'document-ready' })
此时console的打印结果是先1111,然后是2222。
👉 帮它模拟完整的生命周期
综上,我们可以模拟出一个完整的生命周期,
唯一的瑕疵是before update会在组件销毁时和unmount一起执行一次。
useVisibleTask$(() => {
console.log('before mounted!')
}, { strategy: 'document-ready' })
useVisibleTask$(({ cleanup }) => {
console.log('mounted!')
cleanup(() => console.log('unmount'))
})
useVisibleTask$(({ track, cleanup }) => {
track(() => console.log('updated!', count.value))
cleanup(() => console.log('before update'))
})
💎 总结
qwik上线一年不到已经17.9k地star了,足见它地优秀了!
©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经