Vue可复用解决方案

淡淡的烟草味﹌ 2024-04-06 12:06 142阅读 0赞

目录

一. 自定义指令

1.1.全局指令

1.2.局部指令

1.3.指令参数

二. Mixin混入

2.1.基本用法

2.2. 混入优先级

2.3.全局 Mixin

三. 插件

3.1.基本用法

3.2.给Vue扩展功能


一个项目是由很多组件组成的。而组件之间可能存在很多相似的功能,如果我们在每个组件中去重复定义这些功能,会使得项目出现代码冗余并提高了维护难度。针对这种情况官方提供了很多可复用解决方案,比如:自定义指令、Mixin、插件等。

一. 自定义指令

除了核心功能默认内置的指令 (例如 v-model 和 v-show 等),Vue 也允许创建自己的指令。自己做的指令中可以封装某个功能,这样就能达到复用代码的目的。

1.1.全局指令

下面实例中自定义一个全局指令,能够显示当前时间。

  1. <body>
  2. <div id="app">
  3. <div v-date></div>
  4. <div v-date></div>
  5. </div>
  6. <script src="https://unpkg.com/vue@next"></script>
  7. <script>
  8. let app = Vue.createApp({});
  9. app.directive('date', {
  10. mounted(el) {
  11. el.innerHTML = new Date();
  12. }
  13. })
  14. //注意这里:需要先声明自定义指令后再绑定视图
  15. app.mount('#app');
  16. </script>
  17. </body>
  • 使用Vue实例中的directive函数创建自定义指令。第一个参数是指令名,第二个参数是指令内容。

  • 自定义指令中,使用了 mounted 生命周期,因为需要操作DOM。

  • mounted 生命周期函数中有一个参数,此参数就是使用指令的DOM对象。

  • 使用时指令依然为 “v-指令名” 的形式。

  • 上面自定义指令直接挂载到Vue实例上,所以是全局指令

1.2.局部指令

下面单独创建自定义指令,然后在Vue实例中引用这个指令,所以是局部指令。

  1. <body>
  2. <div id="app">
  3. <div v-date></div>
  4. <div v-date></div>
  5. </div>
  6. <script src="https://unpkg.com/vue@next"></script>
  7. <script>
  8. const mydirective = {
  9. date: {
  10. mounted(el) {
  11. el.innerHTML = new Date();
  12. }
  13. }
  14. }
  15. let app = Vue.createApp({
  16. data() {
  17. return {
  18. }
  19. },
  20. directives: mydirective
  21. });
  22. app.mount('#app');
  23. </script>
  24. </body>
  • 上面代码中,单独创建一个自定义指令,所以需要在Vue实例中使用directives属性引用这个指令。

1.3.指令参数

指令作为封装好的一段功能代码,应该具有参数功能,这样才能更加灵活的封装代码。

下面实现一个带参数的自定义指令,它能够将图片按照指定大小显示成圆形图片。

  1. <body>
  2. <div id="app">
  3. <img src="img/gf01.jpeg" v-imgcir="200">
  4. </div>
  5. <script src="https://unpkg.com/vue@next"></script>
  6. <script>
  7. const mydirective = {
  8. imgcir: {
  9. mounted(el,binding) {
  10. el.style.width = binding.value+'px';
  11. el.style.height = binding.value+'px';
  12. el.style.borderRadius = (binding.value/2)+'px';
  13. }
  14. }
  15. }
  16. let app = Vue.createApp({
  17. data() {
  18. return {
  19. }
  20. },
  21. directives: mydirective
  22. });
  23. app.mount('#app');
  24. </script>
  25. </body>
  • 首先,在视图层使用自定义指令时添加一个参数值。

  • 自定义指令可以使用binding来接收这个参数,并使用binding.value的形式获取。


二. Mixin混入

官方解释:Mixin 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个 mixin 对象可以包含任意组件选项。当组件使用 mixin 对象时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项。

2.1.基本用法

  1. <body>
  2. <div id="app">
  3. <p>num:{
  4. {num}}</p>
  5. <p>name:{
  6. {name}}</p>
  7. </div>
  8. <script src="https://unpkg.com/vue@next"></script>
  9. <script>
  10. const common = {
  11. data(){
  12. return {
  13. name: '张三'
  14. }
  15. }
  16. }
  17. let app = Vue.createApp({
  18. data() {
  19. return {
  20. num: 10
  21. }
  22. },
  23. mixins: [common]
  24. });
  25. app.mount('#app');
  26. </script>
  27. </body>
  • 先定义共通内容。再使用mixins属性将此内容混入到Vue实例中。

  • 此时,Vue实例中就可以使用混入的内容了。

2.2. 混入优先级

一个 mixin 中可以书写 Vue 中的任何选项,包括 data、methods、计算属性等等。那么,如果混入内容与Vue原有选项内容有冲突时如何处理呢?

  1. <body>
  2. <div id="app">
  3. <p>num:{
  4. {num}}</p>
  5. <button @click="add">点击</button>
  6. </div>
  7. <script src="https://unpkg.com/vue@next"></script>
  8. <script>
  9. const common = {
  10. data(){
  11. return {
  12. num: 20
  13. }
  14. },
  15. methods:{
  16. add(){
  17. console.log('Mixin事件');
  18. }
  19. },
  20. created(){
  21. console.log('Mixin生命周期');
  22. }
  23. }
  24. let app = Vue.createApp({
  25. data() {
  26. return {
  27. num: 10
  28. }
  29. },
  30. mixins: [common],
  31. methods:{
  32. add(){
  33. console.log('Vue实例事件');
  34. }
  35. },
  36. created(){
  37. console.log('Vue生命周期');
  38. }
  39. });
  40. app.mount('#app');
  41. </script>
  42. </body>

通过上面实例可以发现优先级规则:

  • 在mixin与组件选项有重叠时,组件选项优先级高于mixin选项。

  • 但生命周期函数会先执行mixin的生命周期函数,再执行组件的。

2.3.全局 Mixin

Mixin 也可以进行全局注册。也就是将Mixin直接挂载到Vue实例上,这样,组件中就不用再写mixins: [common]选项了。这就是全局Mixin。

  1. <body>
  2. <div id="app">
  3. <p>num:{
  4. {num}}</p>
  5. <button @click="add">点击</button>
  6. </div>
  7. <script src="https://unpkg.com/vue@next"></script>
  8. <script>
  9. let app = Vue.createApp({
  10. data() {
  11. return {
  12. num: 10
  13. }
  14. },
  15. //mixins: [common],
  16. methods:{
  17. add(){
  18. console.log('Vue实例事件');
  19. }
  20. },
  21. created(){
  22. console.log('Vue生命周期');
  23. }
  24. });
  25. //将 Mixin直接挂载到Vue实例上
  26. app.mixin({
  27. data(){
  28. return {
  29. num: 20
  30. }
  31. },
  32. methods:{
  33. add(){
  34. console.log('Mixin事件');
  35. }
  36. },
  37. created(){
  38. console.log('Mixin生命周期');
  39. }
  40. });
  41. app.mount('#app');
  42. </script>
  43. </body>
  • 将Mixin直接挂载到Vue实例上。

  • Vue中就不需要mixins选项了。

注意:一旦使用全局 mixin,它将影响每一个之后创建的组件 (例如,每个子组件)。


三. 插件

plugin插件是把通用功能封装起来,通常向 Vue 添加全局级功能。比如,给Vue添加自定义指令、Mixin等。

3.1.基本用法

下面实例中,声明一个插件并被Vue实例所引用。

  1. <body>
  2. <div id="app">
  3. </div>
  4. <script src="https://unpkg.com/vue@next"></script>
  5. <script>
  6. //对象形式声明插件
  7. const MyPlugin = {
  8. install(app, options) {
  9. console.log('hello world!');
  10. console.log(app);
  11. console.log(options);
  12. }
  13. }
  14. /*
  15. //函数形式声明插件
  16. const MyPlugin = (app, options) => {
  17. console.log('hello world!');
  18. console.log(app);
  19. console.log(options);
  20. }
  21. */
  22. let app = Vue.createApp({
  23. data() {
  24. return {
  25. }
  26. },
  27. });
  28. app.use(MyPlugin, { name: 'zhangsan' })
  29. app.mount('#app');
  30. </script>
  31. </body>
  • 声明插件可以有两种形式:对象形式、函数形式。

  • 如果是对象形式,那么需要声明 install 方法,并自动给 install 方法传递两个参数。

  • 如果是函数形式,那么直接给此函数传递两个参数。

  • 第一个参数为Vue实例,第二个参数为引用插件时所传递的数据。

  • 使用时,调用Vue实例的use方法引入插件,并给插件传递数据(可选)。

3.2.给Vue扩展功能

下面在插件中给Vue扩展功能。

  1. <body>
  2. <div id="app">
  3. <img src="img/gf01.jpeg" v-imgcir="200">
  4. <p>{
  5. {curdate}}</p>
  6. </div>
  7. <script src="https://unpkg.com/vue@next"></script>
  8. <script>
  9. const MyPlugin = {
  10. install(app, options) {
  11. app.directive('imgcir', {
  12. mounted(el, binding) {
  13. el.style.width = binding.value + 'px';
  14. el.style.height = binding.value + 'px';
  15. el.style.borderRadius = (binding.value / 2) + 'px';
  16. }
  17. });
  18. app.mixin({
  19. data(){
  20. return {
  21. curdate: new Date()
  22. }
  23. }
  24. });
  25. }
  26. }
  27. let app = Vue.createApp({
  28. data() {
  29. return {
  30. }
  31. },
  32. });
  33. app.use(MyPlugin)
  34. app.mount('#app');
  35. </script>
  36. </body>
  • 上面代码中,通过插件给Vue扩展了一个自定义标签,一个Mixin。

发表评论

表情:
评论列表 (有 0 条评论,142人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Vue表格组件复用

    复用的原则,将DOM的操作交给开发者,比如表头和表体,而封装只是将,样式和一些通用的方法进行封装。 目前想法是通过插槽进行实现,表格外框的内容是固定的,但是表头和表体是通