Vue组件开发-高级玩法

在文章《Vue组件开发三板斧:prop、event、slot》中聊了常用的组件开发常用API和一些采坑心得,这里,再说说一些可能不太常用的高级玩法,可参考https://cn.vuejs.org/v2/api/。

1. 组件挂载

方式一:components属性

我们常用的创建组件方式就是文件声明,例如,在一个假设的 headTop.js 或 headTop.vue 文件中定义组件。然后通过components 引入组件,将其挂载在DOM节点上。

// layout.vue文件





组件headTop是挂载在组件layout中某个DOM节点下。

方式二:$mount

还有两种方式可以创建组件:

  • new Vue()
  • Vue.extend()

new Vue()创建一个 Vue 实例时,都会有一个选项 el,可以用来指定实例的根节点。如果不写 el 选项,那组件就处于未挂载状态。看看最顶层的App.vue是如何挂载到根节点上的:

import App from './App'
......
new Vue({
  el: '#app',
  router,
  store,
  template: '',
  components: { App }
})

Vue.extend 是基于 Vue 构造器,创建一个“子类”,它的参数跟 new Vue 的基本一样,但是data写法和组件类似,需要返回一个函数。

import Vue from 'vue';

const AlertComponent = Vue.extend({
  template: '
{{ message }}
', data () { return { message: 'Hello world!' }; }, });

Vue.extend是无法挂载组件的,此时需要:

  1. 使用$mount 渲染组件或者渲染并挂载组件
  2. 使用JS原生方法,挂载组件
// 方式一:仅仅渲染
const component = new AlertComponent().$mount();
// 通过JS方法组件添加到body节点上
document.body.appendChild(component.$el);

// 方式二:渲染挂载同时做
// 创建并挂载到 #app (会替换 #app)
new AlertComponent().$mount('#app')

应用场景:最常见的应该是自定义全局消息弹窗了。需要将组件挂载在body根节点上,此时,就可以通过$mount指定挂载节点。


同步歪歪一下React......

React 16 的portal也有异曲同工之妙。
portal可以帮助我们在JSX中跟普通组件一样直接使用dialog, 但是又可以让dialog内容层级不在父组件内,而是显示在独立于原来app在外的同层级组件。

HTML:

// 这里为我们定义Dialog想要放入的位置

JS:

const modalRoot = document.getElementById('modal-root');

// Let's create a Modal component that is an abstraction around the portal API.
class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement('div');
  }

  componentDidMount() {
    // Append the element into the DOM on mount. We'll render
    // into the modal container element (see the HTML tab).
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    // Remove the element from the DOM when we unmount
    modalRoot.removeChild(this.el);
  }
  
  render() {
    // Use a portal to render the children into the element
    return ReactDOM.createPortal(
      this.props.children,
      this.el,
    );
  }
}

2. 渲染函数 render

Vue.js 2.0使用了 Virtual DOM(虚拟 DOM)来更新 DOM 节点,提升渲染性能。

一般我们写 Vue.js 组件,模板都是写在