React结合vite使用vue3,在纯typescript的react hooks中使用vue


发布者 ourjs  发布时间 1736914220899
关键字 react hooks  vue 

React结合vite使用vue3

在某个React的项目中,有个较复杂的表单非常适合通过vue来实现。 在vite中使用vue要比webpack要容易一些。不需要配置v-on 这样的自定义标签

但还是需要一些特殊方法来在React中使用vue

  1. React只渲染一次

在React中使用vue的前提是,整个react组件只能渲染一次,这样vue绑定的事件才不会被多次渲染冲掉。 React中的StrictMode会调用函数组件两次,保证其为纯函数。可以先把这个模式禁掉,或采用其它方法,保证vue只渲染一次。

createRoot(document.getElementById('root')!).render(
  // <StrictMode>
    <HashRouter>
      <Routes>
        ...
      </Routes>
    </HashRouter>
  // </StrictMode>,
)
  1. 安装 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'
  1. 写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>
  )
}








  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA