React结合vite使用vue3
在某个React的项目中,有个较复杂的表单非常适合通过vue来实现。 在vite中使用vue要比webpack要容易一些。不需要配置v-on 这样的自定义标签
但还是需要一些特殊方法来在React中使用vue
- React只渲染一次
在React中使用vue的前提是,整个react组件只能渲染一次,这样vue绑定的事件才不会被多次渲染冲掉。 React中的StrictMode会调用函数组件两次,保证其为纯函数。可以先把这个模式禁掉,或采用其它方法,保证vue只渲染一次。
createRoot(document.getElementById('root')!).render(
// <StrictMode>
<HashRouter>
<Routes>
...
</Routes>
</HashRouter>
// </StrictMode>,
)
- 安装 vue
这里"vue": "^3.5.13"
yarn add vue
然后在代码里引用,vue 3.5.13 还无法直接从"vue"引用,这里引用: 'vue/dist/vue.esm-browser.js'
// import { createApp, ref } from 'vue'
import { createApp, ref } from 'vue/dist/vue.esm-browser.js'
- 写react组件
现在可以编写基于vue的React组件。这里使用 useEffect 确保在React初始化完成后,dom已经在页面显示后再渲染vue。
import { useEffect } from 'react'
// import { createApp, ref } from 'vue'
import { createApp, ref } from 'vue/dist/vue.esm-browser.js'
import './PropertyPanel.css'
export function PropertyPanel() {
console.log('PropertyPanel', new Date())
useEffect(() => {
createApp({
setup() {
return {
count: ref(0),
}
}
}).mount('#app');
}, [])
return (
<div>
<div id="app">
{/* <button @click="count++">
Count is: {{count}}
</button> */}
<button v-on:click="count++" v-text="count"></button>
</div>
</div>
)
}
目前的vite还不支持 @click= 和 {{count}} 这样的html属性,会显示编译错误,这里使用 v-on:click 和 v-text 写法代替。
复杂一些的例子,增删改查:
import { useEffect } from 'react'
import { createApp, reactive, toRefs} from 'vue/dist/vue.esm-browser.js'
export function PropertyPanel() {
useEffect(() => {
const data = reactive({
events: [{}],
minOne(index) {
data.events.splice(index, 1)
},
})
const app = createApp({
setup() {
return {
...toRefs(data),
addOne(index) {
data.events.splice(index, 0, {})
}
}
}
});
app.mount(".accordion-item");
}, [])
return (
<div className="accordion-item">
<h2 className="accordion-header">
<button className="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
Events Input
</button>
</h2>
<div id="collapseOne" className="accordion-collapse collapse show">
<div className="accordion-body">
<table className="table">
<tbody>
<tr v-for="(event, index) in events">
<td><span v-on:click="addOne(index)"><i className="ti-plus"></i></span></td>
<td>
<input className="form-control" v-model="event.name" />
</td>
<td>
<select className="form-select" v-model="event.type">
<option value="int">int</option>
<option value="string">string</option>
</select>
</td>
<td><span v-on:click="minOne(index)"><i className="ti-trash"></i></span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
)
}
回复 (0)
微信扫码 立即评论