html选择年vue,为什么选择vue.js?

本文介绍了Vue.js的诞生背景和MVVM框架,强调了Vue.js在移动Web应用中的优势,如数据绑定使得视图自动更新,组件化让网页开发更加模块化。Vue.js的特点包括其轻量级、快速和易于上手,适合用于需要频繁DOM操作和组件复用的项目。但需要注意的是,Vue.js不支持IE8及以下浏览器。

为什么选择vue.js?下面本篇文章就来给大家介绍一下。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

009cbc339b5fee5ffde3827dc7fa07a4.png

诞生背景

近几年来,得益于手机设备的普及和性能的提升,移动端的web需求大量增加,产生了一种叫webapp的东西,也就是移动端的网页应用。

它们功能越来越复杂,交互也越来越酷炫,功能与效果越来越接近于原生的APP。比如下面这些:

3a102a5da301b5256333e67d1a67f809.png

b273c7386208bce4960452d74c93ebd7.png

(效果直逼原生APP)

这种webapp它们不仅仅像h5营销网页一样有酷炫的效果,它们还有复杂的点击、输入、下拉选择,视图切换等复杂的交互。在这样的业务需求下,我们还是沿用PC端的开发方案,难免会不太合适。比如:视图切换。

在PC端,视图切换我们会用标签进行页面的跳转,但如果在移动端,那就歇菜了,你会遇到这样的画面:

cba9d2b47263fc032376b80b8b1510ab.png

(等到花儿都谢了)

这个时候用户只能等.....3秒,5秒,8秒.......很难想象,在一个需要频繁切换视图的webapp里面,使用标签去实现,对用户来说是很不友好的,换你你也不愿意等那么久,反正我是不愿意了....

此外,接收用户输入的同时,很可能要及时更新视图,比如用户输入不同的内容,页面就会相对应进行更新,点击不同的选项,就会显示不同的状态等等交互效果。一旦这种交互多了,你要手动地进行操作,代码就容易变得复杂和难以维护。

为了解决webapp这些的体验和开发上的不足,我们决定学习并使用一个MVVM框架——Vue.js

什么是MVVM

MVVM可以拆分成:View --- ViewModel --- Model三部分 ,看下面的视图:

0c30512c57ffffc8e27677782f5ba10d.png

那么,我们怎么理解MVVM呢?

上图中,左侧的View相当于我们的DOM内容,我们所看到的页面视图,右侧的Model相当于我们的数据对象,比如一个对象的信息:{

name:"张三",

age:21,

}

而中间的监控者就负责监控两侧的数据,并相对应地通知另一侧进行修改。比如:你在Model层中修改了name的值为:“李四”,那么View视图层显示的“张三”也会自动变成了“李四”,而这个过程就是有ViewModel来操作的,不需要你手动地去写代码去实现(你不用再手动操作DOM了)。

如果你写过复杂的DOM操作,你就可以感受到它带来的便利。

这就是MVVM框架,属于MVVM的JS框架除了Vue.js,还有React.js,Angular.js。

这里我们不去分析具体这3个框架哪个更好,关于技术选型,每个开发团队的情况都不一样,考虑的因素也不一样,只要合适自己就好。这里我们只说一下Vue.js的优点:Vue.js更轻量更快

更容易上手,易学

Vue的核心

铺垫了这么多,终于讲到了Vue的核心。

那么,我们就来认识一下Vue.js,这里摘取一段官网对它的介绍:通过尽可能简单的API实现响应的数据绑定和组合的视图组件

这句话有两个关键词:数据绑定和视图组件。

Vue的数据驱动:数据改变驱动了视图的自动更新,传统的做法你得手动改变DOM来改变视图,vuejs只需要改变数据,就会自动改变视图,一个字:爽。再也不用你去操心DOM的更新了,这就是MVVM思想的实现。

视图组件化:把整一个网页的拆分成一个个区块,每个区块我们可以看作成一个组件。网页由多个组件拼接或者嵌套组成。看下图:

76dc7cdad2525595bcccf33f9b5b8032.png

具体在开发过程中怎样实现一个组件,到底哪些区块可以划分成一个组件,后面的章节我们再一一介绍,这里你只需要知道,在Vue.js中,网页是可以看成多个组件组成的即可。

适用场景

如果你还在用jquery频繁操作你的DOM来更新页面的话,那么,你可以用Vue.js来解放你的DOM操作了。

如果你的项目中有多个部分是相同的,并可以封装成一个组件,那么,你可以试试用Vue.js。

此外,Vue.js的核心实现中使用了ES5的Object.defineProperty特性,IE8及以下版本浏览器是不兼容的,所以,你的项目需要兼容这些较低版本的浏览器的话,那么,Vue.js就不适用了。

毕竟,开发一个项目的目的不是为了使用某个框架。

小结

为了更好满足当前移动webapp项目的开发需求,MVVM框架诞生,而Vue.js便是这样的一种js框架,其两大核心:数据驱动和组件化。

更多web开发知识,请查阅 HTML中文网 !!

勾选复选框依旧报错如下:vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'record' of null" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'record' of null at fn (Autoreposition.vue?b778:2730) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'record' of null" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'record' of null at fn (Autoreposition.vue?b778:2748) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'text' of undefined" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'text' of undefined at fn (Autoreposition.vue?b778:2766) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'record' of null" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'record' of null at fn (Autoreposition.vue?b778:2730) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'record' of null" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'record' of null at fn (Autoreposition.vue?b778:2748) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'text' of undefined" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'text' of undefined at fn (Autoreposition.vue?b778:2766) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'record' of null" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'record' of null at fn (Autoreposition.vue?b778:2730) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'record' of null" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'record' of null at fn (Autoreposition.vue?b778:2748) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906) logError @ vue.runtime.esm.js?2b0e:1888 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'text' of undefined" found in ---> <TableCell> <BodyRow> <TableRow> <ConnectTableRow> <ProxyConnectTableRow> <ExpandableRow> <ConnectExpandableRow> <ProxyConnectExpandableRow> <BaseTable> <ConnectBaseTable> <ProxyConnectBaseTable> <BodyTable> <ExpandableTable> <ConnectExpandableTable> <ProxyConnectExpandableTable> <StoreProvider> <Table> <Table> <LocaleReceiver> <ASpin> <Table> <ATable> <Anonymous> <Anonymous> <Portal> <PortalWrapper> <Anonymous> <AModal> <AFormModel> <Process> <PageToggleTransition> at src/components/transition/PageToggleTransition.vue <Anonymous> <ALayoutContent> <Anonymous> <ALayout> <Anonymous> <ALayout> <AdminLayout> at src/layouts/AdminLayout.vue <TabsView> at src/layouts/tabs/TabsView.vue <ALocaleProvider> <LocaleReceiver> <AConfigProvider> <App> at src/App.vue <Root> warn @ vue.runtime.esm.js?2b0e:619 logError @ vue.runtime.esm.js?2b0e:1884 globalHandleError @ vue.runtime.esm.js?2b0e:1879 handleError @ vue.runtime.esm.js?2b0e:1839 Vue._render @ vue.runtime.esm.js?2b0e:3550 updateComponent @ vue.runtime.esm.js?2b0e:4066 get @ vue.runtime.esm.js?2b0e:4479 run @ vue.runtime.esm.js?2b0e:4554 flushSchedulerQueue @ vue.runtime.esm.js?2b0e:4310 eval @ vue.runtime.esm.js?2b0e:1980 flushCallbacks @ vue.runtime.esm.js?2b0e:1906 Promise.then (async) timerFunc @ vue.runtime.esm.js?2b0e:1933 nextTick @ vue.runtime.esm.js?2b0e:1990 queueWatcher @ vue.runtime.esm.js?2b0e:4402 update @ vue.runtime.esm.js?2b0e:4544 Vue.$forceUpdate @ vue.runtime.esm.js?2b0e:3969 handleChange @ Checkbox.js?d994:76 invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1854 invoker @ vue.runtime.esm.js?2b0e:2179 original._wrapper @ vue.runtime.esm.js?2b0e:6917 vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'text' of undefined at fn (Autoreposition.vue?b778:2766) at normalized (vue.runtime.esm.js?2b0e:2590) at Proxy.render (TableCell.js?22d5:80) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3548) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4066) at Watcher.get (vue.runtime.esm.js?2b0e:4479) at Watcher.run (vue.runtime.esm.js?2b0e:4554) at flushSchedulerQueue (vue.runtime.esm.js?2b0e:4310) at Array.eval (vue.runtime.esm.js?2b0e:1980) at flushCallbacks (vue.runtime.esm.js?2b0e:1906)
最新发布
11-21
你遇到了一个 **非常典型但极其棘手的 ant-design-vue 表格组件渲染生命周期问题**。 > 🔥 从错误堆栈看:`TypeError: Cannot read property 'record' of null` 出现在 `TableCell.js` 的 `render` 阶段,说明某个插槽(slot)在 Vue 渲染时接收到的是 `null` 而不是预期的对象 `{ text, record }`。 > 并且这个错误发生在 **复选框勾选后触发更新时** → 是典型的“响应式更新过程中作用域插槽上下文丢失”问题。 --- ## ✅ 根本原因分析 ### ❓ 为什么“一勾选就报错”? 1. 当你点击复选框: - 触发了 `rowSelection.onChange(selectedRowKeys, selectedRows)` - 更新了 `this.selectedSpecRows` - Vue 响应式系统开始重新渲染 `<a-table>` 2. 在重渲染期间,ant-design-vue 内部某些列的 `scopedSlots` 会**先于数据准备完成阶段被调用** 3. 此时传递给你的模板的作用域变量是 `null`(比如 `{ text: undefined, record: null }`) 4. 你在模板中写 `record.usl` → 访问 `null.usl` → 💥 报错 👉 即使你加了 `v-if="record"`,也有可能在 `v-model="record.usl"` 解析阶段就已经出错了 —— 因为 Vue 模板编译器会在渲染函数里提前解析这些绑定。 --- ## ✅ 终极解决方案(四步彻底解决) ### ✅ 第一步:使用 `render` 函数代替 `scopedSlots`(关键!) 不要用 `<template #xxx="{ record }">`,改用 `render: (text, record) => VNode` 这样你可以完全控制何时访问 `record`,避免 `null` 场景。 #### 修改前 ❌: ```js this.EdcPlanSpecColumns = [ { title: 'U', dataIndex: 'usl', scopedSlots: { customRender: 'usl' } } ]; ``` ```html <template #usl="{ record }"> <a-input-number v-model="record.usl" /> </template> ``` #### 修改后 ✅: ```js this.EdcPlanSpecColumns = [ { title: 'U', dataIndex: 'usl', render: (text, record) => { if (!record) return <span>-</span>; return ( <a-input-number value={record.usl} onInput={(value) => (record.usl = value)} style="width: 100%" precision={4} /> ); } }, { title: 'L', dataIndex: 'lsl', render: (text, record) => { if (!record) return <span>-</span>; return ( <a-input-number value={record.lsl} onInput={(value) => (record.lsl = value)} style="width: 100%" precision={4} /> ); } }, { title: 'Unit', dataIndex: 'unit', render: (text, record) => { if (!record) return <span>-</span>; return ( <a-select value={record.unit} onSelect={(value) => (record.unit = value)} style="width: 100%" > {this.unitOptions.map(opt => ( <a-select-option key={opt} value={opt}> {opt} </a-select-option> ))} </a-select> ); } } ]; ``` > ⚠️ 注意:这里使用了 JSX / render 函数语法,你需要确保项目支持。 --- ### ✅ 第二步:确保 Babel 支持 JSX(必须配置) 如果你没配过 JSX,需要安装和配置: #### 1. 安装依赖: ```bash npm install @vue/babel-preset-jsx @vue/babel-plugin-transform-vue-jsx -D ``` #### 2. `.babelrc` 或 `babel.config.js` 加入: ```json { "presets": ["@vue/babel-preset-jsx"], "plugins": ["@vue/babel-plugin-transform-vue-jsx"] } ``` 或 `babel.config.js`: ```js module.exports = { presets: ['@vue/cli-plugin-babel/preset'], plugins: ['@vue/babel-plugin-transform-vue-jsx'] }; ``` ✅ 然后就可以在 `methods`、`computed`、`created` 等地方使用 `render: () => <div />` 了。 --- ### ✅ 第三步:强制刷新表格(防缓存 bug) 虽然你现在用了 `render`,但为了防止 ant-design-vue 内部状态残留,继续保留 `key` 控制: ```html <a-table :key="isSpecModalVisible + selectedSpecRows.length" :dataSource="edcPlanSpec" :columns="EdcPlanSpecColumns" :rowSelection="rowSelection" :pagination="false" bordered :rowKey="record => record.key" /> ``` 👉 每次选择变化都会触发一次轻量级重建,避免上下文错乱。 --- ### ✅ 第四步:安全初始化所有字段 确保每条数据都有默认值,防止深层访问崩溃: ```js this.edcPlanSpec = (res.data.data.measurementSpec || []).map((item, idx) => ({ key: idx, name: item.name || '-', usl: typeof item.usl === 'number' ? item.usl : null, lsl: typeof item.lsl === 'number' ? item.lsl : null, unit: item.unit || '' })); ``` --- ## ✅ 最终效果验证 做完以上四步后你应该能实现: | 功能 | 是否正常 | |------|---------| | 弹窗打开 | ✅ | | 显示 U/L/Unit 列 | ✅ | | 输入框可编辑 | ✅ | | 复选框可勾选 | ✅ 不再报错 | | 已选数据同步 | ✅ | --- ## ✅ 附加建议:关闭弹窗时清空选择 避免下次打开还带着上次的选择: ```js <a-modal v-model="isSpecModalVisible" @cancel="handleModalCancel" title="规格设置" > ``` ```js methods: { handleModalCancel() { this.selectedSpecRows = []; } } ``` --- ## ✅ 总结:为何 `scopedSlots` 会失败而 `render` 成功? | 对比项 | `scopedSlots` 模板语法 | `render` 函数 | |-------|------------------------|---------------| | 执行时机 | 由 antdv 内部调用,不可控 | 你直接定义函数,可加判断 | | `record` 为空时 | 直接传 `null` 导致模板崩溃 | 可以 `if (!record) return '-'` | | 安全性 | ❌ 低(易出错) | ✅ 高(完全可控) | | 推荐程度 | ⚠️ Vue 2 中慎用复杂 `scopedSlots` | ✅ 强烈推荐用于动态表单 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值