You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
render(h){return(<div// Component propspropsMsg="hi"// Normal attributes or component props.id="foo"// DOM properties are prefixed with `domProps`domPropsInnerHTML="bar"// event listeners are prefixed with `on` or `nativeOn`onClick={this.clickHandler}nativeOnClick={this.nativeClickHandler}// other special top-level propertiesclass={{foo: true,bar: false}}style={{color: 'red',fontSize: '14px'}}key="key"ref="ref"// assign the `ref` is used on elements/components with v-forrefInForslot="slot"></div>)}
以上jsx语法糖等同于如何h函数生成VNode:
render(h){returnh('div',{// Component propsprops: {msg: 'hi'},// Normal HTML attributesattrs: {id: 'foo'},// DOM propsdomProps: {innerHTML: 'bar'},// Event handlers are nested under "on", though// modifiers such as in v-on:keyup.enter are not// supported. You'll have to manually check the// keyCode in the handler instead.on: {click: this.clickHandler},// For components only. Allows you to listen to// native events, rather than events emitted from// the component using vm.$emit.nativeOn: {click: this.nativeClickHandler},// Class is a special module, same API as `v-bind:class`class: {foo: true,bar: false},// Style is also same as `v-bind:style`style: {color: 'red',fontSize: '14px'},// Other special top-level propertieskey: 'key',ref: 'ref',// Assign the `ref` is used on elements/components with v-forrefInFor: true,slot: 'slot'})}
Vue JSX插件依赖及语法实践
文章内容主要分两块。
第一块是了解jsx运行环境,因为jsx只是语法糖,最终都是需要babel来转译语法,所以需要配置相关babel插件。vue-cli3脚手架工具生成的应用工程默认支持jsx/tsx,省去了自己配置的繁琐,但了解相关babel插件对理解和书写jsx非常有帮助。
第二块是实践jsx在vue中的语法以及相关案例。了解jsx是如何生成最终的VNode。tsx应用Demo代码放在github vue-tsx-demo
1. 环境基础babel
vue-cli3自动生成的app项目中,babel.config.js预设了
presets: ["@vue/app"],该插件为babel-preset-app
里面包含插件,主要是babel解析,以支持许多扩展语法。比如
jsx、es6语法
等:里面重点插件有:
1.1 Babel JSX插件集合
1.2 Babel预设插件集合
直接支持ES6模块语法,浏览器能自己解析import语法
,可显著减少包体积)。注意:指定esmodules目标时,浏览器目标将被忽略启用将ES6模块语法转换为其他模块类型的功能
。"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false,默认为"auto"。设置为false不会转换模块
1.3 其他
2. JSX在Vue中语法
react和vue底层vnode diff对比不是使用相同的数据结构,所以导致两者jsx书写方式有些许不同。目前两者大部分jsx语法一致,是因为有各种babel插件辅助做了这部分事。但对于动态属性这样自由化较高的地方,需要我们知道两者本质区别(即不同的VNode数据结构)。
vue template模板本质上最终生成render函数,而render函数本质上是生成VNode,所以有必要了解这个VNode数据结构。Vue2.x VNode diff核心算法借鉴的是snabbdom库,所以数据结构也有snabbdom数据结构的影子,比如事件需要放置在on属性上,方便最终patch时挂载到真实dom元素上(react则自定义模拟事件系统,所有事件都冒泡到顶层document处理)。更多VNode信息可查看Vue官方文档 - 深入数据对象。
以下查看jsx转译为h函数:
以上jsx语法糖等同于如何h函数生成VNode:
使用jsx代替vue需要解决的系列问题:
2.1 基础语法
bable jsx插件会通过正则匹配的方式在编译阶段将书写在组件上属性进行“分类”。 onXXX的均被认为是事件,nativeOnXXX是原生事件,domPropsXXX是Dom属性。
class,staticClass,style,key,ref,refInFor,slot,scopedSlots这些被认为是顶级属性,至于我们属性声明的props,以及html属性attrs,不需要加前缀,插件会将其统一分类到attrs属性下,然后在运行阶段根据是否在props声明来决定属性归属(即属于props还是attrs)。
2.2 动态属性
在React中所有属性都是顶级属性,直接使用{...props}就可以了,但是在Vue中,你需要明确该属性所属的分类,如一个动态属性value和事件change,你可以使用如下方式(延展属性)传递:
尽量使用明确分类的方式传递属性,而不是要babel插件帮你分类及合并属性。
2.3 指令
常用的v-if和v-for,使用js语法中的if/for语句就能实现了。v-model属于prop + input事件语法糖,也可以使用babel插件自动实现。
2.4 slot插槽
slot直接通过
this.$slots
对象拿到,scopedSlot通过this.$scopedSlots
对象拿到($scopedSlots每项是待调用函数)。2.5 组件
不需要注册,直接使用
2.6 functional函数
2.7 v-model
安装
@vue/babel-sugar-v-model
babel插件后即可自动解析v-model,官方更推荐使用vModel
或者value + onInput事件
。参考文章
The text was updated successfully, but these errors were encountered: