Vue.extend()和我的两米大砍刀

Vue.extends是什么?

一个全局API,用于注册并挂载组件。
传统的引用组件的方式是使用import直接引入,但是使用Vue.extends()也可以实现。

使用规则

<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')
//你可以挂载到任何你想挂载的地方
//new Profile().$mount("#app")

注意:应用场景

这种操作类似于直接用js操作dom元素,belike

//创建
const dom = document.createElemnet('div')
dom.innerHtml = '你好'
//挂载
const container = document.getElementById('#mount-point')
container.appendChild(container)

通过这样的类比,我们很容易就明白为什么不推荐使用这种方式去引入使用一个模块组件,因为vue是有自己的虚拟DOM机制和组件挂载过程的,所以不推荐直接操作DOM。建议还是通过触发数据的变化,引发视图变化,即MVVM机制。
非必要请不要使用这种方式去声明使用组件,因为它会使代码变得不好读,且容易造成误解。那么我们在什么情景下去使用这个api呢?

  • vue.extend主要用于动态创建组件的场景,比如弹窗组件、提示框组件等。(官网这么说,但我依然建议不要这么做。)
  • 组件模板都是事先定义好的,我要从接口动态渲染组件。

1.举个我在项目中使用的实际场景:弹窗组件、提示框组件

function createModal(options) {
  const Modal = Vue.extend({
    data() {
      return {
        title: options.title,
        content: options.content
      };
    },
    template: `
      <div class="modal">
        <h2>{{ title }}</h2>
        {{ content }}
      </div>
    `
  });

  const modal = new Modal();
  modal.mount();
  document.body.appendChild(modal.el);
}

// 调用createModal方法创建一个弹窗
createModal({
  title: '提示',
  content: '这是一个弹窗示例'
});

2.一些操蛋的思路:当时在做这个对话的时候我只想着在发生对话的时候创建一个dom,而非使用视图触发,后面涉及了一些复杂交互头痛。写在这里用于加深学习吧……
对话场景

//DialogueItem.vue

<template>
    你好
    <div @click='stopCurrentAsk'>停止</div>
</template>
<script>
import Vue from 'vue'
export default {
    name: "DialogueItem ",
    props: ['type', 'content', 'id'],
    data() {
        return {
            loading: false,
        };
    },
    methods: {
        changeLoadingStatus(loading) {
            this.loading = loading
        },
        stopCurrentAsk(id) {
            this.$emit('stopAsk');
        },
    }
};
</script>
import DialogueItem from '@/components/DialogueItem'

 public instand = null
 
 this.instand = new (Vue.extend(DialogueItem))
        ({
          propsData: { type, id, content },
        })
 this.instand.$mount()
 //1.子组件触发父组件事件。
 //上文也提到,这就是个封装成组件的dom,所以,想要通过子组件DialogueItem触发父组件的内容,就直接监听事件就行了
 this.instand.$on("stopAsk", () => {});
 
 //2.父组件触发子组件
 this.instand.changeLoadingStatus(false)
 
 dom.appendChild(this.instand.$el)

说实话,真的难用,大抵是我场景不对。但是用都用了记录一下。

关于我的两米大砍刀

我在项目开发中发现同样的引用和参数,却无法产生同样的结果,最后定位发现是两个组件不同的构建方式导致的。这个罪魁祸首就是Vue.extend(),换一种组件引入方式就解决了。
至于为什么,搜索了半天没有明白是什么原因,有的说是vuex没有被正确注入到根实例中。
懒得看了,反正子组件无法使用vuex,也无法使用,谁知道可以来踩踩……
少用,谢谢!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值