vue项目中为什么用jsx,vue3.0 jsx

  vue项目中为什么用jsx,vue3.0 jsx

  本文主要介绍为什么推荐JSX开发vue3,帮助你更好的理解和使用vue框架。感兴趣的朋友可以了解一下。

  长期以来,Vue官方一直将推广重点放在简单的动手上。这确实给Vue带来了非常庞大的用户量,尤其是对需求开发效率的追求。

  在往往不太关心工程代码质量的国内中小企业中,Vue的份额增长很快。但是,作为开发商自己,我们必须认识到一个关键点。简单性和重用不应该在技术选择中占据很大份额,而是可维护性。

  万一有的同学真的不看公文,我先提一下。证监会是。在写vue组件时写的Vue文件。这个文件是一个SFC,全称是单文件组件,也就是单文件组件。

  在开始我的个人观点之前,我们先来看几个事实:

  是的,Vue3的定义原生支持JSX,Vue3源代码中有JSX.d.ts,方便使用JSX。不知道同学们看到这个会怎么想,

  我的第一反应是:社区对JSX的需求不小,所以会把Vue3对JSX的官方支持往后推。

  第二,AntDesign的vue3版本基本都是用JSX开发的,现在Vue3的官方babel-jsx插件最初都是阿里的人维护的。

  虽然我一直不喜欢阿里的KPI驱动技术,目前的JSX语法支持也不符合我的预期,但至少我认同AntDesign团队的观点,JSX开发是更好的选择。

  好了,说这些东西,主要是摆出一些事实作为依据,让有些同学什么都不用拿:

  啊,都是你想出来的。你太自我了。

  不管你怎么想,都没用。我们的Vue应该用SFC开发。

  这些观点批评我。首先我会从客观的角度分析一下为什么。至少,我能说出强弱的原因。

  好了,序言差不多到了。接下来我给大家分析一下为什么要选择JSX发展Vue。

  

TypeScript 支持

  其实第一点已经是杀手锏了。对于想用TypeScript开发Vue3应用的同学来说,这简直是SFC无法攻克的世界难题。

  总之:TypeScript原生支持JSX语法,但基本上不希望ts官方能支持SFC的模板语法。

  毫无疑问,ts在前端社区越来越重要,但任何一个未来对代码质量有一定要求的前端团队,都应该选择TS进行开发。

  现在基本上你可以在NPM上看到软件包,你可以找到相应的TS定义。现在用TS开发的成本只是你懂不懂TS语法。在这种情况下,你是否支持TS是未来发展模式不会走远的重要原因。

  目前SFC只能允许TS进口。vue文件,但是所有SFC组件的定义都是相同的:

  声明模块“*”。vue {

  从“vue”导入{ DefineComponent }

  const component:define component {},{},{ },any

  导出默认组件

  }

  也就是说你介绍的SFC组件TS不知道这个组件应该收到什么道具。所以你享受不到这些TS的优点:

  开发过程中自动提示

  编译时的TS检查允许您尽早发现问题。

  编译组件会生成您的组件定义(这对类库开发尤其重要)。

  当然你会说,既然Vue可以正式开发SFC的语法,自然会支持这些特性。我说当然可以,但是这个难度非常大,需要多方面的支持,甚至官方ts团队都愿意协助。

  但我想不出TS官方有什么理由支持SFC,因为这只是Vue自己创造的一种方言,其他场景用不到。TS是面向整个社区的,我认为他们不会考虑积极支持SFC。

  那么有同学要问了,JSX不也是非母语的JS语法吗?他怎样才能得到TS官方的支持?FB和微硬有PY交易吗?

  这让我想到了第二点,JSX和静态模板之间的灵活性差异。

  

JSX 其实并不是方言

  很多人都犯了一个错误,就是认为SFC的模板语法和JSX一样,是别人发明的语法,不是JS原生的。这是事实,但也有一些差异,这主要体现在对JSX的认识上。

  一句话:JSX没有扩展JS的语法,只是缩写了JS的写法!它的本质就是JS的语法糖。

  就像es6加的语法糖,比如

  常数a=1

  常数b=2

  const obj={ a,b }

  //实际上相当于

  const obj={ a: a,b: b }

  这种写法并没有拓展JS的能力,只是简单的让它变得更容易,JSX也是一样。

  JSX实际上是一个方法调用,JS和JS是一一对应的。让我们看一个例子:

  const element=div id= root hello World/div

  这里的JSX语法实际上是:

  const element=createElement( div ,{ id: root }, Hello World )

  而JSX就是全部,没有更多的内容,所以JSX只是一个方便我们编写嵌套函数调用的语法糖,它没有扩展任何其他内容。

  但是SFC不一样。

  SFC不仅定义语法,还定义文件。

  SFC的具体定义是单个文件组件,它本身就把一个文件当作一个单元,所以约束力要大得多。要使用SFC,您必须有一个固定的文件结构,这造成了许多限制:

  一个文件中只能写入一个组件。

  节点片段只能写在模板里,非常不灵活。

  一个变量绑定只能获取this的内容,而不能使用全局变量(很多时候我们要先在this上挂载全局变量)。

  让我们稍微谈一谈。

  

一个文件只能写一个组件

  说实话,这非常非常不方便。很多时候,我们在编写页面的时候,往往需要把一些小的节点片段拆分成小部件来复用(如果你现在没有这个习惯,可能是因为SFC的限制,你习惯把它们都写在一个文件里)。

  React生态系统中丰富的css-in-js方案就是一个很好的例子。我们可以使用:

  const styled button=styled( button ,{

  颜色:红色,

  })

  如果我们需要在这个页面中使用特定样式的按钮,通常会以这种方式将它们封装在页面文件中。因为不需要拆分这个组件,而且它不是一个可重用的组件,所以需要再次导入。

  Vue生态基本没有css-in-js的成熟方案,其实和这个限制有很大关系。

  我们再举一个例子。比如我们封装了一个Input组件,想把Password组件和Textarea组件都导出,方便用户根据实际需要使用。这两个组件是内部使用的输入组件,只是定制了一些道具:

  常量输入={.}

  导出默认输入

  导出常量Textarea=(props)=输入多行={true} {.道具} /

  导出常量密码=(props)=输入类型=密码 {.道具} /

  它可以在JSX非常简单地实现,但是如果它通过了SFC,你可能不得不强行把它分成三个文件。此外,为了方便起见,您可能需要添加一个index.js来导出这三个组件。你能想象这需要多少工作吗?

  

节点片段只能写在 template 里面,非常不灵活

  不知道有多少同学看过Vue的模板编译的代码。以我的经验来看,他们的阅读量可能不会超过50%(乐观估计)。如果还不知道的话建议同学们去尝试一下。

  为什么要看这个?因为看完之后你会发现你在模板里写的类似HTML的内容和HTMl完全没有关系,它们也会被编译成类似JSX编译的结果。

  {

  渲染(h) {

  返回h(div ,{on: {},props: {}},h(span ))

  }

  }

  类似的结果,这里H函数调用的结果是一个VNode,它是Vue中节点的基本单位。因为这些单元是一个对象,它们当然可以作为参数传递。

  也就是说,理论上他们可以通过props将节点作为参数传递给其他组件。

  这种做法在React中非常常见,称为renderProps,而且非常灵活:

  const Comp=()=Layout header={ my header/} footer={ my footer/}/

  但是由于SFC模板的限制,我们很难在SFC中编写道具上的节点:

  模板

  Layout:header= my header//Layout

  /模板

  这是不可能的,因为SFC定义了头绑定只能接受js表达式,而MyHeader/显然不是。

  

因为通过 props 传递不行,所以 Vue 才发明了 slot 插槽的概念

  虽然我们口口声声说Vue简单,但实际上ScopedSlots一度成为初学者理解Vue的噩梦,很多同学都被这种令人费解的范围害死了。

  让我们看一个ScopedSlots的例子:

  模板

  免费票

  模板v-slot:scope=ctx

  div{{ctx.name}}/div

  /模板

  /Comp

  /模板

  这里ctx是Comp中的属性,通过这种方式传出来,这样我们就可以在当前组件中调用父组件中的属性。这简直是理解的噩梦,但是实现与JSX类似的功能却非常简单:

  comp scope={ name=div { name }/div }/

  我们只是将一个函数传递给一个叫做scope的道具。这个函数接受一个name属性,这个属性将在Comp中被调用,name将被传入。

  简单来说,我们传入的是一个构建节点片段的函数。就这么简单。

  这是因为SFC的模板限制,导致灵活性不足。Vue需要创造概念和关键词来抹平这些不足,创造出来的概念自然引入了学习成本。

  其实我并不认同Vue比React好学的说法。如果你真的研究了所有的用法,总是试图用最合理的方式实现功能,那么Vue永远不会比React简单。

  

变量绑定只能获取this上面的内容,不能使用全局变量

  这体现在两个方面。一个是我们全局定义的一些固定数据,如果要在组件中使用,应该通过这个挂载到组件上。

  比如我们缓存一个城市的数据,基本不会改变,所以不需要把它挂载到组件上使其有响应性。但这在SFC中是做不到的,

  因为模板的执行上下文是在编译时绑定的。你在模板中访问的变量在编译时会自动绑定到这个,因为模板需要编译,字符串没有作用域也是这个概念。

  这在JSX已经不存在了:

  const citys=[]

  const Comp=()={

  返回citys.map(c=div{c}/div)

  }

  另一个方面是组件的使用。在SFC中,组件必须提前注册,因为我们在模板中写的只能是字符串,而不是具体的组件变量。

  那么模板中的组件和真正的组件对象只能通过字符串匹配来绑定。这带来了以下问题:

  增加注册组件的步骤,增加代码量。

  用字符串名注册自然会产生可能的冲突。

  模板解析组件支持不同的样式,比如MyComp和my-comp,很容易导致不同的样式。

  在JSX不存在这样的问题,因为JSX直接使用组件引用作为参数:

  const Comp={.}

  const App=()=Comp /

  

需要通过directive来扩展能力

  其实从上面可以看出,除了SFC本身的问题,Vue使用字符串模板也会带来很多灵活性的问题。

  最直接的证据就是Vue用directive来扩展功能(当然这不是Vue发明的,模板引擎早就有类似问题了)。

  为什么指令是最后的选择?因为静态模板缺乏逻辑处理的能力。我们以list循环为例。在JS中,我们可以很容易地通过map函数创建一个列表:

  const list=arr . map(name=span key={ name } { name }/span

  而且因为JSX本身就是一个函数调用,所以把上面的代码和JSX结合起来也是非常自然的:

  const App=()=(

  差异

  标题/

  {arr.map(name=(

  span key={name}{name}/span

  ))}

  /div

  )

  上述示例对应于JS,如下所示:

  const App=()=

  createElement(div ,{},[

  标题/,

  arr . map(name=createElement( span ,{ key: name },name)),

  ])

  这还是因为JSX只是JS的语法糖。在JSX可以实现的一切在JSX也可以实现。

  但是,SFC的模板是基于一个字符串编译的,这个字符串本身就是一个字符串。我们不能直接在模板中写map来循环节点(当然也可以写在可以接收表达式的地方,比如v-on)。

  所以不能循环节点,需要这样的函数来渲染列表。我们做什么呢就是发明一个标志告诉编译器这里需要一个循环,在Vue中的体现就是v-for指令。

  同学们可能要问了,既然Vue可以实现v-for,为什么不直接实现表达式循环链表呢?他当然可以实现,但他肯定不会选择,因为成本太高。

  他要做的事情相当于实现了一个JS引擎。其实里面很多内容都是不必要的,一个v-for其实可以适用于大多数情况。

  但是有了v-for,就需要v-if,然后后面就需要其他能力了。这是一种方言产生和发展的过程。

  当然,指令不仅仅是JS表达式的替代品,还增加了一些其他的能力,比如它可以让我们更容易的访问DOM节点。

  但是,我们之所以使用框架,是为了尽可能屏蔽DOM操作~

  

总结

  这是我对应该使用JSX还是SFC进行开发的分析。其实说到底,SFC的问题是不拥抱JS。

  他的语法是他自己发明的,需要一个JS实现的编译器让它在JS环境下运行,本质上是一个发明。

  我们不能否认发明确实有优点,但不能只看它不看问题。如果我们没能拥抱JS,自然就很难充分重用JS社区的优势。

  JS社区一直在蓬勃发展,有用的工具不断出现。然而,SFC想要使用JS社区的这些工具,必须自己实现另一个工具。我们可以统计一下SFC做的以下兼容性。

  vue-loader在webpack中的应用

  Eslint-plugin-vue到Eslint

  汇总插件-用于汇总的vue

  玩笑对玩笑

  Vetur用作代码提示

  基本上,我们需要等待Vue社区或者插件的官方开发,才能运行常用的工具。在babel和typescript的官方支持下,

  基本上,所有新的JS生态工具都是原生支持的。

  在Vue3准备的这个阶段,我们还是希望Vue社区能够用更好更规范的方式去开发。

  其实如果直接用JSX开发Vue3,我们会发现很多时候并不需要用到emit和attrs的概念。

  即使Vue3的JSX插件支持它,我们甚至可以放弃插槽。

  但由于Vue3必须考虑兼容Vue2,潜力巨大的Vue3总是显得畏首畏尾,很可惜。

  这就是为什么建议JSX开发Vue3。关于与JSX一起开发Vue3的更多信息,请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: