我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Vue中Vue.extend()的使用及解析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Vue中Vue.extend()的使用及解析

Vue Vue.extend()的使用

Vue.extend 属于 Vue 的全局 API,在实际业务开发中我们很少使用,因为相比常用的 Vue.component 写法使用 extend 步骤要更加繁琐一些。但是在一些独立组件开发场景中,Vue.extend + $mount 这对组合是我们需要去关注的。

应用场景

在 vue 项目中,初始化的根实例后,所有页面基本上都是通过 router 来管理,组件也是通过 import 来进行局部注册,所以组件的创建不需要去关注,相比 extend 要更省心一点点。但是这样做会有几个缺点:

组件模板都是事先定义好的,如果我要从接口动态渲染组件怎么办?所有内容都是在 #app 下渲染,注册组件都是在当前位置渲染。如果我要实现一个类似于 window.alert() 提示组件要求像调用 JS 函数一样调用它,该怎么办?

这时候,Vue.extend + vm.$mount 组合就派上用场了。

简单实用

基础用法

Vue.extend( options )

  • 参数:{Object} options
  • 用法:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象;
  • data 选项是特例,需要注意: 在 Vue.extend() 中它必须是函数;      
<div id="mount-point"></div>
// 创建构造器
var Profile = Vue.extend({
  template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
  data: function () {
    return {
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    }
  }
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
// 结果如下:
<p>Walter White aka Heisenberg</p>

可以看到,extend 创建的是 Vue 构造器,而不是我们平时常写的组件实例,所以不可以通过 new Vue({ components: testExtend }) 来直接使用,需要通过 new Profile().$mount(’#mount-point’) 来挂载到指定的元素上。

第二种写法

可以在创建实例的时候传入一个元素,生成的组件将会挂载到这个元素上,跟 $mount 差不多。

// 1. 定义一个vue模版 
let  tem ={
    template:'{{firstName}} {{lastName}} aka {{alias}}',
    data:function(){    
    return{    
	    firstName:'Walter',   
	    lastName:'White',    
	    alias:'Heisenberg'
    }
}
// 2. 调用
const TemConstructor = Vue.extend(tem) 
const intance = new TemConstructor({el:"#app"}) // 生成一个实例,并且挂载在 #app 上

使用Vue.extend()编写vue插件

今天,我们使用Vue.extend()编程式的写法来编写一个vue插件,本质是将插件实例挂载到Vue的原型上。然后,就像element-ui的toast组件那样,使用this.$toast()实例方法去调用插件。

Vue.extend()

使用Vue这个基础构造器,构造出一个“子类”,其实就是个构造函数,通过new运算符生成vue实例。具体见官方文档Vue-extend。

如何编程式使用组件呢

比如,我们要实现个弹窗功能。通过编程式导航,我们就不用在模板中写了,可以使用js直接编写唤出弹窗。首先,我们正常的编写弹窗组件。如下:

<template>
  <div class="gulu-toast" :class="toastClasses">
    <div class="toast" ref="toast">
      <div class="message">
        <slot v-if="!enableHtml"></slot>
        <div v-else v-html="$slots.default[0]"></div>
      </div>
      <div class="line" ref="line"></div>
      <span class="close" v-if="closeButton" @click="onClickClose">
        {{closeButton.text}}
      </span>
    </div>
  </div>
</template>
<script>
  //构造组件的选项
  export default {
    name: 'Toast',
    props: {
      autoClose: {
        type: [Boolean, Number],
        default: 5,
        validator (value) {
          return value === false || typeof value === 'number';
        }
      },
      closeButton: {
        type: Object,
        default () {
          return {
            text: '关闭', callback: undefined
          }
        }
      },
      enableHtml: {
        type: Boolean,
        default: false
      },
      position: {
        type: String,
        default: 'top',
        validator (value) {
          return ['top', 'bottom', 'middle'].indexOf(value) >= 0
        }
      }
    },
    mounted () {
      // 这里是为了防止不断点击,出现多个弹窗
      const toast = document.getElementsByClassName('gulu-toast')[0]
      toast && document.body.removeChild(toast)
      this.updateStyles()
      this.execAutoClose()
    },
    computed: {
      toastClasses () {
        return {
          [`position-${this.position}`]: true
        }
      }
    },
    methods: {
      updateStyles () {
        this.$nextTick(() => {
          this.$refs.line.style.height =
            `${this.$refs.toast.getBoundingClientRect().height}px`
        })
      },
      execAutoClose () {
        if (this.autoClose) {
          setTimeout(() => {
            this.close()
          }, this.autoClose * 1000)
        }
      },
      close () {
        this.$el.remove()
        this.$emit('close')
        this.$destroy()
      },
      onClickClose () {
        this.close()
        if (this.closeButton && typeof this.closeButton.callback === 'function') {
          this.closeButton.callback(this)//this === toast实例
        }
      }
    }
  }
</script>

接下来,就是Vue.extend()出场了。

import Toast from './class="lazy" data-src/toast.vue';
Toast.install = function (Vue) {
    // 其实就是全局挂载使用
    Vue.prototype.$toast = function (text, props) {
        const ToastMain = Vue.extend(Toast)
        const instance = new ToastMain({
            propsData: props // 这里必须是propsData
        })
        instance.$slots.default = [text] // 插槽内容
        // instance.$mount().$el 该段代码意义为:
        // 文档之外渲染,并且获取该实例的根DOM元素,将其插入到body元素中。
        document.body.appendChild(instance.$mount().$el) 
    }
}
export default Toast

我们在main.js入口文件中,使用Vue.use()安装后,就可以在任何地方使用了~~。

具体使用

this.$toast("关闭吗?", {
        closeButton: {
          text: "关闭",
          callback: () => {
            console.log('已经关闭了');
          },
        },
        autoClose: 12,
        position: 'bottom'
      });

小结:

首先,Vue.extend 获得是一个构造函数,可以通过实例化生成一个 Vue 实例。

实例化时可以向这个实例传入参数,但是需要注意的是 props 的值需要通过 propsData 属性来传递。

还可以通过$slots来自定义插槽内容。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Vue中Vue.extend()的使用及解析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Vue中Vue.extend()的使用及解析

这篇文章主要介绍了Vue中Vue.extend()的使用及解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
Vue中Vue.extend()的使用及解析
2022-11-13

关于vue.extend的使用及说明

这篇文章主要介绍了关于vue.extend的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-03-06

vue中Vue.set()的使用以及对其进行深入解析

vue不允许在已经创建的实例上动态添加新的根级响应式属性,不过可以使用Vue.set()方法将响应式属性添加到嵌套的对象上,下面这篇文章主要给大家介绍了关于vue中Vue.set()的使用以及对其进行深入解析的相关资料,需要的朋友可以参考下
2023-01-04

VUE中的exportdefault和export使用方法解析

exportdefault和export都能导出一个模块里面的常量,函数,文件,模块等,在其它文件或模块中通过import来导入常量,函数,文件或模块。但是,在一个文件或模块中export,import可以有多个,exportdefault却只能有一个。
2022-12-14

编程热搜

目录