vue-base-4

1.组件

- 组件定义:
    一个组件就是一个功能体,内部封装了数据和方法,集成了html、css和js。
    每个组件都是Vue的实例对象。

- 组件优点:
    封装可复用的代码

- 组件与模块化区别:  
    组件化:主要从ui界面上进行划分。例如前端的组件化,方便ui组件的调用。
    模块化:主要从代码逻辑的角度进行划分,方便代码分层开发,保证每个功能模块职责单一。
    
- 组件分类:
    - 非单文件组件(.html)
    - 单文件组件(.vue)

2.非单文件组件 (.html)

1、Vue中使用组件的三大步骤:

  • 一、定义组件(创建组件)
  • 二、注册组件
  • 三、使用组件(写组件标签)

2、如何定义一个组件?

  • 1.使用Vue.extend(options)创建,其中options和new Vue(options)传入的options几乎一样,区别如下:

    • 1.el 不能写:组件不单为谁而服务,可以用在任何地方。
    • 2.data必须写成函数,为什么?
      组件被复用时,data就被复制一份,对象间的复制传递的是引用,修改一个实例的属性,其他被复制的实例数据也会受到影响。
      若是函数,每次复用调用函数会获得一个新对象,保证了数据的独立,互不干扰。
      简单来说避免组件被复用时,数据存在引用关系.
      
    • 3.配置组件结构:使用template,只是过渡,真实开发不用。
      • template:' ' 写单行html结构
      • template:`` 写多行html结构
      • template 中必须有一个根节点,template不渲染自身标签
  • 2.注册组件

    • 1.局部注册:在new Vue的时候传入components:{}选项
    • 2.全局注册:使用Vue.component('组件名',引用的组件)
  • 3.使用组件标签:

    • [脚手架专用,不使用脚手架导致后续组件无法渲染]

3、组件几个注意点:

  • 1、注册名命名(注册名和使用标签始终是对应的)
    • 1个单词
      • 纯小写,使用标签也是纯小写
      • 首个字母大写,使用标签也是首字母大写(跟开发者工具呼应)
    • 多个单词
      • kabab-case:全小写中间用- my-school,使用标签同样对应,
      • CamelCase每个单次首字母大写,MySchool,使用标签同样对应, [脚手架专用]
    • 备注:
      • 1.禁止使用html已有标签名作为注册组件名
      • 2.关于name
        • 若定义组件时指定了name,则开发者工具使用name作为呈现的名字,首字母依旧会大写
        • 若定义组件时未指定name,则开发者工具使用注册的组件名作为呈现名字,首字母大写
  • 2、关于组件标签
    • [自闭合标签脚手架专用]
  • 3、一个简写形式
    • const school = Vue.extend(options) 生成并返回VC构造函数,再拿过来用
      • 显示使用Vue.extend会立即生成并返回VueComponent构造函数。注册components对象只是做了引用,页面使用标签时(页面渲染)再new实例化(页面会传不同参数)
    • const school = options 用的时候再调用Vue.extend生成并返回VC构造函数,再拿过来用
      • 创建school时只是对象,注册componnets引入对象,在页面使用组件标签时再判断对象或VC构造函数,对象再调用Vue.extend,然后实例化

4、组件的定义和使用

// 1、创建组件
//显示使用Vue.extend会立即生成并返回VueComponent构造函数
//components对象只是做了引用,页面使用标签时(页面渲染)再new实例化
const s = Vue.extend({
    name:'',//组件名称
    //模板结构
    template:` 
        

你好{{msg}}

`, data(){ return{ msg:'tom' } } }) 备注: 1.配置对象与new Vue()传入对象几乎一致,区别有两点: - 1.el属性不能写,因为组件不属于谁,vm可以将其用在任何处,而el只能用于new创建的实例身上。 - 2.data对象要用函数返回,否则报错。vue这样设计的原因是,对象传递的是引用,修改组件会影响到其他组件。而函数返回{},就是返回一个新对象,组件内可以维护自己的私有变量。 2.非单文件html中,模板结构只能写template,只是过渡,真实开发不用。 template:'' //写单行html结构 template:`` //写多行html结构 template:'
' //template中必须有一个根节点,template不渲染自身标签 // 2、注册组件 // 局部注册 new Vue({ el:'#root', components:{ school // school:school的简写:注册的名字和引用的变量同名可以使用 school:school school:s //school为注册的组件名字,s为中转变量 }, }) //全局注册 Vue.component('school',s)//school:注册的组件名,s:引入的中转变量

3.组件嵌套

  • 嵌套
    • 组件注册给谁了,就在谁那使用
  • 引出app概念
    • 一般采用app管理所有组件,vm只管理app组件,app是vm之下,组件之上
  • template
    • template里必须有一个根节点,vm中使用template会覆盖el挂载的节点
    //定义student组件
    const student = Vue.extend({
        name:'student',
        template:`
            

{{name}}

`, data(){ return { age:18 } } }) //定义school组件,school中引入子组件student const school = Vue.extend({ name:'school', template:`

学校名称:{{name}}

`, data(){ return { name:'大学' } }, components:{ student //注册组件(局部) } }) //定义hello组件 const hello = Vue.extend({ template:`

{{msg}}

`, data(){ return { msg:'hello!' } } }) //定义app组件 const app = Vue.extend({ template:`
`, components:{ school,hello } }) //创建vm new Vue({ //注意,vm使用template显示内容,会替换掉root的div //如果在div里使用组件标签,则包含root的div template:'', el:'#root', components:{app} //注册组件(局部) })

5.VueComponent

  • 1.Vue.extend调用后生成并返回一个名为VueComponent的构造函数,school组件实际就是VueComponent的构造函数。

  • 2.我们只需要写,Vue解析时会帮我们创建school组件的实例对象
    即Vue执行:new VueComponent(options),携带传给子组件的传参option。

  • 3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!因为代码里是var sub,每次都生成一个新的函数

  • 4.组件执行的原理总结:

    • 1、Vue.extend生成返回不同的构造函数作准备。
    • 2、数据改变引起模板解析。模板解析时,寻找components对象的组件引用,
      • 若是构造函数传递不同参数实例化对象;
      • 若是对象,调用Vue.extend返回构造函数再实例化
  • 5.关于this指向:

    • (1).组件配置中:
      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
    • (2).new Vue(options)配置中:
      data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
  • 6.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)。
    Vue的实例对象,以后简称vm。

6.一个重要的内置关系

  1. 一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype
  2. 为什么要有这个关系:让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
  3. vm与vc区别在于,vc不能传el属性,且vc的data必须函数式返回对象,其他都一样。
    防止组件被多次引用时数据存在引用关系
//创建一个Demo的实例对象
const d = new Demo() //构造函数

console.log(Demo.prototype) //构造函数的原型对象,也叫显示原型属性

console.log(d.__proto__) //实力对象的原型对象,也叫隐式原型属性

console.log(Demo.prototype === d.__proto__) // 指向同一对象

Vue.prototype === vm.__proto__ //vue构造函数原型对象也是实力对象的原型对象
vm.__proto__.__proto__ === Vue.prototype.__proto__ === Object //vue原型对象是继承自object

VueComponent.prototype.__proto__ === Vue.prototype 
//VueComponent原型对象是继承自vue原型对象,所以VueComponent原型对象的原型对象是vue的原型对象
//这样VueComponent组件就有了vue的方法和属性

7.单文件组件 (.vue)

  • 1、命名

    • school my-school
    • School My-School 好处是与开发者工具呈现呼应
    • name最好与文件名一致
  • 2、.vue文件

  • 3、针对html、js、css,vue设计了