ホームページ > 記事 > ウェブフロントエンド > Vue3+ViteでのJSXの使い方を詳しく解説
Vue Vite で JSX を使用するにはどうすればよいですか?以下の記事ではVue3 ViteでのJSXの使い方を紹介していますので、ご参考になれば幸いです。
[関連する推奨事項: vuejs ビデオ チュートリアル、Web フロントエンド開発]
JSX (JavaScript および XML) は、React で初めて導入された JavaScript 内 HTML 構文拡張機能です。 JSX は、UI がどのように対話するかという本質において、UI がどのように動作するかを記述する優れた方法です。 JSX は JavaScript 構文の拡張であるため、HTML に似たコードは JS と共存できます。例:
const button = <MyButton color="blue" shadowSize={2}> Click Me </MyButton>
ボタン定数は JSX 式と呼ばれます。これを使用して、アプリケーションで 3c45ec991a34a5c936634b431885c5ff
タグをレンダリングできます。ブラウザは JSX を直接読み取って解析することはできません。 (Babel や Parcel などのツールを使用して) コンパイルされた後の JSX 式は次のようになります。
React.createElement( MyButton, {color: 'blue', shadowSize: 2}, 'Click Me' )
実際、JSX は React.createElement(component, props, ...children) 関数の糖衣構文にすぎません。 React.createElement() を使用して自分で UI を記述することで、コンパイル手順をスキップできます。ただし、そうすると JSX の宣言的な利点が失われ、コードが読みにくくなります。コンパイルは開発プロセスにおける追加のステップですが、React コミュニティの多くの開発者は、JSX の読みやすさにはそれだけの価値があると信じています。さらに、一般的なツールでは、JSX から JavaScript へのコンパイルがセットアップ プロセスの一部になっています。希望しない限り、自分でコンパイルを設定する必要はありません。特定の JSX が JavaScript に変換されるものをテストしたい場合は、Online Babel コンパイラ を使用してみてください。
React では JSX を使用する必要はありません。ビルド環境で JSX コンパイルを構成したくない場合は、React で JSX を使用しない方が便利です。たとえば、JSX で書かれたコード:
class Hello extends React.Component { render() { return <div>Hello {this.props.toWhat}</div>; } } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Hello toWhat="World" />);
は、JSX を使用しないコードとして書くことができます:
class Hello extends React.Component { render() { return React.createElement('div', null, `Hello ${this.props.toWhat}`); } } const root = ReactDOM.createRoot(document.getElementById('root')); root.render(React.createElement(Hello, {toWhat: 'World'}, null));
Vue では、次の単一のコードを使用します。 -file コンポーネントは、テンプレート、関連スクリプト、CSS を .vue で終わる単一のファイルに統合します。これらのファイルは、最終的に JS パッケージ化またはビルド ツール (Webpack、Vite など) によって処理されます。
jsx は React によって初めて導入されましたが、JSX 構文は実際にはランタイム セマンティクスを定義しておらず、さまざまな出力形式にコンパイルできます。以前に JSX 構文を使用したことがある場合は、.vue ファイルの
d477f9ce7bf77f53fbcf36bec1b69b7a
要素には、すべてのマークアップ構造とコンポーネント表示ロジックが含まれています。テンプレートには、有効な HTML だけでなく、Vue 固有の構文も含めることができます。たとえば、d477f9ce7bf77f53fbcf36bec1b69b7a
タグのlang
属性を設定すると、885a744315c58b9af712dd38b4d61be6# と設定して Pug テンプレートを使用できます。 ## 標準の HTML を置き換えます。
3f1c4e4b6b16bbbd69b2ee476dc4f83a
コンポーネントの CSS スタイルは、タグには、コンポーネント内のすべての非表示ロジックが含まれており、デフォルトで JS オブジェクトをエクスポートする必要があります。このオブジェクトは、コンポーネントがローカルに登録され、プロパティが定義され、ローカル状態が処理され、メソッドが定義される場所です。ビルドフェーズでは、テンプレートを含むこのオブジェクトが処理され、render() 関数を使用して Vue コンポーネントに変換されます。
c9ccee2e6ea535a969eb3f532ad9fe89
タグに記述されます。
scoped属性が追加されると、Vue はスタイルの範囲を次のように制限します。単一ファイルコンポーネントのコンテンツ。これは CSS-in-JS に似たソリューションですが、純粋な CSS を記述できます。 CLI 経由でプロジェクトを作成するときに CSS プリプロセッサを選択した場合は、
lang属性を
c9ccee2e6ea535a969eb3f532ad9fe89タグに追加して、Webpack がビルド時にコンテンツを処理できるようにすることができます。
Vue の JSX コンパイル方法は React の JSX コンパイル方法とは異なるため、Vue アプリケーションでは React の JSX コンパイルを使用できないことに注意してください。 React JSX 構文との顕著な違いは次のとおりです。
class
和 for
作为 props - 不需要使用 className
或 htmlFor
。Vue 的类型定义也提供了 TSX 语法的类型推导支持。当使用 TSX 语法时,确保在 tsconfig.json
中配置了 "jsx": "preserve"
,这样的 TypeScript 就能保证 Vue JSX 语法编译过程中的完整性。
vite 官方提供了官方的插件来支持在 vue3 中使用 jsx/tsx,直接安装就行。
npm i @vitejs/plugin-vue-jsx -D
安装完之后在 vite.config.js 文件中的 plugins 字段中添加 jsx 支持:
import vueJsx from "@vitejs/plugin-vue-jsx"; export default defineConfig({ plugins: [ vueJsx(), ] })
这样就可以在项目中使用 jsx/tsx 了。
在项目中新建 jsx 或 tsx 后缀的文件,语法和 js 文件类似,但是和 .vue 文件中的 3f1c4e4b6b16bbbd69b2ee476dc4f83a
标签一样需要默认导出一个 JS 对象。该对象是在本地注册组件、定义属性、处理本地状态、定义方法等的地方。
import HelloWorld from './HelloWorld.vue' export default { setup() { return () => <HelloWorld msg="11" />; }, };
1、插值。与 vue 模板语法中的插值一样,但是双大括号 {{}} 变为了单大括号 {}。大括号内支持任何有效的 JavaScript 表达式,比如:2 + 2,user.firstName,formatName(user) 等。
// 模板语法 <span>{{ a + b }}</span> // jsx/tsx <span>{ a + b }</span>
2、class 类名绑定。有两种方式,使用模板字符串或者使用数组。
// 模板字符串 <div className={ `header ${ isBg ? 'headerBg' : '' }` }>header</div> // 数组 <div class={ [ 'header', isBg && 'headerBg' ] } >header</div>
3、style 样式绑定。需要使用双大括号。
const color = 'red' const element = <sapn style={{ color, fontSize: '16px' }}>style</sapn>
4、条件渲染。由于 jsx 本身具有 js 语法,所以不再需要使用 v-if 指令,使用 if/else 和三元表达式都可以实现。但是支持 v-show 指令。
const element = (name) => { if (name) { return <h1>Hello, { name }</h1> } else { return <h1>Hello, Stranger</h1> } } const element = icon ? <span class="icon"></span> : null; // 以上代码等效于: const element = icon && <span class="icon"></span>;
5、列表渲染。同样,由于 jsx 本身具有 js 语法,所以不再需要使用 v-for 指令,使用 JS 数组的 map 方法即可。
const listData = [ {name: 'Tom', age: 18}, {name: 'Jim', age: 20}, {name: 'Lucy', age: 16} ] return () => ( <div> <div class={'box'}> <span>姓名</span> <span>年龄</span> </div> { prop.listData.map(item => <div class={'box'}> <span>{item.name}</span> <span>{item.age}</span> </div> }) </div> )
6、标签属性绑定。也是使用大括号包裹,不能使用 v-bind 指令。而 vue 组件中通过 7a49b8a1571104a37acffe1450d6cc1e16b28748ea4df4d9c2150843fecfba68
批量绑定标签属性,在 JSX 中需要使用 04eaf629e1aa69a83352c6b37941496316b28748ea4df4d9c2150843fecfba68
。
const href = 'https://cn.vuejs.org/' const element = <a href={href}>Vue3</a>
7、事件绑定。使用的也是 单大括号 {},不过事件绑定不是以 @为前缀了,而是改成了 on,与原生相同。例如:click 事件是 onClick 或 onclick。
const confirm = () => { // 确认提交 } <button onClick={confirm}>确定</button>
如果要带参数,需要使用箭头函数进行包裹:
const confirm = (name) => { // 确认提交 } <button onClick={() => confirm('Are you sure')}>确定</button>
8、事件修饰符。需要使用 withModifiers 方法,接收两个参数,第一个参数是绑定的事件,第二个参数是需要使用的事件修饰符。
import { withModifiers, defineComponent, ref } from 'vue' const App = defineComponent({ setup() { const count = ref(0); const inc = () => { count.value++; }; return () => ( <div onClick={ withModifiers(inc, ['self']) }>{ count.value }</div> ); }, }) export default App
注意:Vue 模板中 ref 变量是可以直接解构的,但是在 jsx 中不行,需要添加 .value,比如上面的 { count.value }。
9、v-model 双向绑定。需要使用单大括号 {}。如果绑定属性则需要一个数组,第一个元素为绑定的值,第二个元素为绑定的属性。
// 绑定值 <input v-model="show" /> // vue <input v-model={show.value} /> // jsx // 绑定属性 <input v-model:prop="show" /> // vue <input v-model={[show.value,'prop']} /> // jsx // 修饰符写法 <input v-model:prop.trim="show" /> // vue <input v-model={[show.value,'prop',['trim']]} /> // jsx
10、slot 插槽。jsx/tsx 中无法使用 slot 标签,定义插槽方式一:通过 setup 函数的第一个参数 ctx 上下文对象的 slots 的属性,setup 函数默认接收两个参数:
如果解构了 props
对象,解构出的变量将会丢失响应性,因此推荐通过 props.xxx
的形式来使用其中的 props。如果确实需要解构 props
对象,或者需要将某个 prop 传到一个外部函数中并保持响应性,可以使用 toRefs() 和 toRef() 这两个工具函数:
import { toRefs, toRef } from 'vue' export default { setup(props) { // 将 `props` 转为一个其中全是 ref 的对象,然后解构 const { title } = toRefs(props) // `title` 是一个追踪着 `props.title` 的 ref console.log(title.value) // 或者,将 `props` 的单个属性转为一个 ref const title = toRef(props, 'title') } }
ctx 上下文对象是非响应式的,可以安全地解构:
export default { setup(props, { attrs, slots, emit, expose }) { ... } }
attrs 和 slots 都是响应式(有状态)的对象,它们总是会随着组件自身的更新而更新。这意味着你应当避免解构它们,并始终通过 attrs.x 或 slots.x 的形式使用其中的属性。此外,和 props 不同,attrs 和 slots 的属性都不是响应式的。如果想要基于 attrs 或 slots 的改变来执行副作用,那么应该在 onBeforeUpdate 生命周期钩子中编写相关逻辑。
expose 函数用于显式地限制该组件暴露出的属性,当父组件通过模板引用访问该组件的实例时,将仅能访问 expose 函数暴露出的内容:
export default { setup(props, { expose }) { // 让组件实例处于 “关闭状态” // 即不向父组件暴露任何东西 expose() const publicCount = ref(0) const privateCount = ref(0) // 有选择地暴露局部状态 expose({ count: publicCount }) } }
通过 ctx 上下文对象的 slots 的属性可以获取插槽对象后,就可以定义插槽了。
import { defineComponent } from 'vue' export default defineComponent({ setup(props, { slots }) { // 逻辑 return () => { return <p> <button>{ slots.test?.() }</button> <button>{ slots.default?.() }</button> </p> } }, }) // 在引用的组件中 <template #test>slot-test</template> <template #>slot-default</template>
定义插槽方式二:使用 renderSlot 函数。
import { renderSlot } from 'vue' <button> { renderSlot(slots, 'default') } </button>
而如果在 jsx 中使用插槽,可以直接通过标签属性 slot,或通过 v-slots 指令。
import HelloWorld from './HelloWorld' export default defineComponent({ setup() { return () => ( <div class={'box'}> <HelloWorld v-slots={{ title: () => { return <p>我是title插槽</p> }, default: () => { return <p>我是default插槽</p> } }} /> </div> ) } })
11、CSS Modules。引入局部样式,相当于 vue 组件中 c9ccee2e6ea535a969eb3f532ad9fe89
标签的 scoped 属性。
import styles from './index.module.scss' <div class={styles.wrap}></div>
以上がVue3+ViteでのJSXの使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。