Vue中jsx不完全应用指南小结

前言:文章不介绍任务背景知识,没有原理说明,偏向于实践的总结和经验分享。

文章所有的代码是基于Vue CLI 3.x版本,不会涉及到一步步通过Webpack来配置JSX所需要的知识点。

在使用Vue开发项目时绝大多数情况下都是使用模板来写HTML,但是有些时候页面复杂又存在各种条件判断来显示/隐藏和拼凑页面内容,或者页面中很多部分存在部分DOM结构一样的时候就略显捉襟见肘,会写大量重复的代码,会出现单个.vue文件过长的情况,这个时候我们就需要更多的代码控制,这时候可以使用渲染函数。

渲染函数想必平时几乎没有人去写,因为写起来很痛苦(本人也没有写过)。更多的是在Vue中使用JSX语法。写法上和在React中差不多,但是功能上还是没有React中那么完善。

在写JSX的过程中不得考虑一个样式的问题,虽然可以直接在.vue文件中不写<tempate>部分,只写<script>和<style>部分,而不用担心样式作用域问题。但是更多的时候还是推荐直接使用.js的方式来写组件,这个时候就涉及到样式作用域的问题了。

在React的生态中,有很多CSS-IN-JS的解决方案,比如styled-jsx、emotion、styled-components等,目前最活跃和用户量最多的是styled-components,目前已经拥有良好的生态圈子。如果需要在样式中作一些像Sass/Less中的颜色计算,可以使用polished来实现,当然不止这么简单的功能。但是在Vue中可使用的方案就太少了,因为Vue使用模板来写HTML本身是开箱即用的样式scoped,在使用JSX写组件的时候就面临着样式问题,一种方案是在组件包裹<div>中取一个特殊的名字,然后样式都嵌套写在这个class下面,但是难免会遇到命名冲突的情况,而且每次还得变着花样取名称。此外,就是引入CSS-IN-JS在Vue对应的实现,但目前来看Styled-components官方提供了一个Vue版本的叫vue-styled-components和emotion的vue-emotion,但是用的人实在太少。像styled-components进行了重大更新和变化,但是Vue版本的还是最初的版本,而且有时候还出现样式不生效的情况。

接下来进入正题,从简单语法到经验分享(大牛请绕行)

基本用法

首先需要约定一下,使用JSX组件命名采用首字母大写的驼峰命名方式,样式可以少的可以直接基于vue-styled-components写在同一个文件中,复杂的建议放在单独的_Styles.js_文件中,当然也可以不采用CSS-IN-JS的方式,使用Less/Sass来写,然后在文件中import进来。

下面是一个通用的骨架:

import styled from 'vue-styled-components'

const Container = styled.div`
 heigth: 100%;
`

const Dashboard = {
 name: 'Dashboard',

 render() {
 return (
  <Container>内容</Container>
 )
 }
}

export default Dashboard

插值

在JSX中使用单个括号来绑定文本插值

<span>Message: {this.messsage}</span>
<!-- 类似于v-html -->
<div domPropsInnerHTML={this.dangerHtml}/>
<!-- v-model -->
<el-input v-model={this.vm.name} />

在jsx中不需要把v-model分成事件绑定和赋值二部分分开来写,因为有相应的babel插件来专门处理。

样式

在JSX中可以直接使用class="xx"来指定样式类,内联样式可以直接写成style="xxx"

<div class="btn btn-default" style="font-size: 12px;">Button</div>

<!-- 动态指定 -->
<div class={`btn btn-${this.isDefault ? 'default' : ''}`}></div>
<div class={{'btn-default': this.isDefault, 'btn-primary': this.isPrimary}}></div>
<div style={{color: 'red', fontSize: '14px'}}></div>

遍历

在JSX中没有v-for和v-if等指令的存在,这些全部需要采用Js的方式来实现

{/* 类似于v-if */}
{this.withTitle && <Title />}

{/* 类似于v-if 加 v-else */}
{this.isSubTitle ? <SubTitle /> : <Title />}

{/* 类似于v-for */}
{this.options.map(option => {
 <div>{option.title}</div>
})}

事件绑定

事件绑定需要在事件名称前端加上on前缀,原生事件添加nativeOn

<!-- 对应@click -->
<el-buton onClick={this.handleClick}>Click me</el-buton>
<!-- 对应@click.native -->
<el-button nativeOnClick={this.handleClick}>Native click</el-button>
<!-- 传递参数 -->
<el-button onClick={e => this.handleClick(this.id)}>Click and pass data</el-button>

注意:如果需要给事件处理函数传参数,需要使用箭头函数来实现。如果不使用箭头函数那么接收的将会是事件的对象event属性。

高级部分

在Vue中基于jsx也可以把组件拆分成一个个小的函数式组件,但是有一个限制是必需有一个外层的包裹元素,不能直接写类似:

const Demo = () => (
 <li>One</li>
 <li>Two</li>
)

必需写成:

const Demo = () => (
 <div>
  <li>One</li>
 <li>Two</li>
 </div>
)

而在React中可以使用空标签<></>和<react.Fragment></react.Fragment>来实现包裹元素,这里的空标签其实只是react.Fragment的一个语法糖。同时在React 16中直接支持返回数组的形式:

const Demo = () => [
 <li>One</li>
 <li>Two</li>
]

那么在Vue中就只能通过遍历来实现类似的功能,大体思路就是把数据先定义好数据然后直接一个map生成,当然如果说元素的标签是不同类型的那就需要额外添加标识来判断了。

{
 data() {
 return {
  options: ['one', 'two']
 }
 },

 render() {
 const LiItem = () => this.options.map(option => <li>{option}</li>)

 return (
  <div>
   <ul>
    <LiItem />
   </ul>
   </div>
 )
 }
}

事件修饰符

在基础部分简单介绍了事件的绑定用法,这里主要是补充一下事件修饰符的写法。

在模板语法中Vue提供了很多事件修饰符来快速处理事件的冒泡、捕获、事件触发频率、按键识别等。可以直接查看官方文档的事件&按键修饰符部分,这里把相关内容原样搬运过来:

修饰符 前缀
.passive &
.capture !
.once ~
.capture.once或.once.capture ~!

使用方式如下:

<el-button {...{
 '!click': this.doThisInCapturingMode,
 '!keyup': this.doThisOnce,
 '~!mouseover': this.doThisOnceInCapturingMode
}}>Click Me!</el-button>

下面给出的事件修饰符是需要在事件处理函数中写出对应的等价操作

修饰符 处理函数中的等价操作
.stop event.stopPropagation()
.prevent event.preventDefault()
.self if (event.target !== event.currentTarget) return
按键: .enter, .13 if (event.keyCode !== 13) return (对于别的按键修饰符来说,可将 13 改为另一个按键码)
修饰键: .ctrl, .alt, .shift, .meta if (!event.ctrlKey) return (将 ctrlKey 分别修改为 altKey、shiftKey 或者 metaKey)

下面是在事件处理函数中使用修饰符的例子:

methods: {
 keyup(e) {
 // 对应`.self`
 if (e.target !== e.currentTarget) return

 // 对应 `.enter`, `.13`
 if (!e.shiftKey || e.keyCode !== 13) return

 // 对应 `.stop`
 e.stopPropagation()

 // 对应 `.prevent`
 e.preventDefault()

 // ...
 }
}

ref和refInFor

在Vue中ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件。

注意:

  • 因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在
  • $refs不是响应式的,因此你不应该试图用它在模板中做数据绑定。

当 v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。

假如在jsx中想要引用遍历元素或组件的时候,例如:

const LiArray = () => this.options.map(option => (
 <li ref="li" key={option}>{option}</li>
))

会发现从this.$refs.li中获取的并不是期望的数组值,这个时候就需要使用refInFor属性,并置为true来达到在模板中v-for中使用ref的效果:

const LiArray = () => this.options.map(option => (
 <li ref="li" refInFor={true} key={option}>{option}</li>
))

插槽(v-slot)

在jsx中可以使用this.$slots来访问静态插槽的内容。

注意:在Vue 2.6.x版本后废弃了slot和slot-scope,在模板中统一使用新的统一语法v-slot指令。v-slot只能用于Vue组件和template标签。

<div class="page-header__title">
 {this.$slots.title ? this.$slots.title : this.title}
</div>

等价于模板的

<div class="page-header__title">
 <slot name="title">{{ title }}</slot>
</div>

在Vue官方文档中提到:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。因此像下面的示例是无法正常工作的

<current-user>
 {{ user.firstName }}
</current-user>

在<current-user>组件中可以访问到user属性,但是提供的内容却是在父组件渲染的。如果想要达到期望的效果,这个时候就需要使用作用域插槽了。下面是改写后的代码,更多知识点可以直接查看官方文档的作用域插槽

<!-- current-user组件定义部分 -->
<span>
 <slot v-bind:user="user">
  {{ user.lastName }}
 </slot>
</span>

<!-- current-user 使用 -->
<current-user>
 <template v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
 </template>
</current-user>

上面的示例其实就是官方的示例,这里需要说明的是,其实在Vue中所谓的作用域插槽功能类似于React中的Render Props的概念,只不过在React中我们更多时候不仅提供了属性,还提供了操作方法。但是在Vue中更多的是提供数据供父作用域渲染展示,当然我们也可以把方法提供出去,例如:

<template>
 <div>
 <slot v-bind:injectedProps="slotProps">
  {{ user.lastName }}
  </slot>
 </div>
</template>

<script>
 export default {
 data() {
  return {
  user: {
   firstName: 'snow',
   lastName: 'wolf'
  }
  }
 },

 computed: {
  slotProps() {
  return {
   user: this.user,
   logFullName: this.logFullName
  }
  }
 },

 methods: {
  logFullName() {
  console.log(`${this.firstName} ${this.lastName}`)
  }
 }
 }
</script>

在父组件中使用:

<current-user>
 <template v-slot:default="{ injectedProps }">
  <div>{{ injectedProps.user.firstName }}</div>
  <el-button @click="injectedProps.logFullName">Log Full Name</el-button>
 </template>
</current-user>

在上面的代码中我们实际上使用解构的方式来取得injectedProps,基于解构的特性还可以重命名属性名,在prop为undefined的时候指定初始值。

<current-user v-slot="{ user = { firstName: 'Guest' } }">
 {{ user.firstName }}
</current-user>

如果组件只有一个默认的插槽还可以使用缩写语法,将v-slot:default="slotProps"写成v-slot="slotProps",命名插槽写成v-slot:user="slotProps",如果想要动态插槽名还可以写成v-slot:[dynamicSlotName],此外具名插槽同样也有缩写语法,例如 v-slot:header可以被重写为#header

上面介绍了很多插槽相关的知识点足已说明其在开发过程中的重要性。说了很多在模板中如何定义和使用作用域插槽,现在进入正题如何在jsx中同样使用呢?

// current-user components
{
 data() {
 return {
  user: {
  firstName: 'snow',
  lastName: 'wolf'
  }
 }
 },

 computed: {
 slotProps() {
  return {
  user: this.user,
  logFullName: this.logFullName
  }
 }
 },

 methods: {
 logFullName() {
  console.log(`${this.firstName} ${this.lastName}`)
 }
 },

 render() {
 return (
  <div>
  {this.$scopedSlots.subTitle({
   injectedProps: this.slotProps
  })}
  </div>
 )
 }
}

然后在父组件中以jsx使用:

<current-user {...{
 scopedSlots: {
 subTitle: ({ injectedProps }) => (
  <div>
   <h3>injectedProps.user</h3>
  <el-button onClick={injectedProps.logFullName}>Log Full Name</el-button>
  </div>
 )
 }
}}></current-user>

指令

这里需要注意的是在jsx中所有Vue内置的指令除了v-show以外都不支持,需要使用一些等价方式来实现,比如v-if使用三目运算表达式、v-for使用array.map()等。

对于自定义的指令可以使用v-name={value}的语法来写,需要注意的是指令的参数、修饰符此种方式并不支持。以官方文档指令部分给出的示例v-focus使用为例,介绍二种解决办法:

1 直接使用对象传递所有指令属性

<input type="text" v-focus={{ value: true }} />

2 使用原始的vnode指令数据格式

{
 directives:{
 focus: {
  inserted: function(el) {
  el.focus()
  }
 }
 },

 render() {
 const directives = [
  { name: 'focus', value: true }
 ]

 return (
  <div>
   <input type="text" {...{ directives }} />
  </div>
 )
 }
}

过滤器

过滤器其实在开发过程中用得倒是不多,因为更多时候可以通过计算属性来对数据做一些转换和筛选。这里只是简单提及一下并没有什么可以深究的知识点。

在模板中的用法如下:

<!-- 在双花括号中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

在jsx中使用方法为:

<div>{this.$options.filters('formatDate')('2019-07-01')}</div>

注意:由于Vue全局的过滤器只用于模板中,如果需要用于组件的方法中,可以把过滤器方法单独抽离出一个公共Js文件,然后引入组件中,然后用于方法中。

一些简单经验分享

并不是说我们在开发Vue项目的时候一定要使用jsx的方式来写,但是多掌握一种方式来灵活变通,提高工作效率,扩展思路何尝不值得一试。而且,在有些场景下释放js的完全编程能力会让你更加能够得心应手。其实在使用模板方式的时候我们并没有完全采用组件的思维方式来做,或者说是做得不彻底,不纯粹,拆分的粒度不够。更多 的时候并没有考虑到组件怎么切分和抽象,多人协作的时候如何处理依赖并明确自己的功能点。

关于DOM属性、HTML属性和组件属性

在React中所有数据均挂载在props下,Vue则不然,仅属性就有三种:组件属性props,普通html属性attrs和DOM属性domProps。在Angular的文档中关于插值绑定部分是重点说明了DOM属性和HTML属性的区别,在大多数情况下两者都有对应的同名属性,也就是1:1映射关系,但是也有例外的情况,比如HTML中colspan,DOM中的textContent。HTML属性的值指定了初始值,并且不能改变,而DOM属性的值表示当前值,是可以改变的。

然后在Vue的模板语法中是不区分DOM属性和HTML属性的,例如:

<template>
 <div>
 <div>输入的值:{{ title }}</div>
 <input type="text" value="我是DOM属性值" v-model="title" @input="logTitle" />
 </div>
</template>

<script>
export default {
 data() {
 return {
  title: ''
 }
 },

 methods: {
 logTitle(e) {
  // 输出DOM属性
  console.log(e.target.value)
  // 输出HTML属性
  console.log(e.target.getAttribue('value'))
 }
 }
}
</script>

运行示例可以看到input的初始值被设置为了“我是DOM属性值",当我们在输入框中添加或者删除文字时,HTML属性始终没有变化,而绑定的DOM值一值在变动。然后再看一下在jsx中的实现:

<div>输入值:{ this.title }</div>
<input type="text" value="我是DOM属性" v-model={this.title} onInput={this.logTitle} />

同样运行后会发现在jsx写法中并没有直接将HTML属性初始化为DOM属性值,即输入框中当前值为空字符串,这符合预期的行为。

此外在模板语法中是无法区分HTML属性和DOM属性命名一样的场景,但是在jsx中可以很好的区分:

<Demo title="我是组件属性" domPropsTitle="我是DOM属性" />

结果会就是在HMTL中显示title="我是DOM属性,而"我是组件属性”传递给了组件。

在React中CSS的样式写义在jsx中的语法是以className="xx"的形式,而在Vue的jsx中可以直接写成class="xx"。实际上由于class是Js的保留字,因此在DOM中其属性名为className而在HTML属性中为class,我们可以在Vue中这样写,经过Babel转译后得到正确的样式类名:

<div domPropsClassName="mt__xs"></div>

注意:如果同时写了class="xx" domPropsClassName="yy"那么后者的优先级较高,和位置无关。所以尽量还是采用class的写法。

有使用过Bootstrap经验的可能会注意到它里面包含了很多ARIA属性,这些属性并不属于DOM,在jsx中可以通过attrsXX或者直接aria-xx的方式来添加:

<label aria-label="title"></label>
<label attrsAria-label="title"></label>

但是上面的换成domPropsAria-label就没有任何效果。

注意:在jsx中所有DOM属性(Property)语法为domPropsXx, HTML特性(Attribute)语法为attrsXx。更多的时候建议还是少使用,或者说合理使用。

在jsx中还可以使用混用的写法,例如在组件中写了<Demo title="demo" />,还可以定义一个属性对象,然后使用{...props}的方式写在一起,这个时候就会出现属性合并的问题,同样的事件多个地方声明事件处理函数,都会触发。

最后需要提及一点的是,在Vue中当给一个组件传了很多props,但是有的并不是组件声明的,也有可能是一些通用的HTML或者DOM属性,但是在最终编译后的HTML中会直接显示这些props,如果不希望这些属性显示在最终的HTML中,可以在组件中设inheritAttrs: false。虽然不显示了,但是我们依然可以通过vm.$attrs获取所有(除class和style)绑定的属性,包括不在props中定义的。

关于事件

前面已经把事件相关的知识点都介绍了,这里主要是提及一下关于jsx事件绑定语法onXx和组件属性(主要是函数prop)以on开头的情况如何处理。

虽然在写组件的时候可以避开命名以on开头,但是在使用第三库的时候,如果遇到了该如何处理呢?比如Element组件Upload很多钩子都是以on开头。 下面提供两种解决办法:

1.使用展开

<el-upload {...{
 props: {
 onPreview: this.handlePreview
 }
}} />

使用propsXx

<el-upload propsOnPreview={this.handlePreview} />

推荐使用第二种方式,写起来要简单些。

复杂逻辑条件判断

在模板语法中可以使用v-if、v-else-if和v-else来做条件判断。在jsx中可以通过?:三元运算符(Ternary operator)运算符来做if-else判断:

const Demo = () => isTrue ? <p>True!</p> : null

然后可以利用&&运算符的特性简写为:

const Demo = () => isTrue && <p>True!</p>

对于复杂的条件判断,例如:

const Demo = () => (
 <div>
  {flag && flag2 && !flag3
  ? flag4
   ? <p>Blash</p>
  : flag5
   ? <p>Meh</p>
  : <p>hErp</p>
  : <p>Derp</p>
 }
 </div>
)

可以采用两种方式来降低判断识别的复杂度

  • 最好的办法:将判断逻辑转移到子组件
  • 可选的hacky方法:使用IIFE(立即执行表达式)
  • 使用第三方库解决:jsx-control-statements

下面是使用IIFE通过内部使用if-else返回值来优化上述问题:

const Demo = () => (
 <div>
 {
  (() => {
  if (flag && flag2 &&!flag3) {
   if (flag4) {
   return <p>Blah</p>
   } else if (flag5) {
   return <p>Meh</p>
   } else {
   return <p>Herp</p>
   }
  } else {
   return <p>Derp</p>
  }
  })()
 }
 </div>
)

还可以使用do表达式,但是需要插件@babel/plugin-proposal-do-expressions的转译来支持,

const Demo = () => (
 <div>
 {
  do {
  if (flag1 && flag2 && !flag3) {
   if (flag4) {
   <p>Blah</p>
   } else if (flag5) {
   <p>Meh</p>
   } else {
   <p>Herp</p>
   }
  } else {
   <p>Derp</p>
  }
  }
 }
 </div>
)

再就是一种比较简单的可选办法,如下:

const Demo = () => {
 const basicCondition = flag && flag1 && !flag3;
 if (!basicCondition) return <p>Derp</p>
 if (flag4) return <p>Blah</p>
 if (flag5) return <p>Meh</p>
 return <p>Herp</p>
}

最后一种使用jsx插件的就不详述和举例了,有兴趣的可以直接查看文档。

组件的传值

在单个jsx文件中可以写很多函数式组件来切分更小的粒度,例如之前的文章Vue后台管理系统开发日常总结__组件PageHeader,组件的形态有两种,一种是普通标题,另一种是带有选项卡的标题,那么在写的时候就可以这样写:

render() {
 // partial html
 const TabHeader = (
  <div class="page-header page-header--tab"></div>
 )

 // function partial
 const Header = () => (
  <div class="page-header"></div>
 )

 <div class="page-header">
  {this.withTab ? TabHeader : <Header/>}
 </div>
}

注意在拆分的时候,如果不需要做任何判断可以纯粹是HTML片段赋值给变量,如果需要条件判断就使用函数式组件的方式来写。需要注意的是由于render函数会多次被调用,写的时候注意一下对性能的影响,目前能力有限这方面就不作展开了。

既然使用函数式组件,那么同样可以在函数中传递参数了,参数是一个对象中,包含了以下属性

children  # VNode数组,类似于React的children
data   # 绑定的属性
 attrs  # Attribute
 domProps # DOM property
 on    # 事件
injections # 注入的对象
listeners: # 绑定的事件类型
 click   # 点击事件
 ...
parent   # 父组件
props    # 属性
scopedSlots # 对象,作用域插槽,使用中发现作用域插槽也挂在这个下面
slots    # 函数,插槽

虽然可以在函数式组件中传参数、事件、slot但是个人觉得不建议这样做,反而搞复杂了。

render() {
 const Demo = props => {
 return (
  <div>
   <h3>Jsx中的内部组件 { props.data.title }</h3>
  { props.children }
  <br />
  { props.scopedSlots.bar() }
  </div>
 )
 }

 return (
  <div>
  <Demo title="test" attrsA="a" domPropsB="b" onClick={this.demo}>
   <h3>我是Children</h3>
  <template slot="bar">
   <p>我是Slot内容</p>
  </template>
  </Demo>
 </div>
 )
}

上面的示例最终生成的HTML中会将<template>的内容转换为#document-fragment。

总结

接触Vue时间比较早,但是真正的Vue项目开发经验一年不到,平时比较懒,不怎么去深入学习和研究,所以文章在叙述上没有什么条理性,有些知识点可能并没表达清楚,很多东西还是得多实践去检验。如果有问题欢迎留言共同探讨。

其实早一点实践jsx的写法,对于后面的Vue 3.0出现后可以更快的融入其中,就像React对函数式组件中新增了钩子(Hooks)函数,以后Vue也是主推函数式组件,以后模板语法方式的占比会稍有下降。

文章并没有包含所有Vue中jsx写法的全部知识点,→_→所以叫不完全指南^_^"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 在vue中使用jsx语法的使用方法

    什么是JSX? JSX就是Javascript和XML结合的一种格式.React发明了JSX,利用HTML语法来创建虚拟DOM.当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析. 我为什么要在vue中用JSX? 想折腾一下呗,开玩笑.最开始是因为近期在学习react,在里面体验了一把jsx语法,发现也并没有别人说的很难受的感觉啊,于是就想尝试在vue中也试下,废话不多说,先来用代码来看下两者的区别吧. ps:vue中大部分场景是不需要用render函数的,还是用模板更简洁直观

  • vue组件jsx语法的具体使用

    如果使用render函数来写比较复杂的vue组件,对于可读性和可维护性都很不友好,而使用jsx就会让我们回到更接近于模板的语法.babel转译器会将jsx转译为render函数渲染. 配置 需要用到babel插件 安装 npm install\ babel-plugin-syntax-jsx\ babel-plugin-transform-vue-jsx\ babel-helper-vue-jsx-merge-props\ babel-preset-env\ --save-dev .babelr

  • 详解Vue如何支持JSX语法

    通常开发vue我们使用的是模板语法,其实还有和react相同的语法,那就是render函数,同样支持jsx语法. Vue 的模板实际是编译成了 render 函数. 1.传统的createElement方法 createElement( 'anchored-heading', { props: { level: 1 } }, [ createElement('span', 'Hello'), ' world!' ] ) 渲染成下面这样 <anchored-heading :level="1

  • 详解利用jsx写vue组件的方法示例

    前言 本文主要给大家介绍的是关于利用jsx写vue组件,下面话不多说,来一起看看详细的介绍吧. 我们平常写vue的组件时,一般都是用的是模版,这种方式看起来比较简洁,而且vue作者也推荐使用这个方式,但是这种方式也有一些它的弊端,例如模版调试麻烦,或者在一些场景下模版描述可能没那么简单和方便. 下面我们要讲的是如何在vue里面写jsx,知道react的人应该都知道jsx,jsx的一个特性就是非常灵活,虽然有的人觉得jsx很丑陋,把逻辑都写到模版的感觉,但萝卜青菜各有所爱,适合自己适合团队的就是最

  • 详解如何使用webpack在vue项目中写jsx语法

    本文介绍了如何使用webpack在vue项目中写jsx语法,分享给大家,具体如下: 我们知道Vue 2.0中对虚拟DOM的支持.我们可以通过JavaScript动态的创建元素,而不用在template中写HTML代码.虚拟DOM最终将被渲染为真正的DOM. data: { msg: 'Hello world' }, render (h) { return h( 'div', { attrs: { id: 'my-id' }, [ this.msg ] ); } 渲染后的内容为: <div id=

  • vue jsx 使用指南及vue.js 使用jsx语法的方法

    vue  jsx  语法与 react  jsx  还是有些不一样,在这里记录下. let component = null// if 语句 if (true) { component = ( <div></div> ); } else { component = ( <div></div> ); } var ul = ( <ul> {component} </ul> ); // map 语句 var coms = limit.map

  • Vue中jsx不完全应用指南小结

    前言:文章不介绍任务背景知识,没有原理说明,偏向于实践的总结和经验分享. 文章所有的代码是基于Vue CLI 3.x版本,不会涉及到一步步通过Webpack来配置JSX所需要的知识点. 在使用Vue开发项目时绝大多数情况下都是使用模板来写HTML,但是有些时候页面复杂又存在各种条件判断来显示/隐藏和拼凑页面内容,或者页面中很多部分存在部分DOM结构一样的时候就略显捉襟见肘,会写大量重复的代码,会出现单个.vue文件过长的情况,这个时候我们就需要更多的代码控制,这时候可以使用渲染函数. 渲染函数想

  • Vue框架TypeScript装饰器使用指南小结

    前言 装饰器是一种特殊类型的声明,它能够被附加到 类声明,方法, 访问符,属性或参数 上. 装饰器使用 @expression这种形式, expression求值 后必须为一个函数,它会在 运行时被调用 ,被装饰的声明信息做为参数传入. 本篇先从项目的宏观角度来总结一下Decorator如何组织. 目录 主要的Decorator依赖 vue-class-component vuex-class vue-property-decorator core-decorators 自定义Decorator

  • 浅谈vue中使用图片懒加载vue-lazyload插件详细指南

    在vue中使用图片懒加载详细指南,分享给大家.具体如下: 说明 当网络请求比较慢的时候,提前给这张图片添加一个像素比较低的占位图片,不至于堆叠在一块,或显示大片空白,让用户体验更好一点. 使用方式 使用vue的 vue-lazyload 插件 插件地址:https://www.npmjs.com/package/vue-lazyload 案例 demo: 懒加载案例demo Installation 安装方式 npm $ npm i vue-lazyload -D CDN CDN: https:

  • Vue中的Vux配置指南

    简介 Vux(读音 [v'ju:z],同views)是基于WeUI和Vue(2.x)开发的移动端UI组件库,主要服务于微信页面. 基于webpack+vue-loader+vux可以快速开发移动端页面,配合vux-loader方便你在WeUI的基础上定制需要的样式. vux-loader保证了组件按需使用,因此不用担心最终打包了整个vux的组件库代码. vux并不完全依赖于WeUI,但是尽量保持整体UI样式接近WeUI的设计规范.最初目标是创建一个易用,实用,美观的移动端UI组件库,现在离理想状

  • Vue中的v-for循环key属性注意事项小结

    当Vue用 v-for 正在更新已渲染过的元素列表是,它默认用"就地复用"策略.如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素. 为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性.key属性的类型只能为 string或者number类型. 在下面这个例子中,如果不给 p 元素绑定key,我先选中第一个, 然后输入ID和Nam

  • 在 Vue 中使用 JSX 及使用它的原因浅析

    本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料.欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西. Vue.js 具有简单的 API 和几个选项,可用于在我们的组件中定义HTML模板. 我们可以使用 <template> 标签选项,在根组件实例上定义 template 属性,或者使用单文件组件. 上面的选项很棒并且可以完美地工作,但是,在您的应用程序的生命周期中,有时会

  • 在vue中created、mounted等方法使用小结

    created:html加载完成之前,执行.执行顺序:父组件-子组件 mounted:html加载完成后执行.执行顺序:子组件-父组件 methods:事件方法执行 watch:watch是去监听一个值的变化,然后执行相对应的函数. computed:computed是计算属性,也就是依赖其它的属性计算所得出最后的值 export default { name: "draw", data(){ // 定义变量source return { source:new ol.source.Ve

  • Vue 3.0中jsx语法的使用

    Vue 3.0 正式发布了,喜大普奔

  • 如何在 Vue 中使用 JSX

    JSX 是什么 JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javascript 的灵活性,同时又兼具 html 的语义化和直观性 为什么要在 Vue 中使用 JSX 有时候,我们使用渲染函数(render function)来抽象组件,渲染函数不是很清楚的参见官方文档, 而渲染函数有时候写起来是非常痛苦的 createElement( 'anchored-h

随机推荐