2023年5月26日
By: Chase

在blog中运行js,React与Vue

前言

blog框架内集成了klipse. 可以运行js, python, clojure等等. 运行klipse需要能qiang, 他的js源挂在google上

config-edn内像这里写的设置一下就可以, 注意key和value的隐射转化 框架内的设置

我的是从公司blog里copy过来的, 如下

:klipse            {:selector-eval-js ".klipse-js"
                    :selector-transpile-jsx ".klipse-transpile-jsx"
                    :selector-render-jsx ".klipse-render-jsx"
                    :selector-jsx ".klipse-jsx"
                    :selector-react ".klipse-react"}

本文的实际效果, 就是加载了每个对应的示例代码

运行js

在代码引入处加上klipse-js后缀, 示例代码

```klipse-js
const add = (a, b) => a + b
add(1, 3)

实际效果:

const add = (a, b) => a + b
add(1, 3)

还能实时编译, 你可以改动上面的代码试试.

能跑js, 还能支持script引入, 所以我们将React与Vue的源引入, 就可以跑他们的示例demo了.

同理其他的script也可以, 只要你可以用单页面html实现的demo. 都可以在blog显示出来.

运行React

引入React

引入 React 与 ReactDOM, 源是官网提供的. 示例代码

<pre>
    <code
        class="klipse-js"
        data-external-libs="https://unpkg.com/react@18/umd/react.production.min.js,https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
    >
        console.log('React keys:', Object.keys(React))
        console.log('ReactDOM keys:', Object.keys(ReactDOM))
    </code>
</pre>

实际效果:


        console.log('React keys:', Object.keys(React))
        console.log('ReactDOM keys:', Object.keys(ReactDOM))
    

在之后的js引用里也可以使用React变量了

    Object.keys(React).length

渲染jsx-Class版本

我们在html的script的标签内, 无法直接写jsx.

klipse提供了一个可以写jsx的包裹klipse-jsx.

可以直接渲染jsx代码, 这里是一个React 16以前的Class写法, 示例代码:

```klipse-jsx
const { createRoot } = ReactDOM
const root = createRoot(document.getElementById('jsx-demo'))

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = { data: 0 };
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState({
            data: this.state.data + 1
        });
    }

    render() {
        return (
            <div>
                <div>state: {this.state.data}</div>
                <button onClick={this.handleClick}>add</button>
            </div>
        )
    }
}

root.render(<App />);

// 这里有个代码引用结束的```被吞掉了
<div id="jsx-demo"></div>

实际效果:

const { createRoot } = ReactDOM
const root = createRoot(document.getElementById('jsx-demo'))

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = { data: 0 };
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState({
            data: this.state.data + 1
        });
    }

    render() {
        return (
            <div>
                <div>state: {this.state.data}</div>
                <button onClick={this.handleClick}>add</button>
            </div>
        )
    }
}

root.render(<App />);

渲染jsx-hooks版本

Class写法真是几年没写过了, 现在都用hooks的函数式写法. 同样可以支持. 示例代码:

```klipse-jsx
const { createRoot } = ReactDOM
const root = createRoot(document.getElementById('jsx-hooks-demo'))

const App = () => {
    const [state, setState] = React.useState(0)
    const handleClick = () => {
        setState(state + 1)
    }
  
    return (
        <div>
            <div>state: {state} </div>
            <button onClick={handleClick}>
                add
            </button>
        </div>
    )
}

root.render(<App />);

// 这里有个代码引用结束的```被吞掉了
<div id="jsx-hooks-demo"></div>

实际效果:

const { createRoot } = ReactDOM
const root = createRoot(document.getElementById('jsx-hooks-demo'))

const App = () => {
    const [state, setState] = React.useState(0)
    const handleClick = () => {
        setState(state + 1)
    }
  
    return (
        <div>
            <div>state: {state} </div>
            <button onClick={handleClick}>
                add
            </button>
        </div>
    )
}

root.render(<App />);

转化jsx

klipse还提供了一个jsx的转化代码, 比如以下代码, 添加klipse-transpile-jsx可以将jsx的render内的内容转化为React.createElement, 目前看来没什么卵用

除了打算用纯js代码, 输出渲染react组件. 示例代码:

```klipse-transpile-jsx
<div>
    <div>state: {state}</div>
    <button onClick={handleClick}>{btnName}</button>
</div>

实际效果:

    <div>
        <div>state: {state}</div>
        <button onClick={handleClick}>{btnName}</button>
    </div>

利用转化jsx

用纯js代码, 输出渲染react组件, 以下代码在html的纯script标签下就可执行. 示例代码:

```klipse-js
const { createRoot } = ReactDOM
const root = createRoot(document.getElementById('render-js-react'));
const App = (props) => {
    const { btnName = "按钮" } = props
    const [state, setState] = React.useState(0)
    const handleClick = () => {
        setState(state + 1)
    }

    return React.createElement(
        "div",
        null,
        React.createElement(
            "div",
            null,
            "state: ",
            state
        ),
        React.createElement(
            "button",
            { onClick: handleClick },
            btnName
        )
    );
}
root.render(
    React.createElement(App)
);
// 这里有个代码引用结束的```被吞掉了
<div id="render-js-react"></div>

实际效果:

const { createRoot } = ReactDOM
const root = createRoot(document.getElementById('render-js-react'));
const App = (props) => {
    const { btnName = "按钮" } = props
    const [state, setState] = React.useState(0)
    const handleClick = () => {
        setState(state + 1)
    }

    return React.createElement(
        "div",
        null,
        React.createElement(
            "div",
            null,
            "state: ",
            state
        ),
        React.createElement(
            "button",
            { onClick: handleClick },
            btnName
        )
    );
}
root.render(
    React.createElement(App)
);

运行Vue

引入Vue

示例代码:

<pre>
    <code
        class="klipse-js"
        data-external-libs="https://unpkg.com/vue@3/dist/vue.global.js"
    >
        console.log('Vue keys length:', Object.keys(Vue).length)
    </code>
</pre>

实际效果:


        console.log('Vue keys length:', Object.keys(Vue).length)
    

运行VueDemo

示例代码:

```klipse-js
const { createApp } = Vue

createApp({
    data() {
        return {
            count: 0
        }
    }

}).mount('#app-vue')
// 这里有个代码引用结束的```被吞掉了
<div id="app-vue">
    <button v-on:click="count++">Add 1</button>
    <p>{{count}}</p>
</div>

实际效果:

const { createApp } = Vue

createApp({
    data() {
        return {
            count: 0
        }
    }

}).mount('#app-vue')

{{count}}

注意不要用vue的语法糖, 因为原生html页面并没有template包裹处理, 我的v-on:click变为@click就不生效了.

关于运行Vue的补充

在本示例中, script的引入是通过data-external-libs, 他实际是klipse的封装, 盲猜针对js, 他会处理成script的src.

遗憾的是, 我并没有看到该库拓展处理script的type, 而vue的官网纯html项目展示很多是处理成module.

<script type="module">
    ...
</script>

所以想要在blog内以比较顺手的写法写Vue demo, 需要自己做一些变通处理.

另外, 有任何Vue在Blog下内运行的问题, 不要找我, 我是Vue菜逼.

Tags: blog React klipse