自己封装 vue 组件 和 插件
vue 组件
一、组件的创建,两种方法。(本质上是1、2两种,vue文件,只是创建了一个 组件选项对象,仅是一个js对象)
1、通过 Vue.component 创建组件:
Vue.component 创建的组件,在全局中已经注册。所以不需要注册组件。
注册组件:有全局注册、局部 注册 之分。
个人理解:注册的组件只是 为了给 template 模板中使用组件。
var ComponentA = { template : '<h3>这是使用 Vue.component 创建的组件</h3>', data(){ return {} }, methods: { } }
- 全局注册:
// 组件对象,在注册时,会自动调用 Vue.extend方法。所以vue中生成组件本质只有 Vue.extend 方法。 Vue.component('my-component-name', ComponentA)
说明:Vue.component('my-component-name', ComponentA) 中一个组件语法糖,内部还是调用的的 Vue.extend(ComponentA) 生成组件。
- 局部注册:
new Vue({ el: '#app', components: { 'component-a': ComponentA } })
注: Vue.component ,返回一个全局注册组件的构造器,基于这个构造器就可以再次实例化一个组件出来。
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注册的是全局组件,js中可以通过Vue.component 方法获取;如果在template中有使用,也可以通过 $refs 属性获取;。
// 获取注册的组件 (始终返回构造器) var MyComponent = Vue.component('my-component') // MyComponent 是一个组件构造器,而不是这个组件实例本身。全局组件没有挂载到DOM(或虚拟don)上,就不存在组件实例,但是它的构造器是可以获取到的。 console.log(new MyComponent()) // 打印出一个 组件实例
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' }
// 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) } }
// 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 组件 和 插件的区别: https://blog.csdn.net/weixin_39111384/article/details/111919657
1、组件其实很好理解,我们平时使用的 .vue 文件就是一个组件。省略
2、插件通常是为了给 Vue
添加全局功能的。插件的功能范围没有严格意义上的限制。
四、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)方式进行实例化(从而实现模拟组件)
自动调用 Vue.extend