本次小编通过一个简单的实例来教给大家如何写一个vue插件,以及需要注意的地方,如果有需要的读者跟着学习一下吧。
在学习之前,先问问自己,为什么要编写vue的插件。
在一个项目中,尤其是大型项目,有很多部分需要复用,比如加载的loading动画,弹出框。如果一个一个的引用也稍显麻烦,而且在一个vue文件中引用的组件多了,会显得代码臃肿,所以才有了封装vue插件的需求。
说完需求,就来看看具体实现。目前我尝试了两种不一样的插件编写的方法,逐个介绍。
这是我的项目目录,大致的结构解释这样,尽量简单,容易理解。
一个是loading插件,一个是toast插件,不同的地方在于:loading插件是作为组件引入使用,而toast插件是直接添加在挂载点里,通过方法改变状态调用的。
目前使用起来是酱紫的:
toast插件
toast文件下有两个文件,后缀为vue的文件就是这个插件的骨架,js文件一个是将这个骨架放入Vue全局中,并写明操作逻辑。
可以看一下toast.vue的内容:
<template> <transition name="fade"> <p v-show="show"> {{message}} </p> </transition> </template> <script> export default { data() { return { show: false, message: "" }; } }; </script> <style lang="scss" scoped> .toast { position: fixed; top: 40%; left: 50%; margin-left: -15vw; padding: 2vw; width: 30vw; font-size: 4vw; color: #fff; text-align: center; background-color: rgba(0, 0, 0, 0.8); border-radius: 5vw; z-index: 999; } .fade-enter-active, .fade-leave-active { transition: 0.3s ease-out; } .fade-enter { opacity: 0; transform: scale(1.2); } .fade-leave-to { opacity: 0; transform: scale(0.8); } </style>
这里面主要的内容只有两个,决定是否显示的show
和显示什么内容的message
。
粗看这里,有没有发现什么问题?
这个文件中并没有props
属性,也就是无论是show也好,message也好,就没有办法通过父子组件通信的方式进行修改,那他们是怎么正确处理的呢。别急,来看他的配置文件。
index.js:
import ToastComponent from './toast.vue' const Toast = {}; // 注册Toast Toast.install = function (Vue) { // 生成一个Vue的子类 // 同时这个子类也就是组件 const ToastConstructor = Vue.extend(ToastComponent) // 生成一个该子类的实例 const instance = new ToastConstructor(); // 将这个实例挂载在我创建的p上 // 并将此p加入全局挂载点内部 instance.$mount(document.createElement('p')) document.body.appendChild(instance.$el) // 通过Vue的原型注册一个方法 // 让所有实例共享这个方法 Vue.prototype.$toast = (msg, duration = 2000) => { instance.message = msg; instance.show = true; setTimeout(() => { instance.show = false; }, duration); } } export default Toast
这里的逻辑大致可以分成这么几步:
创建一个空对象,这个对象就是日后要使用到的插件的名字。此外,这个对象中要有一个install的函数。使用vue的extend方法创建一个插件的构造函数(可以看做创建了一个vue的子类),实例化该子类,之后的所有操作都可以通过这个子类完成。之后再Vue的原型上添加一个共用的方法。
这里需要着重提的是Vue.extend()
。举个例子,我们日常使用vue编写组件是这个样子的:
Vue.component('MyComponent',{ template:'<p>这是组件</p>' })
这是全局组件的注册方法,但其实这是一个语法糖,真正的运行过程是这样的:
let component = Vue.extend({ template:'<p>这是组件</p>' }) Vue.component('MyComponent',component)
Vue.extend会返回一个对象,按照大多数资料上提及的,也可以说是返回一个Vue的子类,既然是子类,就没有办法直接通过他使用Vue原型上的方法,所以需要new一个实例出来使用。
在代码里console.log(instance)
得出的是这样的结果:
可以看到$el:p.toast
也就是toast组件模板的根节点。
疑惑的是,我不知道为什么要创建一个空的p节点,并把这个实例挂载在上面。我尝试注释这段代码,但是运行会报错。
查找这个错误的原因,貌似是因为
document.body.appendChild(instance.$el)
这里面的instance.$el
的问题,那好,我们console下这个看看。WTF!!!!结果居然是undefined
。
那接着
console.log(instance)
和上一张图片比对一下,发现了什么?对,$el消失了,换句话说在我注释了
instance.$mount(document.createElement('p'))
这句话之后,挂载点也不存在了。接着我试着改了一下这句:
instance.$mount(instance.$el)
$el又神奇的回来了………………
暂时没有发现这种改动有什么问题,可以和上面一样运行。但无论如何,这也就是说instance实例必须挂载在一个节点上才能进行后续操作。
之后的代码就简单了,无非是在Vue的原型上添加一个改变插件状态的方法。之后导出这个对象。
接下来就是怎么使用的问题了。来看看main.js是怎么写的:
import Vue from 'vue' import App from './App' // import router from './router' import Toast from './components/taost' Vue.use(Toast) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ // router, render: h => h(App) }).$mount('#app')
这样就可以在其他vue文件中直接使用了,像这样:
// app.vue <template> <p id="app"> <loading duration='2s' :isshow='show'></loading> <!-- <button @click="show = !show">显示/隐藏loading</button> --> <button @click="toast">显示taost弹出框</button> </p> </template> <script> export default { name: "app", data() { return { show: false }; }, methods: { toast() { this.$toast("你好"); } } }; </script> <style> #app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
通过在methods中增加一个方法控制写在Vue原型上的$toast对toast组件进行操作。
这样toast组件的编写过程就结束了,可以看到一开始gif图里的效果。
loading插件
经过上一个插件的讲解,这一部分就不会那么细致了,毕竟大多数都没有什么不同,我只指出不一样的地方。
<template> <p class='wrapper' v-if="isshow"> <p class='loading'> <img src="./loading.gif"> </p> </p> </template> <script> export default { props: { duration: { type: String, default: "1s" //默认1s }, isshow: { type: Boolean, default: false } }, data: function() { return {}; } }; </script> <style lang="scss" scoped> </style>
这个就只是一个模板,传入两个父组件的数据控制显示效果。
那再来看一下该插件的配置文件:
import LoadingComponent from './loading.vue' let Loading = {}; Loading.install = (Vue) => { Vue.component('loading', LoadingComponent) } export default Loading;
这个和taoat的插件相比,简单了很多,依然是一个空对象,里面有一个install方法,然后在全局注册了一个组件。
比较
那介绍了这两种不同的插件编写方法,貌似没有什么不一样啊,真的是这样么?
来看一下完整的main.js和app.vue这两个文件:
// main.js import Vue from 'vue' import App from './App' // import router from './router' import Toast from './components/taost' import Loading from './components/loading' Vue.use(Toast) Vue.use(Loading) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ // router, render: h => h(App) }).$mount('#app') // app.vue <template> <p id="app"> <loading duration='2s' :isshow='show'></loading> <!-- <button @click="show = !show">显示/隐藏loading</button> --> <button @click="toast">显示taost弹出框</button> </p> </template> <script> export default { name: "app", data() { return { show: false }; }, methods: { toast() { this.$toast("你好"); } } }; </script> <style> #app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
可以看出来,loading是显示的写在app.vue模板里的,而toast并没有作为一个组件写入,仅仅是通过一个方法控制显示。
来看一下html结构和vue工具给出的结构:
看出来了么,toast插件没有在挂载点里面,而是独立存在的,也就是说当执行
vue.use(toast)
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上是如何编写vue插件的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Atom编辑器mac版下载
最流行的的开源编辑器

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境