Docusaurus, similar to Vuepress, is a static site generation tool. Unlike Docusaurus, which makes it easy to mix React components into documents, Vuepress is good for mixing Vue components into documents.
This left me confused. If I wanted to use both the Vue and React components in my blog, neither would work for me, so I decided to experiment and use both components in my documentation
The initial goal was to encapsulate the Vue component into the React component and let Docusaurus render the component without having to write the underlying layer, saving a lot of effort
Docusaurus website description:
Using JSX in Markdown:
export const Highlight = ({children, color}) = > (
<span
style={{
backgroundColor: color.borderRadius: '2px',
color: '#fff',
padding: '0.2 rem'}} >
{children}
</span>
);
<Highlight color="#25c2a0">Docusaurus green</Highlight> and <Highlight color="#1877F2">Facebook blue</Highlight> are my favorite colors.
I can write **Markdown** alongside my _JSX_!
Copy the code
You get the following render result:
Write a method that uses the vue component as input and returns the React component:
export const uvc = (vueComponent) = > {
return function() {
return ( // return one JSX each)}}Copy the code
Then there are two things to deal with:
- How do I parse.vue files
- How do component transformations take place
Parse the. Vue file
Using the vue – loader
Vue Loader is a Webpack Loader that allows you to write Vue components in a format called single-file Components (SFCs)
Next we need to write a Docusaurus plug-in that will parse the.vue files we encounter
Using the configureWebpack hook in the lifecycle:
module.exports = (content,options) = > {
return {
name: 'docusaurus-plugin-usevue'.configureWebpack(config, isServer, utils) {
return {
module: {
rules: [{
test: /\.vue$/,
use: ['vue-loader']]}},plugins: [
new VueLoaderPlugin()
]
}
}
}
}
Copy the code
Component transformation
Vue and React are single-page applications. We can take advantage of this by mounting the render component of the DOM node to vue:
Since the.vue file has been converted by vue-loader, it can be rendered directly with h function
Mount vue components after the React component is rendered:
import React from 'react'
import Vue from 'vue'
export function uvc(test) {
return class VueComponent extends React.Component {
constructor(props) {
super(props)
}
componentDidMount() {
new Vue({
el: `.app`.render: h= > h(test)
})
}
render() {
return React.createElement("div", {
className: app }); }}; }Copy the code
But if only this, globally unique. App class, only one component will be in effect, then need to generate a random class name:
function randomCoding(){
// Create an array of 26 letters
let arr = ['A'.'B'.'C'.'D'.'E'.'F'.'G'.'H'.'I'.'J'.'K'.'L'.'M'.'N'.'O'.'P'.'Q'.'R'.'S'.'T'.'U'.'V'.'W'.'X'.'Y'.'Z'];
let idvalue =' ';
const n = 16;
for(let i=0; i<n; i++){ idvalue+=arr[Math.floor(Math.random()*26)];
}
return idvalue;
}
export function uvc(test) {
return class VueComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
uuid: randomCoding()
}
}
componentDidMount() {
new Vue({
el: `.The ${this.state.uuid}`.render: h= > h(test)
})
}
render() {
return React.createElement("div", {
className: this.state.uuid }); }}; }Copy the code
Done, test results:
To make it easier for others to use, publish it on NPM as follows:
The installation
yarn add docusaurus-plugin-usevue use-vue-component
Copy the code
Plug-in to introduce
docusaurus.config.js:
module.exports = {
// ...
plugins: [['docusaurus-plugin-usevue',
{
name: 'usevue'},]],};Copy the code
usage
directory structure:
+-- docs
| +-- test.vue
| +-- intro.mdx
Copy the code
test.vue:
<template>
<div class="red">
hello world, this is {{name}}
</div>
</template>
<script>
export default {
data() {
return {
name: 'peter'
}
}
}
</script>
<style>
.red {
color: red
}
</style>
Copy the code
intro.mdx:
---
sidebar_position: 1
---
## Getting Started
import {uvc} from 'use-vue-component' / / import uvc
import test from './text.vue'
export const HelloWorld = uvc(test)
<HelloWorld/>
Copy the code
It looks like the React component of Docusaurus is used similarly
limited
Because it is written casually, there are still many deficiencies
- Currently, only Vue2 is supported. We are considering introducing Vue3
- Global import of components to be supported
- .
Feel free to share your ideas in the comments section!
For more details:
gitHub: docusaurus-plugin-usevue
gitHub: use-vue-component