JavaScript文件中使用JSX的方法步骤
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 配置 Babel 支持 JSX</a></li><li><a href="#_label1">2. 在 JS 文件中使用 JSX 的基本语法</a></li><li><a href="#_label2">3. JSX 与模板语法的对比</a></li></ul></div><p>在 Vue 项目中,你可以通过以下步骤在 .js 文件中使用 JSX:</p><p class="maodian"><a name="_label0"></a></p><h2>1. 配置 Babel 支持 JSX</h2>
<p>首先需要确保你的项目配置支持 JSX 转换:</p>
<p>安装必要依赖</p>
<div class="jb51code"><pre class="brush:bash;">npm install @vue/babel-plugin-jsx -D
yarn add @vue/babel-plugin-jsx -D
</pre></div>
<p>配置 babel.config.js</p>
<div class="jb51code"><pre class="brush:js;">module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
'@vue/babel-plugin-jsx'
]
}
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>2. 在 JS 文件中使用 JSX 的基本语法</h2>
<div class="jb51code"><pre class="brush:js;">// HelloWorld.js
import { defineComponent } from 'vue'
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String
},
setup(props) {
return () => (
<div class="hello">
<h1>{props.msg}</h1>
<button onClick={() => console.log('clicked')}>Click me</button>
</div>
)
}
})
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>3. JSX 与模板语法的对比</h2>
<p>模板语法 JSX 语法</p>
<div class="jb51code"><pre class="brush:js;"><template> 标签 直接在 JS 中写 JSX
v-if {condition && <div/>}
v-for {items.map(item => <div key={item.id}>{item.name}</div>)}
v-bind 或 : 直接使用属性 name={value}
v-on 或 @ onClick={handler}
v-model value={state} onChange={handler}
</pre></div>
<ol start="4"><li>实际使用示例<br />带状态的组件</li></ol>
<div class="jb51code"><pre class="brush:js;">// Counter.js
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup() {
const count = ref(0)
const increment = () => {
count.value++
}
return () => (
<div>
<p>Count: {count.value}</p>
<button onClick={increment}>Increment</button>
</div>
)
}
})
</pre></div>
<p>带子组件的示例</p>
<div class="jb51code"><pre class="brush:js;">// ParentComponent.js
import { defineComponent } from 'vue'
import ChildComponent from './ChildComponent'
export default defineComponent({
setup() {
const items = ['Apple', 'Banana', 'Orange']
return () => (
<div>
<h1>Fruit List</h1>
<ul>
{items.map(item => (
<ChildComponent item={item} key={item} />
))}
</ul>
</div>
)
}
})
</pre></div>
<ol start="5"><li>注意事项<br />文件扩展名:虽然可以在 .js 文件中使用 JSX,但推荐使用 .jsx 扩展名以便区分<br />Vue 指令:在 JSX 中不能直接使用 Vue 指令,需要转换为 JSX 等价形式<br />样式处理:</li></ol>
<div class="jb51code"><pre class="brush:js;">// 使用对象语法
<div style={{ color: 'red', fontSize: '14px' }}></div>
// 使用 class
<div class={['foo', { active: isActive }]}></div>
插槽:
// 默认插槽
<Child>{() => '默认插槽内容'}</Child>
// 具名插槽
<Child>
{{
default: () => '默认内容',
header: () => <h1>标题</h1>
}}
</Child>
</pre></div>
<ol start="6"><li>与 TypeScript 结合<br />如果你使用 TypeScript,可以创建 .tsx 文件:</li></ol>
<div class="jb51code"><pre class="brush:js;">// Hello.tsx
import { defineComponent, PropType } from 'vue'
interface User {
name: string
age: number
}
export default defineComponent({
props: {
user: {
type: Object as PropType<User>,
required: true
}
},
setup(props) {
return () => (
<div>
<p>Name: {props.user.name}</p>
<p>Age: {props.user.age}</p>
</div>
)
}
})
</pre></div>
<p>通过以上配置和示例,你就可以在 Vue 项目的 JavaScript 文件中自由使用 JSX 语法了。<br /><strong>或者不使用sertup</strong></p>
<p>在 Vue 组件中直接使用 render 函数(不使用 setup)<br />在 Vue 中,你可以直接在组件选项中定义 render 函数,而不需要使用 setup 函数。这种方式在 Vue 2 和 Vue 3 中都适用,是更传统的写法。</p>
<p>基本语法</p>
<div class="jb51code"><pre class="brush:js;">import { h } from 'vue'
export default {
props: ['message'],
render() {
return h('div', this.message)
}
}
</pre></div>
<p>完整示例</p>
<ol><li>简单组件</li></ol>
<div class="jb51code"><pre class="brush:js;">// SimpleComponent.js
import { h } from 'vue'
export default {
name: 'SimpleComponent',
props: {
title: String,
count: Number
},
render() {
return h('div', [
h('h1', this.title),
h('p', `Count: ${this.count}`),
h('button', {
onClick: () => this.$emit('increment')
}, 'Add')
])
}
}
</pre></div>
<ol start="2"><li>带状态的组件</li></ol>
<div class="jb51code"><pre class="brush:js;">// Counter.js
import { h } from 'vue'
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
},
render() {
return h('div', [
h('p', `Current count: ${this.count}`),
h('button', {
onClick: this.increment
}, 'Increment')
])
}
}
</pre></div>
<p>JSX 版本<br />如果你配置了 JSX 支持(如前所述),可以这样写:</p>
<div class="jb51code"><pre class="brush:js;">// JsxComponent.js
export default {
props: ['items'],
render() {
return (
<ul>
{this.items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)
}
}
</pre></div>
<p>与传统模板的比较<br />模板语法 Render 函数等效</p>
<div class="jb51code"><pre class="brush:js;">v-if="condition" condition ? h('div') : null
v-for="item in items" items.map(item => h('div', item))
v-bind:id="id" { id: this.id }
@click="handleClick" { onClick: this.handleClick }
v-model="value" 需要手动实现(见下方示例)
实现 v-model
// InputComponent.js
import { h } from 'vue'
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
render() {
return h('input', {
value: this.modelValue,
onInput: (e) => {
this.$emit('update:modelValue', e.target.value)
}
})
}
}
</pre></div>
<p>插槽处理</p>
<div class="jb51code"><pre class="brush:js;">// LayoutComponent.js
import { h } from 'vue'
export default {
render() {
return h('div', [
h('header', this.$slots.header()),
h('main', this.$slots.default()),
h('footer', this.$slots.footer())
])
}
}
</pre></div>
<p>作用域插槽</p>
<div class="jb51code"><pre class="brush:js;">// ScopedSlotComponent.js
import { h } from 'vue'
export default {
data() {
return {
user: {
name: 'John',
age: 30
}
}
},
render() {
return h('div', [
this.$slots.default({
user: this.user
})
])
}
}
</pre></div>
頁:
[1]