通过Vue3对比学习Reactjs: 模板语法 vs JSX
Vue 使用一种基于 HTML 的模板语法,在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。Vue也支持jsx语法,但请注意,jsx语法将不会享受到和模板同等级别的编译时优化。
JSX是JavaScript的语法扩展,允许您在JavaScript文件中编写类似HTML的标记。尽管还有其他编写组件的方法,但大多数React开发人员更喜欢JSX的简洁性,大多数代码库都使用它。
文本插值
最基本的数据绑定形式是文本插值,同时都支持javascript表达式和函数调用
- Vue 使用
{{}}
(双大括号语法)
<span>Message: {{ msg }}</span>
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<time> {{ formatDate(date) }} </time>
- JSX 使用
{}
(单大括号语法)
{ number + 1 }
<span>Message: { msg }</span>
<h1>To Do List for {formatDate(today)}</h1>
一般属性值
在Vue中,双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind
指令:
- 绑定单个动态值
<div v-bind:id="dynamicId"></div>
简写
<div :id="dynamicId"></div>
- 动态绑定多个值
有这样的一个包含多个 attribute 的 JavaScript 对象:
const objectOfAttrs = {
id: 'container',
class: 'wrapper'
}
通过不带参数的 v-bind
,你可以将它们绑定到单个元素上:
<div v-bind="objectOfAttrs"></div>
效果等价于
<div id="container" class="wrapper"></div>
在jsx中,属性绑定和写HTML的属性类似,如果是动态属性则需要用 {}
单括号
- 动态绑定单个值
export default function Avatar() {
const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
const description = 'Gregorio Y. Zara';
return (
<img
className="avatar"
src={avatar}
alt={description}
/>
);
}
- 动态绑定多个值
在jsx中想把一个对象中的全部属性都作为属性传递给组件,需要用到javascript
中的析构语法
const person = {
name: 'kevin',
age: 20
}
function Profile() {
return (
<div className="card">
<Avatar {...person} />
</div>
);
}
等价于
<Avatar name="kevin" age={20} />
这种方法最好慎用,可能会引起意料之外的错误
CSS
来看一下css和对象,作为属性传递时,这两者有什么区别
- class
const isActive = ref(true)
const hasError = ref(false)
<div :class="{ active: isActive, error: hasError }"></div>
最终渲染成
<div class="active"></div>
动态的class
,还支持数组
const activeClass = ref('active')
const errorClass = ref('text-danger')
<div :class="[activeClass, errorClass]"></div>
会渲染成
<div class="active text-danger"></div>
还支持以下方式
<div :class="[isActive ? activeClass : '', errorClass]"></div>
<div :class="[{ active: isActive }, errorClass]"></div>
- style
对于内联样式
<div :style="{ color: 'red', fontSize: '20px' }"></div>
推荐使用 camelCase,但 :style
也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称),例如:
<div :style="{ 'font-size': '20px' }"></div>
:style
也支持对象格式
const styleObject = reactive({
color: 'red',
fontSize: '13px'
})
<div :style="styleObject"></div>
我们还可以给 :style
绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上:
<div :style="[baseStyles, overridingStyles]"></div>
在jsx
中的样式的写法有它自己的一套 css-in-js
的方案,如果在jsx
中使用简单的class
和style
,可以使用下面的方式,在jsx
中,class
要用className
替换,css中的style属性要用camelCase格式
<ul style={{
backgroundColor: 'black',
color: 'pink'
}}>
<ul className=""></ul>
条件渲染(if)
在vue中条件渲染需要用到指令有 v-show
、v-if
、v-else
、v-else-if
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
关于v-if
v-show
v-for
之间的关系和区别,会用单独的一篇文章介绍
而在jsx
中的条件渲染有以下几种方式
- if
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
- &&
{cond && <A />}
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
- ? :
{cond ? <A /> : <B />}
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
列表渲染(list)
在Vue
中我们可以使用 v-for
指令基于一个数组来渲染一个列表。有以下几种写法
- 数组
<li v-for="item in items" :key={}>
{{ item.message }}
</li>
- 带索引
<li v-for="(item, index) in items" :key={}>
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
- 使用析构
<li v-for="{ message } in items" :key={}>
{{ message }}
</li>
<!-- 有 index 索引时 -->
<li v-for="({ message }, index) in items">
{{ message }} {{ index }}
</li>
- 使用
of
代替in
<div v-for="item of items"></div>
- 遍历对象
你也可以使用 v-for 来遍历一个对象的所有属性。遍历的顺序会基于对该对象调用 Object.keys() 的返回值来决定。
const myObject = reactive({
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
})
#1
<ul>
<li v-for="value in myObject" :key={}>
{{ value }}
</li>
</ul>
#2 可以通过提供第二个参数表示属性名 (例如 key):
<li v-for="(value, key) in myObject" :key={}>
{{ key }}: {{ value }}
</li>
#3 第三个参数表示位置索引:
<li v-for="(value, key, index) in myObject" :key={}>
{{ index }}. {{ key }}: {{ value }}
</li>
在jsx
中,需要用到javascript
中的数组的方法,常用数组的 map
方法
const people = [{
id: 0,
name: 'Creola Katherine Johnson',
profession: 'mathematician',
}, {
id: 1,
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
}, {
id: 2,
name: 'Mohammad Abdus Salam',
profession: 'physicist',
}, {
name: 'Percy Lavon Julian',
profession: 'chemist',
}, {
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
}];
const chemists = people.filter(person =>
person.profession === 'chemist'
);
const listItems = chemists.map(person =>
<li>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}:</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
不管是在vue
还是在jsx
,渲染列表时,都需要 key
元素,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素
转载自:https://juejin.cn/post/7246963275955093561