自己封装 vue 组件 和 插件

vue 组件

一、组件的创建,两种方法。(本质上是1、2两种,vue文件,只是创建了一个  组件选项对象,仅是一个js对象)
1、定义组件:Vue.component('button-counter',{})。这种方法创建的组件,只能使用在父组件中,无法使用在插件中。因为在不挂载组件时,无法获取到组件对象。

Vue.component('my-component',{ 
            template : '<h3>这是使用 Vue.component 创建的组件</h3>',
            data(){
                return {}
            },
            methods: {
            }
})

2、通过Vue.extend({}) ,再实例化一个组件出来。 https://www.w3cplus.com/vue/vue-extend.html

   个人理解:Vue.extend() 方法 的 作用就是将一个 组件选项对象  变成一个 组件类。可以直接把 导入的 vue组件 ,作为 Vue.extend() 的参数。

let baseExtend = Vue.extend({
    template: `<p> {{ firstName }} {{ lastName }} aka {{ alias }}</p>`,
    data() {
        return {
            firstName: '大漠',
            lastName: 'w3cplus',
            alias: '大漠_w3cplus'
        }
    },
    created() {
        console.log('onCreated-1');
    }
})
new baseExtend() // 实例化一个组件

 等同于:

// test.vue  (把上面的组件选项对象,写入一个 vue文件中)
。。。
import test from './test.vue'  // 引入 一个vue组件文件

let baseExtend = Vue.extend(test)  // 这里通过打印test,发现test和上面的 Vue.extend()的参数属性名不完全相同。但是通过 Vue.extend() 后是一样。个人猜测 vue组件文件 导入 ,应该是webpack 做了某些处理了。不用去深究

new baseExtend() // 实例化一个组件

3、vue文件(这个其实没有创建组件):vue文件的组件,其它的地方使用,一定要先导入,导入获得的只是一个有关这个组件的 js对象,还不是一个组件(应该就是1和2中参数中的对象)。
   要使用这个组件,还需要把这个 js对象注入到组件中。(我猜使用Vue.extend应该也是可以的)

感悟:通过打印  import ToastComponent from './toast.vue'     console.log(ToastComponent)   发现  ToastComponent 中  template 属性,但是里面有其它的属性。

      vue文件是webpack才有的,直接 导入一个 vue文件,得到 一个 组件选项对象。虽然打印出来,和 直接写的 组件选项不完全一样。但是两者其实是一样的。应该是webpack对vue文件导入时做过处理,毕竟vue文件里还有css呢。

二、组件的使用:https://blog.csdn.net/WU5229485/article/details/82908068
1、组件在父组件的使用,只要组件注册(个人理解,就是创建一个挂载这个组件的标签)到父组件中就可以使用。当然,全局使用就全局注册。
2、组件在插件中的使用,必须要获取到这个组件对象才能使用。因为组件在插件中使用是不需要生成挂载标签的。一般是通过手动挂载的。

三、获取组件实例:
1、Vue.component注册的组件,必须在使用组件的时候,通过$refs属性获得。无法直接在没有挂载组件时,获取组件实例。
2、Vue.extend 获取组件实例很简单,直接new一个实例出来就可以了。插件中需要组件实例,都是用这种方式获取到的。


 vue 插件

1、vue 插件 格式:

   说明:install方式的插件,其实就是方便把插件注册到Vue对象上。就是把插件挂载在Vue对象下,这样在其他的地方使用时,可以不用引入Vue(就像Vue内置的功能一样使用,比如指令、方法、属性等)。

var MyPlugin = {}
MyPlugin.install = function (Vue, options) { Vue.myGlobalMethod = function () { // 1. 添加全局方法或属性,如: vue-custom-element // 逻辑... } Vue.directive('my-directive', { // 2. 添加全局资源:指令/过滤器/过渡等,如 vue-touch bind (el, binding, vnode, oldVnode) { // 逻辑... } ... }) Vue.mixin({ created: function () { // 3. 通过全局 mixin方法添加一些组件选项,如: vuex // 逻辑... } ... }) Vue.prototype.$myMethod = function (options) { // 4. 添加实例方法,通过把它们添加到 Vue.prototype 上实现 // 逻辑... } }

2、纯 js (不需要显示 html 标签)的插件很简单,很好开发。

// MyPlugin.js
var MyPlugin = {}
MyPlugin.install = function (Vue, option) {
  Vue.prototype.$msg = 'hello'
}
export default MyPlugin // 注意,vue 中导出一个对象都是使用 export default,因为其它的导出和 import混用,可能会出现报错的问题。
// main.js
import MyPlugin from './Plugins/MyPlugin'
Vue.use(MyPlugin)  // 这一步的作用是自动 调用插件里面的install方法,同时把Vue和option两个参数传递进去
// 使用的页面中
console.log(this.$msg)

3、需要显示 内容(即需要html标签显示的)的插件开发。如:Toast 插件 的开发  https://www.cnblogs.com/linxin/p/6637904.html 或  https://www.cnblogs.com/DangerousBaymax/p/9116453.html(亲测有效)

// Toast.js
var MyPlugin = {}
MyPlugin.install = function (Vue, option) {
  Vue.prototype.$Toast = (tips) => {
    let ToastTpl = Vue.extend({ // 1、创建构造器,定义好提示信息的模板
      template: '<div class="vue-toast">' + tips + '</div>'
    })
    let tpl = new ToastTpl().$mount().$el // 2、创建实例,在文档之外渲染成
    document.body.appendChild(tpl) // 3、把创建的实例添加到body中
    setTimeout(function () { // 4、延迟2.5秒后移除该提示
      document.body.removeChild(tpl)
    }, 2500)
  }
}
export default MyPlugin // 注意,vue 中导出一个对象都是使用 export default,因为其它的导出和 import混用,可能会出现报错的问题。
// main.js
import MyPlugin from './Plugins/MyPlugin'
Vue.use(MyPlugin)  // 这一步的作用是自动 调用插件里面的install方法,同时把Vue和option两个参数传递进去
// 使用的页面中
this.$Toast('Global') 

4、使用vue文件,作为组件的插件。https://blog.csdn.net/Wbiokr/article/details/78881308

// toast.vue
<template>
    <div>{{msg}}</div>
</template>
<script>
export default {
  data () {
    return {
      msg: ''
    }
  }
}
</script>
// toast.js
import toast from './toast.vue'

var plugin = {}
plugin.install = (Vue, option) => {
  Vue.prototype.$toast = (msg) => {
    var ToastClass = Vue.extend(toast)
    var ToastCom = new ToastClass()
    ToastCom.msg = msg
    var Dom = ToastCom .$mount().$el
    document.body.appendChild(Dom)
  }
}

export default plugin
this.$toast('数据')

5、自己写一个图片放大浏览的插件:

涉及的概念:

  a、组件构造器 (Vue.extend),再组件实例化。  https://cn.vuejs.org/v2/api/#Vue-extend(官网)

  b、组件名.$mount():手动将组件挂载到DOM 中 (和Vue初始化的el属性是一样的功能)。     https://cn.vuejs.org/v2/api/#vm-mount(官网)

     c、组件的 $el 属性:获取相应 vue(或组件)实例渲染($mount方法没有参数,就有渲染成DOM功能)后的DOM对象。  https://cn.vuejs.org/v2/api/#vm-el (官网)

总结:(个人)插件不一定非得使用Vue.use(install)的方法开发,直接写一个方法也是可以的。然后把这个方法挂载Vue实例上就可以了(官方推荐使用Vue.use这种方法)。

   需要组件的插件,难点在于,生成组件,并且把组件的标签手动挂载在DOM上。


四、Vue.component(el,{}) 和 Vue.extend({})有什么区别 https://www.cnblogs.com/battle-wang/p/9673577.html
1、Vue.component 作用是将组件注册到挂载标签el上。Vue.extend({})创建的组件类,需要使用vue.component进行实例化、或使用new extendName().$mount(''+el)方式进行实例化(从而实现模拟组件)

原文地址:https://www.cnblogs.com/wfblog/p/10519599.html