02 Vue进阶 render和jsx语法使用

一.render语法

 render.js

import Vue from 'vue'

const component = {
  props: ['props1'],
  name: 'comp',
  // template: `
  //   <div :style="style">
  //     <slot></slot>
  //   </div>
  // `,
  render (createElement) { // 等同上面使用template
    return createElement('div', { 
      style: this.style
      // on: {
      //   click: () => { this.$emit('click') }
      // }
    }, [
      this.$slots.header,
      this.props1
    ])
  },
  data () {
    return {
      style: {
        width: '200px',
        height: '200px',
        border: '1px solid #aaa'
      },
      value: 'component value'
    }
  }
}

new Vue({
  components: {
    CompOne: component
  },
  el: '#root',
  data () {
    return {
      value: '123'
    }
  },
  mounted () {
    console.log(this.$refs.comp.value, this.$refs.span)
  },
  methods: {
    handleClick () {
      console.log('clicked')
    }
  },
  // template: `
  //   <comp-one ref="comp">
  //     <span ref="span">{{value}}</span>
  //   </comp-one>
  // `,
  render (createElement) {
    return createElement(
      'comp-one',
      {
        ref: 'comp',
        props: {
          props1: this.value
        },
        // on: {
        //   click: this.handleClick
        // },
        nativeOn: {
          click: this.handleClick
        }
      },
      [
        createElement('span', {
          ref: 'span',
          slot: 'header',
          attrs: {
            id: 'test-id'
          }
        }, this.value)
      ]
    )
  }
})

二.jsx语法

环境安装:npm i babel-plugin-transform-vue-jsx -D

.babelrc配置 plugins: ["transform-vue-jsx "]

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2",
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime","transform-object-rest-spread"]
}

0. 变量如何绑定 在jsx如何实现

render(){
   return (
    <div>
     {this.show}
    </div>
   )
  }

1.v-if 在jsx如何实现

render(){
   return (
    <div>
     {this.show?'Vue':'React'}
    </div>
   )
  }

写三元表达式只能写简单的,那么复杂的还得用if/else

render(){
  let ifText
  if(this.show){
    ifText=<p>Vue</p>
  }else{
    ifText=<p>React</p>
  }
  return (
   <div>
    {ifText}
   </div>
  )
 }

2.v-for 在jsx如何实现

render(){
 return (
  <div>
   {this.list.map((v)=>{
    return <p>{v}</p>
   })}
  </div>
 )
}

 3.v-model 在jsx如何实现

<script>
export default {
  name: "item",
  data() {
    return {
      show: false,
      list: [1, 2, 3, 4],
      text: ""
    };
  },
  methods: {
    input(e) {
      console.log("input事件触发");
      this.text = e.target.value;
    }
  },
  render() {
    return (
      <div>
        <input type="text" value={this.text} onInput={this.input} />
        <p>{this.text}</p>
      </div>
    );
  }
};
</script>

4.事件 在jsx如何实现

export default {
  name: 'Tab',
  methods: {
    handleClick () {
      this.$parent.onChange(this.index)
    }
  },
  render () {
    const tab = this.$slots.label || <span>{this.label}</span>

    return (
      <li on-click={this.handleClick}>
        {tab}
      </li>
    )
  }
}
</script>

5. class,style,ref 在jsx如何实现

render (h) {
 return (
  <div
   // normal attributes or component props.
   id="foo"
   // DOM properties are prefixed with `domProps`
   domPropsInnerHTML="bar"
   // event listeners are prefixed with `on` or `nativeOn`
   onClick={this.clickHandler}
   nativeOnClick={this.nativeClickHandler}
   // other special top-level properties
   class={{ foo: true, bar: false }}
   style={{ color: 'red', fontSize: '14px' }}
   key="key"
   ref="ref"
   // assign the `ref` is used on elements/components with v-for
   refInFor
   slot="slot">
  </div>
 )
}

6.插槽定义 在jsx如何实现

默认插槽:this.$slots.default

render () {
    return (
      <div class='tabs'>
        <ul class='tabs-header'>
          {this.$slots.default}
        </ul>
      </div>
    )
  },

具名插槽:this.$slots.label

//使用页面main.vue
<tab index="2">
   <span slot="label" style="color:red">tab2</span>
   <p>this is content 2</p>
</tab>


//tab.vue
render () {
    const tab = this.$slots.label || <span>{this.label}</span>
    return (
      <li>
        {tab}
      </li>
    )
  }

7.jsx中怎么用自定义组件?

很简单,只需要导入进来,不用再在components属性声明了,直接写在jsx中比如

<script>
 import HelloWolrd from './HelloWorld'
  export default {
   name: "item",
   render(){
    return (
      <HelloWolrd/>
    )
   }
  }
</script>

 综合案例:tab.vue

<script>
export default {
  name: 'Tab',
  props: {
    index: {
      required: true,
      type: [Number, String]
    },
    label: {
      type: String,
      default: 'tab'
    }
  },
  mounted () {
    this.$parent.panes.push(this)
  },
  computed: {
    active () {
      return this.$parent.value === this.index
    }
  },
  methods: {
    handleClick () {
      this.$parent.onChange(this.index)
    }
  },
  render () {
    const tab = this.$slots.label || <span>{this.label}</span>
    const classNames = {
      tab: true,
      active: this.active
    }
    return (
      <li class={classNames} on-click={this.handleClick}>
        {tab}
      </li>
    )
  }
}
</script>

<style lang="css" scoped>
.tab {
  list-style: none;
  line-height: 40px;
  margin-right: 30px;
  position: relative;
  bottom: -2px;
  cursor: pointer;
}

.active {
  border-bottom: 2px solid blue;
}

.tab:last-child {
  margin-right: 0;
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值