美文网首页
以 JSX 的方式来编写 Vue 代码

以 JSX 的方式来编写 Vue 代码

作者: wyc0859 | 来源:发表于2021-08-31 10:26 被阅读0次

    TSX优势

    代码效验、代码提示、错误提示
    支持ts里直接写标签 及 组件
    还可以将组件写在函数里,结合一下动态值,然后调用函数,实现组件参数的复杂计算

    //main.ts中将
    import App from './App.vue'
    改为:
    import App from './App'
    

    实现app.vue,用更直观的js写法,vue的h函数

    // App.vue 改为 App.ts
    import { createApp, defineComponent, h, reactive, ref ,PropType } from 'vue' 
    
    export default defineComponent({
     setup() {
       const state = reactive({
         name: 'ax:',
       })  
       const numberRef = ref("bx:")
       setInterval(() => {
         state.name += 'a' 
         numberRef.value += 'b' 
       }, 2000)
       return () => { 
         const number = numberRef.value //Ref的变化会引起return 函数的重新执行,所以才会重新渲染节点,让值有更新
         return h('div', { id: 'app' }, [h('p', state.name), h('p', number)])
       }
     },
    })
    

    JSX 编中写html标签

    jsx中写html标签是如何一步步进化衍变的

    1、渲染函数 render

    //main.ts
    import { createApp, defineComponent, createVNode,h } from "vue"; 
    
    
    const App2 = defineComponent({
       render() {
         return (
           //h('div', { id: 'app' }),
           createVNode('div', { id: 'app' }),
           [
             h('img', {
               alt: 'Vue logo'
             })
           ]
         )
       },
     })
     createApp(App2).mount("#app");
    

    h函数只是createVNode的简单封装,所以把h函数替换为createVNode也是一样的

    setup中使用H函数

    <template>
        <diy />
    </template>
    
    <script setup>
    import { ref,h } from 'vue'
    const msg = ref('abc')
    const diy = () => h('div',msg.value);
    </script>
    

    2、Babel 插件

    如果你写了很多 render 函数,可能会觉得这样的代码写起来很痛苦,特别是对应的模板如此简单的情况下。
    这就是为什么会有一个 Babel 插件,用于在 Vue 中使用 JSX 语法,它可以让我们回到更接近于模板的语法上。

      render() {
        return <div>Vue 3.0</div>;
      },
    

    vue2有官方的babel插件
    安装: npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props

    vue3没有官方的,有阿里出的 vuejs/jsx-next
    安装: npm install @vue/babel-plugin-jsx -D
    还需要在babel.config.js文件中配置plugins: ["@vue/babel-plugin-jsx"]

    \color{red}{注意文件后缀必须是小写TSX,不能是TS}

    //App.tsx
    import { defineComponent} from 'vue'  
    export default defineComponent({
      setup() {   
        return () => { 
          return <div>asd</div>;
        }
      },
    })
    



    App.vue改为App.jsx需要安装扩展,不然会报错!
    https://github.com/vuejs/jsx-next

    npm install @vue/babel-plugin-jsx -D
    新建一个 .babelrc 文件,内容如下
    {
      "plugins": ["@vue/babel-plugin-jsx"]
    }
    

    最新版vue3不安装这个扩展,改为import App from './App'也是能正常运行App.tsx的

    //App.vue.tsx
    import { createApp, defineComponent, h, reactive, ref ,PropType } from 'vue'
    import HelloWorld from './components/HelloWorld'
    const img = require('./assets/logo.png') // eslint-disable-line
    
    //setup return里可以直接放组件,也可以提出来放函数里计算后传参并返回组件
    //cfg:any,在组件处不会报错,因为any代表任意,那config也是能适用的
    function renderHelloWorld(num: number,cfg:Config) { 
      return <HelloWorld age={num} msg="abc" config={cfg}  />
    }
    
    //所以为了判断类型,这里也要有一个config接口
    interface Config {
      name: string,
      num: number
    }
    export default defineComponent({
      setup() {
        const state = reactive({
          name: 'ax:',
        }) 
    
        const cfg: Config={
            name:"abc",
            num:321
        } 
    
        const numberRef = ref("bx:")
        setInterval(() => {
          state.name += 'a' 
          numberRef.value += 'b' 
        }, 2000)
        return () => {
          const number = numberRef.value 
          return (
            <div id="app">
              <img src={img} alt="Vue logo" />
              <p>{state.name}</p>
              <p>{number}</p>
              <input type="text" v-model={state.name} />
              {renderHelloWorld(12,cfg)}
            </div>
          ) 
        }
      },
    })
    
    //HelloWorld.tsx
    import { defineComponent, PropType } from "vue";
    
    interface Config {
      name: string,
      num:number
    }
    
    const PropsType = {
      msg: String,
      config: {
        type: Object as PropType<Config>,
        required: true,
      },  
      age: {
        type: Number,
        required: true,
      },
    } as const;
    
    export default defineComponent({
      props: PropsType,
      setup(props) { 
        return () => <div>abc:{props.age}--{props.config.name}++</div>;
      },
    });
    
    

    组件如果是vue文件,那编辑器不会有代码提示和代码检测。组件为tsx文件则可以

    注意:

    在vscode中ts项目引入的库,如vue有红色底线,但运行又没问题问题,那就是vscode自身的bug
    解决办法:File -> Close folder然后File -> Open Folder 再次打开项目文件夹,错误就会消失

    相关文章

      网友评论

          本文标题:以 JSX 的方式来编写 Vue 代码

          本文链接:https://www.haomeiwen.com/subject/ejpailtx.html