vue.extend、 new vue()、component、render

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue.extend、 new vue()、component、render相关的知识,希望对你有一定的参考价值。

参考技术A

前言
vue菜鸟一枚,对vue.extend、 new vue()、component、render比较懵逼,理不清关系,用法,查看了一些博文后,这里记录一下自己一点浅显的理解。

1.vue.extend、 new vue()
vue.extend() 是new vue() 的一个子类。用法都一样,都是实例化一个对象,然后是挂载到到dom元素上。

注意:
(1)挂载到dom元素,其次vue.extend()里面的的html模板 (template:"<p>hello</p>") 会覆盖被挂载的那个dom元素。 new vue() 里面的 render 的模板也会覆盖被挂载的那个dom元素。

(2)vue.extend()中的data是一个函数且返回一个对象。

2.vue.component全局注册和局部注册components
通过component注册组件不会覆盖原有的dom元素,直接把标签放到相应元素内就可使用。

下面进行实例对比
1.component注册使用

2.new 实例().$mount() 被挂在的元素会被覆盖

3.new vue()挂载到组件, render渲染的组件会覆盖被挂在的dom元素

注意
1.vue.extend()完了需要操作new 实例().$mount() ,才能挂载。

2.图片中的两种挂载方法

延伸 :vue.extend()的传参propsData

参考:
https://blog.csdn.net/dkr380205984/article/details/80116024
https://blog.csdn.net/Dear_Mr/article/details/72627214

通过 Vue.extend 或“new Vue()”创建组件时的不同行为:如果通过 new Vue 创建,则无法访问视图模型的数据和方法

【中文标题】通过 Vue.extend 或“new Vue()”创建组件时的不同行为:如果通过 new Vue 创建,则无法访问视图模型的数据和方法【英文标题】:Different behavior when component is created via Vue.extend or via "new Vue()": view-model's data and methods not accessible if created via new Vue 【发布时间】:2017-08-10 02:44:03 【问题描述】:

我有一个简单的组件你好:

<template>
  <div class="hello">
    <h1> msg </h1>
  </div>
</template>

<script>
export default 
  name: 'hello',
  props: 'myprop': String,
  data () 
    return 
      msg: 'Welcome ' + this.myprop
    
  ,
  methods: 
    mymethod: function () 
      return 'hi there'
    
  

</script>

现在,根据组件的创建方式,可以访问方法和数据。最简单的说明方法是通过测试,请阅读测试中的 cmets:

import Vue from 'vue'
import Hello from '@/components/Hello'

describe('Hello.vue', () => 
  it('with Vue Extend', () => 
    const Constructor = Vue.extend(Hello)
    const vm = new Constructor( propsData:  myprop: 'from test via propsdata'  ).$mount()
    // following 3 expections will all SUCCEED
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome from test via propsdata')
    expect(vm.myprop).to.equal('from test via propsdata')
    expect(vm.mymethod()).to.equal('hi there')
  )

  it('with new Vue', () => 
    const vm = new Vue(
      
        template: "<div><hello myprop='from template in test'></hello></div>",
        components:  'hello': Hello 
      ).$mount()
    // following expectation SUCCEDS
    expect(vm.$el.querySelector('.hello h1').textContent)
      .to.equal('Welcome from template in test')
    // following TWO expections will FAIL
    expect(vm.mymethod()).to.equal('hi there')
    expect(vm.myprop).to.equal('from template in test')
  )
)

我怎样才能让最后 2 个期望起作用?

谢谢。

【问题讨论】:

【参考方案1】:

您必须先注册您的自定义组件。有两种方法:

全球注册:

// register
Vue.component('hello', 
    template: "<div><hello myprop='from template in test'></hello></div>",
    // ...
);

// create your root instance
const vm = new Vue(
    el: '#root' // assume root eventually renders the 'hello' component
);

Vue.js 文档state that:

一旦注册,组件就可以在实例的模板中用作自定义元素 [...] 请确保组件在 实例化根 Vue 实例之前已注册。

通过本地注册:

// declare
var hello = 
    template: "<div><hello myprop='from template in test'></hello></div>",
    // ...
;

// create your root instance, registering everything in 'components'
const vm = new Vue(
    components:  'hello': Hello 
);

对于您的情况,前者似乎更合适,因为您希望保持 SOC 完整,并且只测试组件的功能。

【讨论】:

对不起,SOC是什么? 您能否以这样的方式提供测试 2 的完整代码,以使最后 2 个期望成功。我没看到:( 以下预期在测试 2 中失败:expect(vm.mymethod()).to.equal('hi there') expect(vm.myprop).to.equal('from template in test' ) 我的意思是,在 TEST 2 中,第一个期望成功,所以我假设组件安装正确,不是吗?仅在测试 2 中,期望 2 和 3 因不明原因而失败。 我真的不知道。您将不得不调试您的代码和/或发布一些错误,以便我们知道什么不起作用。【参考方案2】:

好的,我找到了解决方案。 要确定最后 2 个期望:

expect(vm.$children[0].mymethod()).to.equal('hi there')
expect(vm.$children[0].myprop).to.equal('from template in test')

回想起来,很明显,因为我们在 div 中添加了组件。

【讨论】:

以上是关于vue.extend、 new vue()、component、render的主要内容,如果未能解决你的问题,请参考以下文章

通过 Vue.extend 或“new Vue()”创建组件时的不同行为:如果通过 new Vue 创建,则无法访问视图模型的数据和方法

Vue 组件创建的流程源码分析

Vue.extend 有啥用?

前端框架vue.js系列:Vue.extendVue.component与new Vue

vue2入坑随记 -- 自定义动态组件

Vue.js(25)之 vue全局配置api介绍