vue组件创建
一、普通组件
- 全局注册
Vue.component 是用来全局注册组件的方法,其作用是将通过 Vue.extend 生成的扩展实例构造器注册(命名)为一个组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元素时,会自动调用类似于 new myVue 这样的构造函数来生成组件实例,并挂载到自定义元素上。
// 使用kebab-case
Vue.component('my-component-name', { // ... 选项 ... })
当使用kebab-case(短横线分隔命名)定义一个组件时,你也必须在引用这个自定义元素时使用kebase-case,例如<my-component-name>。
// 使用PascalCase
Vue.component('MyComponentName', { /* ... */ })
当使用PascalCase(首字母大写命名)定义一个组件时,你在引用这个自定义元素时这两种命名法都可以使用,也就是说<my-component-name> 和 <MyComponentName>都是可接受的。注意,尽管如此,直接在DOM(即非字符串的模板)中使用时只有kabab-case是有效的。
- 局部注册
使用全局注册的话,即使你在项目中没有用到该组件,它仍然会被包含在你最终的构建结果中,这造成了用户下载的Javascript的无谓的增加。在这些情况下,可以采用局部注册
var ComponentA = { /* ... */ } var ComponentB = { /* ... */ } var ComponentC = { /* ... */ }
然后再components选项中定义你想要使用的组件:
new Vue({ el: '#app', components: { 'component-a': ComponentA, 'component-b': ComponentB } })
二、提示弹窗类组件
弹窗这类组件的特点是它们在当前vue实例之外独立存在,通常挂载于body;它们是通过JS动态创建的,不需要在任何组件中声明。常见使用如下
this.$createComponent(Notice,{ // options })
- 采用render
import Vue from 'vue' // 创建函数接收要创建组件定义 function createComponent(Component, props) { // 创建一个Vue新实例 const vm = new Vue({ render(h) { // render函数将传入组件配置对象转换为虚拟dom console.log(h(Component, { props })) return h(Component, { props }) } }).$mount()//执行挂载函数,但未指定挂载目标,表示只执行初始化工作 // 将生成dom元素追加至body document.body.appendChild(vm.$el) // 给组件实例添加销毁方法 const comp = vm.$children[0] comp.remove = () => { // 添加销毁方法,防止页面挂载的越来越多 document.body.removeChild(vm.$el) vm.$destroy() } return comp } // 暴露调用接口 export default createComponent
在需要使用该组件的页面中引入createComponent方法,调用时传入写好的组件页面及参数。
如果不想每次都去引入该方法的话,可以将其注册为插件
import Notice from '@/components/Notice' export default { install(Vue) { Vue.prototype.$notice = function (options) { return createComponent(Notice, options) } } }
调用Vue.use(MyPlugin),即可直接使用this.$notice()
- 使用Vue.extend()
Vue.extend返回的是一个扩展实例构造器
import Vue from 'vue' // 创建函数接收要创建组件定义 function createComponent(Component, props) { const Ctor = Vue.extend(Component) const comp = new Ctor({propsData: props}) comp.$mount(); document.body.appendChild(comp.$el) comp.remove = () => { // 移除dom document.body.removeChild(comp.$el) // 销毁组件 comp.$destroy(); } return comp } // 暴露调用接口 export default createComponent
后续使用方法同上。
三、Vue.extend和Vue.component及component的区别
- Vue.component和component两者都是需要先进行注册,然后通过标签名的方式在页面模板中使用,通过v-if或者v-show来实现显示与销毁或者隐藏。Vue.extend则是函数式编程,手动调用函数去控制创建和销毁。
- Vue.component的灵活性更强,可以采用slot,而Vue.extend只能传入props