Render渲染函数和JSX

1.Render函数

官网API地址:https://cn.vuejs.org/v2/guide/render-function.html

通常写的h为createElement的缩写,createElement 会返回虚拟节点 (virtual node)”,也常简写它为“VNode,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。

  • 第一个参数为一个 HTML 标签名、组件选项对象,为必选项。
  • 第二个参数为 {Object},是一个与模板中属性对应的数据对象。可选。
  • 第三个参数为{String | Array},是子级虚拟节点 (VNodes),由 `createElement()` 构建而成,也可以使用字符串来生成“文本虚拟节点”。可选。

1.1先写一个最简单的render函数例子:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Bus from "./lib/bus";
import $ from "jquery";

Vue.config.productionTip = false;
Vue.prototype.$bus = Bus;

new Vue({
  router,
  store,
  //render: h => h(App)
  render(h) {
    return h('div', {
      attrs: {
        id:"box"
      },
      style: {
        color:"blue"
      }
    },"Caoqi");
  },
}).$mount("#app");

1.2当第一个参数为组件时的写法如下,引入的组件为之前博客中讲过的Count-To组件(https://www.cnblogs.com/qicao/p/10805715.html)

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Bus from "./lib/bus";
import $ from "jquery";
import CountTo from "_c/count-to";

Vue.config.productionTip = false;
Vue.prototype.$bus = Bus;

new Vue({
  router,
  store,
  render: function(h) {
    return h(CountTo, {
      /**
       * class作为一个保留字必须用引号包裹
       * 接受一个字符串、对象或字符串和对象组成的数组
       */
      // 'class':'count-up wrapper',
      //class: ["count-to", true ? "classA" : "classB"],
      class: { "count-to": 1 === 1 },
      // 组件 prop
      props: { endVal: 200 },
      // DOM 属性
      domProps: {
        //innerHTML: "baz"
      },
      /**
       * 事件监听器在 `on` 属性内,
       * 但不再支持如 `v-on:keyup.enter` 这样的修饰器。需要在处理函数中手动检查 keyCode。
       */
      on: {
        "on-animation-end": function(val) {
          console.log("animation end");
        }
      },
      /**
       * 仅用于组件,用于监听原生事件,而不是组件内部使用`vm.$emit` 触发的事件。
       */
      nativeOn: {
        click: () => console.log("I am clicked!")
      },
      /*自定义指令*/
      directives: [],
      // 如果组件是其它组件的子组件,需为插槽指定名称
      slot: "name-of-slot"
    });
  }
}).$mount("#app");

显示效果:

1.3 创建子级虚拟节点:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Bus from "./lib/bus";
import $ from "jquery";
import CountTo from "_c/count-to";

Vue.config.productionTip = false;
Vue.prototype.$bus = Bus;

new Vue({
  router,
  store,
  /**
   * @param {String | Array} h 
   * 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,也可以使用字符串来生成“文本虚拟节点”。可选。
   */
  //render:h=>h('div','123')
  render:function(h) {
    return h('div', [
      h('span','span1'),  
      h('span','span2'),
    ])
  }
}).$mount("#app");

 1.4使用 JavaScript 代替模板功能

模板代码:

<template>
  <div>
    <ul @click="handlerClick">
      <li
        @click.stop="handlerClick"
        v-for="(item,index) in list"
        :key="`list_item_${index}`"
      >{{item.name}}</li>
    </ul>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [
        {
          name: "张三"
        },
        {
          name: "李四"
        }
      ]
    };
  },
  methods: {
    handlerClick: function(event) {
      console.log(event);
    }
  }
};
</script>

main.js: 

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Bus from "./lib/bus";
import $ from "jquery";
import CountTo from "_c/count-to";

Vue.config.productionTip = false;
Vue.prototype.$bus = Bus;

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");

 

若使用render函数中的js代替模板:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Bus from "./lib/bus";
import $ from "jquery";
import CountTo from "_c/count-to";

Vue.config.productionTip = false;
Vue.prototype.$bus = Bus;

const handleClick = event => {
  console.log(event);
  event.stopPropagation();
};

let list = [{ name: "张三" }, { name: "李四" }];
/**
 * Array map用法:
 * 功能:将原数组映射成新数组
 * https://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/#map
 */
const getLiEleArr = h => {
  return list.map((item,index) =>
    h(
      "li",
      {
        on: {
          click: handleClick
        },
        key:`list_item_${index}`
      },
      item.name
    )
  );
};
/**等效于 */
/*function getLiEleArr(h) {
  return list.map(function(item, index) {
    return h(
      "li",
      {
        on: {
          click: handleClick
        },
        key: `list_item_${index}`
      },
      item.name
    );
  });
}*/

new Vue({
  router,
  store,
  render: function(h) {
    return h(
      "ul",
      {
        on: {
          click: handleClick
        }
      },
      getLiEleArr(h)
    );
  }
}).$mount("#app");

函数式组件

JSX

作用域插槽

猜你喜欢

转载自www.cnblogs.com/qicao/p/10822811.html