Vue.js 2.x 官方文档学习记录

概念

  • 是用于构建用户界面的渐进式框架
  • 自底向上逐层应用
  • 只关注视图层
  • 便于与第三方库或既有项目整合
  • 与现代化的工具链以及各种支持类库结合使用
  • 能够为复杂的单页应用提供驱动
  • 特点
    • 响应式数据
    • 指令系统

组件化应用构建

  • 允许使用小型、独立和通常可服用的组件构建大型应用

使用

  • 每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的
1.引入vue.js文件包
2.body中,设置Vue管理渲染的容器
3.实例化Vue对象 new Vue(); 4.设置Vue实例的选项:如el、data... new Vue({选项:值}); 5.在
中通过{{ }}使用data中的数据

Vue对象中的选项

注:watch和生命周期钩子函数不能用箭头函数,箭头函数没有this,函数中使用this会报错

  • el 挂载要渲染的元素
  • data 定义模板中需要的响应式数据
    • 如果想冻结data中的数据,可以通过设置Object.freeze()阻止修改现有的属性,也意味着响应系统无法再追踪变化
  • method 定义对象中的方法
  • 在调用对象中的选项时,选项名称前添加“ ”与用户定义的属性进行区分,如 t h i s . ”与用户定义的属性进行区分,如this. 与用户定义的属性进行区分,如this.data来调用对象中的data选项,在对象中调用属性和方法直接通过this.属性或方法来调用就可以

生命周期函数

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等
不要在选项property或回调上使用箭头函数,因为箭头函数的this是和父级上下文绑定到一起的

  • vue生命周期是指vue实例从创建到销毁的整个过程
  • 包括创建、运行、销毁三个阶段

生命周期函数图示

Vue.js 2.x 官方文档学习记录_第1张图片

创建阶段

  • 特点:每个实例中只执行一次,自动执行
  • beforeCreate 创建之前,data和methods尚未初始化
  • created 创建之后,data和methods已经创建完成,可以在这里进行数据初始化操作
  • beforeMount 容器挂载之前,容器数据还未得到渲染
  • mounted 容器挂载后,可以进行DOM操作
    可用户页面渲染完毕的dom初始化操作(例如给dom元素设置事件),或第三方插件与dom的结合应用

运行阶段

  • 特点:按需被调用 至少0次,最多不限制
  • beforeUpdate 根据最新数据重新解析渲染页面,此时vue数据是最新的,但页面数据还是之前的数据
  • updated 数据和页面更新完毕
    页面已经完成了更新,此时data数据和页面都是最新的

销毁阶段

  • 特点:每个实例一辈子只执行一次
  • beforeDestroy:将要销毁,处于销毁之前阶段,实例还正常可用,
  • 做的事情清空数据、清空事件、卸载模板、清空定时器
  • destroyed:销毁之后,实例已经不工作了

模板语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染 (render) 函数,使用可选的 JSX 语法。

指令系统

  • 概念

    指令 (Directives) 是带有 v- 前缀的html标签的特殊属性。指令属性值应该是一个单独的javascript表达式(V-for除外)。指令的工作是在其表达式的值发生变化时,将其产生的连带影响,响应式地作用于 DOM

插值表达式

使用“{{}}”表示,插值表达式可以用来绑定对象中的数据等

       
{{msg}}
var vm = new Vue({ el: "#app", data: { msg: "hello" } })

插值表达式绑定数据,会根据data中的数据变化而实时更新。如果想实现一次性更新可以给添加插值表达式的节点添加“v-once”指令,插入数据就不会在更新,但是该指令也会影响到该节点其他数据的绑定

v-html/v-text

v-text用于绑定普通文本、对象中的data数据
v-html用于绑定文本、数据或解析html代码
注:最好不要使用v-html/v-text

  • 插值表达式、v-html、v-text都能够进行简单的逻辑运算,绑定js单个表达式
动态参数

2.6.0及以上版本,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数

      
       ... 
      
       ... 
  • 动态参数值得约束
    动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
  • 动态参数表达式的约束
    动态参数表达式有一些语法约束
    • 某些字符,如空格和引号,放在 HTML attribute 名里是无效的
      变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式
    • 键名应该小写
      在 DOM 中使用模板时,避免使用大写字符来命名键名,浏览器会把 attribute 名全部强制转为小写

  ... 

  ... 
v-bind属性绑定
    <标签 v-bind:属性名称="数据信息(变量/常量)">
    // 或
    <标签 :属性名称="xxx">
普通属性绑定


data:{active:"active"}

绑定class和style
     
// 或
// 属性值需要通过引号圈选
   + 在一个数组元素中可以绑定多个或一个样式成员
   + 连字符“-”连接的属性可以通过“font-size”或 fontSize解决
   + v-bind绑定类型可以绑定数组或对象,通过data中的变量来控制标签的类名和样式,
   通过条件判断标签的class和style不同情况加载不同数据`

x

` **注**:绑定class和style可以通过绑定一个**返回对象的计算属性**来实现
        
data: { isActive: true, error: null }, computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' } } }
v-on事件绑定

事件类型:
鼠标事件:onclick ondblclick onmouseenter onmouseleave onmouseover onmousedown等等
键盘事件:onkeyup onkeydown onkeypress 等等
在vuejs中事件名称前都不加on,onclick-》改为click
v-on绑定的所有方法都在method中定义
再绑定事件中如果想访问原生DOM的事件,可以通过$event事件对象来访问

     <标签 v-on:click="事件处理函数名">标签>
     
     <标签 @click="事件处理函数名">标签>
事件传参

当绑定事件方法中有形参时:
1.如果绑定方法时传入实参,方法中形参就是实参
2.如果绑定方法时,方法带有(),形参为undefined
3.如果绑定方法时,未带有(),形参为事件对象
事件对象可以通过$event的方式传入方法
1.

,形参为事件对象
2.
,形参为undefined
3.
,形参为传入实参

  • 在事件处理函数中通过this来调用vm对象中的data数据和method中的方法
    **注:**v-bind和v-on都分别可以缩写为: “:” 和“@”
事件修饰符

以“.”开头的指令后缀,用来替代event.preventDefault()等事件对象的方法
包括“.stop.prevent.capture.self.once.passvie”

  • .stop 阻止事件冒泡传播
  • .prevent 阻止提交事件的默认行为
  • .capture 添加事件监听时启用事件捕获模式(即元素自身触发的事件先在此处理,然后才交由内部元素进行处理)
  • .self 只有是当前元素自身触发事件时,事件才会触发(即事件不是从内部元素冒泡上来的)
  • 新增
    • .once 事件将只会触发一次
      不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上
    • .passive 事件触发时的默认行为将会被立即触发,而不是等待事件完成
      注:
      1. .passive能够提升移动端的性能
      2. .passive会告诉浏览器不想阻止事件的默认行为
      3. .passive不能和.prevent一起使用,否则.prevent将会被忽略
     
     <a v-on:click.stop="doThis">a>
     <form v-on:submit.prevent="onSubmit">form>
     
     <a v-on:click.stop.prevent="doThat">a>
     
     <form v-on:submit.prevent>form>
     
     
     <div v-on:click.capture="doThis">...div>
     
     
     <div v-on:click.self="doThat">...div>
     <--新增-->
     
     <a v-on:click.once="doThis">a>
     
     
     
     <div v-on:scroll.passive="onScroll">...div>
    **注**:
    使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。
    因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
按键修饰符

作用:监听键盘事件时,替代判断按键的按键码
注:event.keyCode已被MND废弃。
现在使用event.key代替keyCode,key对应按键上的字符,keyCode对应按键的按键码。
现在新的浏览器已经不在支持keyCode,但旧的浏览器还支持keyCode
可以将KeyboardEvent.key暴露的任意有效键名转换为kebab-base(带-以小写开头格式)

   <--使用keyCode-->
   
   
   

vue提供常见按键别名:

  • .enter、.tab、.delete (捕获“删除”和“退格”键)、.esc、.space、.up、.down、.lef、t.right
    **另:**可以通过全局 config.keyCodes 对象自定义按键修饰符别名:
    // 可以使用 `v-on:keyup.f1`
     Vue.config.keyCodes.f1 = 112
系统修饰键

控制只有按下相应按键时才会触发对应鼠标或键盘的事件监听,包括.ctrl、.alt、.shift、.meta

注意:在 Mac 系统键盘上,meta 对应 command 键 (⌘)。
在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。
在 Sun 操作系统键盘上,meta 对应实心宝石键 (◆)。
在其他特定键盘上,尤其在 MIT 和 Lisp 机器的键盘、以及其后继产品,比如 Knight 键盘、space-cadet 键盘,meta 被标记为“META”。
在 Symbolics 键盘上,meta 被标记为“META”或者“Meta”。

     
     
     
     
Do something

请注意修饰键与常规按键不同,在和 keyup 事件一起用时,事件触发时修饰键必须处于按下状态。
换句话说,只有在按住 ctrl 的情况下释放其它按键,才能触发 keyup.ctrl。而单单释放 ctrl 也不会触发事件。
如果你想要这样的行为,请为 ctrl 换用 keyCode:keyup.17。

  • 新增
    • .exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
    
    
    
    
    
    
- 鼠标按钮修饰符(新增)
- 包括:.left.、right、.middle
这些修饰符会限制处理函数仅响应特定的鼠标按钮。
条件渲染

都是通过指令根据接收的boolean值将页面元素进行显示或隐藏,可以把一个 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 元素。

  • v-if/v-else-if/v-else
    • 使用 v-else 指令来表示 v-if 的“else 块”
    • v-else-if 充当 v-if 的“else-if 块”,可以连续使用
    • v-else / v-else-if 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面
    • 利用这三个指令可以实现多分支结构,在不同情况下显示或隐藏
    • 可以给不同模块添加key值,以保证不同模块相互独立
   <div v-if="type === 'A'"> A div>
   <div v-else-if="type === 'B'"> B div>
   <div v-else-if="type === 'C'"> C div>
   <div v-else> Not A/B/C div>
  • 用key管理可服用的元素
  • v-show
    区别:v-if进行的是元素的删除或添加,v-show只进行元素css样式的现实或隐藏,
    如果是频繁的切换使用v-show更合适
v-for列表渲染

对数组或对象进行遍历
**注:**遍历的同时会重复创建被遍历的html标签

    <标签 v-for="(遍历出来的小单元, 小单元下标) in 目标">
    <标签 v-for="遍历出来的小单元 in 目标">
  • key值

    v-for使用的同时必须使用“:key”,以便vue能跟踪每个节点的身份
    好处:从而重用和重新排序现有元素,需要为每项提供一个唯一 key 属性值 并且是唯一的,可以代表每个节点的有相同父元素的子元素必须有独特的 key, 值不要重复,否则会渲染错误

    <标签 v-for="(item, index) in 目标" :key="xxx">
    <标签 v-for="(value,key,index) in 目标" :key="xxx">

可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法


在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。

数组的更新检测

Vue 将被侦听的数组的变异方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法
+ 变异方法 (mutation method)
包括push()、pop()、shift()、unshift()、splice()、sort()、reverse()
+ 一些数组方法vue未包裹,为非变异方法filter()、concat()、slice()。非变异方法不会改变原始数组而是返回一个新的数组,可以使用新数组替换旧数组,vue中数据也会进行相应更新,使用新数组替换原来的数组

1. 利用索引和长度对数据的更改,vue不会检测到
vm.items[indexOfItem] = newValue 和 vm.items.length = newLength对数组修改都不会生效
2. 替换方法
Vue.set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)
vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(newLength)

对象的更新检测

注意事项

  • Vue 不能检测对象属性的添加或删除
    obj.key可访问到,obj.key = value 不会响应式更新。
  • 对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。
  • 动态添加属性可以通过Vue.set(object, propertyName, value)vm.$set(vm.userProfile, 'age', 27)方法向嵌套对象添加响应式属性
  • 向原对象添加多个属性,使用Object.assign()或_.extend(),应该按如下方法添加:
   vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: 'Vue Green' })
  • 也可以使用带有v-if或v-for的template渲染一段带有多个元素的内容
避免v-if和v-for一起使用
  • v-for优先级高于v-if
  • 如果为了有条件的遍历渲染内容,可以新建一个计算属性,将数据过滤筛选再遍历
  • 如果想根据不同情况决定是否遍历渲染,可以再遍历元素之外父元素上添加v-if
v-model双向绑定

v-model本质是语法糖
+ 通过v-model可以实现双向数据绑定,vue可以将数据渲染到页面上,当在页面上对数据进行更改时,更改的数据也会被感知到,并更新数据,重新渲染页面

1.v-model 只能 和 表单元素 配合使用(针对value属性起作用),具体为 input、select、textarea
2.v-model只能绑定vue的data成员,不能 绑定各种运算符的表达式 和 常量(例如 v-model="age+5"是错误的)

  <标签  v-model="xxx">
  • 修饰符
    • .lazy 可以把input事件触发输入框的值与数据进行更新,变为使用onchange事件进行事件更新
    • .number 自动将用户的输入值转为数值类型
    • .trim 能够过滤掉用户输入的首尾空白字符
  • 在组件上使用 v-model
    Vue 的组件系统允许创建具有完全自定义行为且可复用的输入组件。
    这些输入组件甚至可以和v-model 一起使用

计算属性和监听器

计算属性

  • 使用场景
    用于处理数据的反复使用的、复杂的js逻辑
    用于处理复杂数据的js复杂逻辑操作
  • 使用:
    1.在vm实例中添加computed属性
    2.在computed的属性中添加对相应data中数据的处理,并把处理结果返回
    3.在试图层绑定computed中的属性
    计算属性成员方法用到的data成员数据发生变化了,那么计算属性也会重新计算得出新值。即num1或num2的值发生变化后,result的值会自动更新
    

Original message: "{{ message }}"

Computed reversed message: "{{ reversedMessage }}"

var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } })

computed中的计算方法依赖于data中的数据,data中数据更新,依赖于computed属性的相应数据也会更新。
+ 计算属性的缓存
将对数据的处理定义为一个方法,在相应位置调用该方法,也能达到和计算属性一样的效果。
区别:
1.计算属性是基于它们的依赖关系进行缓存的。
只有相应关系更改时,才会重新求值,进行相应更新。也就是说,只要计算属性依赖的属性不更新,计算属性的方法就不必重新执行,而是立即返回上一次执行的结果。
2.如果是方法调用,每一次触发渲染,方法都要重新调用
3.方法调用不会有缓存,如果不希望有缓存,可以使用方法调用
4.如果有非常复杂的js逻辑处理,用计算属性可以提高性能,避免多次调用方法(将避免多次执行属性的getter)
+ 计算属性默认只有getter,但需要时也可以提价setter

    computed: {  
        fullName: {   
            // getter
            get: function () {     
                return this.firstName + ' ' + this.lastName 
            },   
            // setter 
            set: function (newValue) {
                var names = newValue.split(' ') 
                this.firstName = names[0]
                this.lastName = names[names.length - 1]
            }  
         }
     }
如果只有getter,computed中的属性,计算属性所依赖的data属性不会变化,设置setter后,computed中属性更新,computed中属性所依赖的data数据也会做相应的更新

监听器

应用场景:用于监听某个数据的变化后,执行某些操作
作用:通过watch选项提供了一个更通用的方法,来响应数据的变化

    export default {
      data(){
        return {
          xxx:'',
          yyy:''
        }
      },
      watch:{
        // 成员名称: 方法
        xxx:function(newval,oldval){},
        yyy:function(newval,oldval){}
      }
    }
watch成员名称 与 被监听的 data成员名称 是一致的,表示明确监听指定成员,
data有两个成员xxx/yyy,它们都受到watch监听,更新后会立即触发执行watch对应的成员方法newval:更新后的值
oldval:更新前的值
    密码:<input type="password" v-model="userpwd" ref="pwd" />
    export default {
      data(){
        return {
          userpwd:''
        }
      },
      watch:{
        userpwd:function(val){
          if(val.length>=8){
            this.$refs.pwd.style.color = 'blue'
          }else{
            this.$refs.pwd.style.color = 'red'
          }
        }
      }
    }

除了 watch 选项之外,还可以使用命令式的 vm.$watch的API

监听属性和计算属性的区别

  1. 计算属性成员方法用到的data成员数据发生变化了,那么计算属性也会重新计算得出新值。
  2. 计算属性是同时监听一个或多个data数据的变化,对data进行处理,得到一个新值
    3.watch成员名称与被监听的data成员名称是一致的,表示明确监听指定成员
    4.watch监听属性,对指定data成员进行监听,当数据发生变化会触发watch执行,侧重于在数据变化后做某些事情
    特点:watch:在数据变化时执行异步操作或开销比较大的操作,只有watch才可以实现
    computed:当一个数据是随着data中一个或多个数据变化而变化,使用computed比watch要方便和简洁,并且可以防止watch的滥用

过滤器

作用:用于对数据信息进行二次处理,本质上就是函数

  • 过滤器只可以用在两个地方:插值表达式:冒号 属性绑定表达式
  • 过滤器应该被添加在 JavaScript 表达式的尾部,由“|竖线”连接;

全局过滤器

给Vue通过filter方法声明的过滤器是全局的,该Vue的所有实例都可以使用

  Vue.filter("过滤器名称",function(origin){return origin处理结果}origin表示被处理的原始数据)
   // 使用
    {{dt|过滤器名称}}

私有过滤器

在Vue实例中,使用filters选项来添加当前对象的私有过滤器

  var vm = new Vue({
    el: '#app',
    data: {},
    filters: {
      // 如下是方法成员,是最新的ES6写法【推荐】
      过滤器的名称(origin){
        return 处理的结果
      }
    }
  })

全局 和 私有 过滤器如果同时存在,并且名称还相同, 则按照 就近原则 调用,级私有的优先
全局过滤器和私有过滤器都可以使用,但如果不能直接创建Vue对象只能创建私有过滤器
数据的处理可以使用多个过滤器
{{ dt | 过滤器 | 过滤器 | 过滤器 ... }}

传参

作用:通过传参,将结果形式根据业务进行调整

     {{ dt | 过滤器的名称(实参,实参...) }}
     Vue.filter('过滤器的名称', function(origin,形参,形参...){
     })

组件

  • 好处
    • 重复利用
    • 提高开发效率
    • 更专注于逻辑层面

组件注册

 Vue.compnent('组件名称',{组价配置成员})
+ 在组件的配置对象中,使用 `template` 属性指定当前组件要渲染的模板结构
+ template必须有且只能有一个根标签
+ template属性值是`多行`的,可以通过`反单引号`圈选编辑

组件使用

  1. 定义组件
    Vue.component("button-counter",{
        data: function () {
            return {
                count: 0
            }
        },
        template:`
            
` })
2. 使用组件
    <--在vue对象挂载的模板中使用组件-->
    
new Vue({ el: '#components-demo' })

组件配置成员

  • 组件是特殊的vue实例,与vue实例对象有相同的选项成员(el除外),data、method、computed、watch等以及生命钩子函数
  • 组件的data选项是一个函数,必须通过return返回一个字面量对象
    (因为只有这样每个复用的组件的实例都只维护自己当前的data)
  • 组件vue实例对象必须导出

私有组件

全局组件注册之后可以使用在任何vue实例中,而有些组件只需要在某个对象中,或只需要使用一次,所以需要将组件注册给特定的vue对象
+ 在vue对象中添加一个components属性,在components中注册需要使用的组件
+ 私有组件只能使用在当前vue对象

    components:{
        '组件的名称': { 组件的配置对象成员 }, 
        '组件的名称': { 组件的配置对象成员 }...
    }
    <--注册-->
    new Vue({
      components:{
        'my-login': {
          template: '
会员登录系统
'
} } }) <--使用--> <div id="app"><my-login></my-login></div>

组件使用v-model

原理: 本质上,v-model是v-bind以及v-on配合使用的语法糖
应用场景:一些表单控件value使用来另做他用的,和input不同,radio和checked用vaue来绑定选项的值,checked控制状态更改


// 就是相当于: 

自定义组件model选项
  • 不设置model选项:默认prop = value, event = input
  • 设置model prop设置绑定属性 event设置绑定事件
条件

为了让它正常工作,这个组件内的 必须:

  • 将其更改状态的属性绑定到prop上
  • 在其自定义事件类型被触发时,将新的值通过自定义的事件抛出
作用
  • 简化了单向数据流的操作,但提高了维护成本
  • 偏向于在表单自定义组建中使用该方法
// 自定义组件使用v-model

// 自定义组件中设置model选项
model: {
    prop: "text",
    event: "onEmitFromChild"
}
// 调用绑定事件
this.$emit("onEmitFormChild","124")

自定义事件

  • 事件名称不存在自动大小写转换,触发的事件名称需要完全匹配
  • 事件名不会被用足js变量名或property名,不能使用首字母大写和驼峰命名法
  • v-on会在DOM模板中自动转换为全小写,导致事件无法监听
    v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。
  • 使用 kebab-case(短横线分隔命名)命名

Vue单文件组件

定义:以.vue结尾,把一个组件的全部内容汇总到一个文件中
+ .vue文件分为三部分
+ template 结构
template用于设定组件要显示的内容,内部必须有一个根节点,可以理解为View部分
template是H5新标签,,只执行不在浏览器显示,要求有
+ script 行为
script导出一个模块,表现上是一个VueComponent组件,可以理解为VM部分,内部所有的成员与Vue实例基本一致
+ style 样式
设置组件结构的样式

vue单文件组件的使用

  • 定义组件
    <template>
      <div>
        <p>{{ msg }}</p>
      </div>
    </template>
    <script>
    导出
      export default {
        data(){
          return {msg}
        },
        methods:{},
        components:{},
        filters:{},
        created(){}
      }
    </script>
    <style lang="less">
        p {color:red;}
    </style>

在相应位置导入组件并注册使用

    导入并注册
    import XXX from './components/xxx.vue' 
    // Vue.component(名称, 组件)
    Vue.component('com-xxx',XXX)import XXX from './components/xxx.vue' 
    var vm = new Vue({
      components:{
        // 名称: 组件
        'xxx': XXX
      }
    })
    使用
    <div id="app">
      <com-xxx></com-xxx>
    </div>
+ scoped 给style添加scoped,保证只在当前组件起作用
+ scoped只能对平级组件进行区分
+ 嵌套组件最好不要使用选择器进行样式设定,scoped不能区分

组件嵌套

嵌套:将一个组件导入并注册为另一个组件的私有组件,并在父组件中使用子组件

组件通信

父子传值

父传子

步骤:
+ 在父组件结构中使用子组件的位置,通过自定义属性属性绑定data中数据,进行传值
+ 在子组件中通过props接收父组件传递过来的数据
+ 在子组件结构中引用传递过来的数据
+ 命名:DOM中自定义属性应该使用短横线分隔命名(post-title)props接收应该使用驼峰命名(‘postTitle’)
html对大小写并不敏感,浏览器会把所有大写字符解析为小写字符
字符串模板不存在这个限制

    传值
    

    
    export default {
        data(){ 
            return { myhouce: '2件茅草屋', mymoney:'5万外债' }
     }
     // 子组件在script中,接收并使用
     
    // 在子组件结构中使用
    


+ prop 父传子是单向下行绑定,父组件prop更新会流向子组件,传递过去的数据会相应更新,
+ 应该避免子组件中直接更改从父级prop传递过来的数据
+ 如果想在把传入数据作为一个本地叔叔使用最好定义一个变量接收传入数据
+ 如果传入数据需要进行处理在引用,可以定义一个计算属性

子传父
  • 在父组件中定义一个事件,同过事件绑定给子组件定义一个事件方法,向子组件传递一个事件方法
  • 在子组件中通过$emit()调用父组件传递过来的事件方法
  • 在父组件中定义事件的形参
  • 在子组件中调用事件方法时,传入实参
    // 2. 向子组件声明一个事件方法,事件的名称可以自定义
     <com-six-son @back="receive"></com-six-son>
     // back是事件名称
    // receive是事件的处理函数,定义在当前组件中

    // 1. 在父组件中定义一个事件
      methods:{
        // 接收"子级给父级"传递回来的数据的方法
        receive(k1,k2,k3){
          console.log(`${k1}-${k2}-${k3}`)
        }
      }
    4.使用传递过来的事件方法
    <button @click="huibao">按钮</button>
    3. 在子组件中在定义的方法中,通过$emit()调用事件方法并传参,调用的是自定义的名字,不是父组件定义处理函数的名字
          huibao(){
            // 调用本身组件的back方法
            // this.$emit(名字事件方法名称,参数,参数,参数..)
            // 参数:可以是各种类型数据(字符串、数组、对象等)
            this.$emit('back','ajax','jquery','h5')
            // $emit:只能是组件调用本身的 名字事件方法(普通方法不可以)
          }

兄弟传值

需要借助第三方vue对象(eventBus)
步骤:

    1. 定义模块car.js
    import Vue from 'vue'
    export default new Vue() 
  • 2.在两个组件中都导入car.js模块
import Car from './car.js'
  • 3.在要接收数据的组件A中通过$on给car对象定义方法并设置形参

请在生命周期函数created中给Car声明事件方法,这样组件被使用的时候事件方法一并就初始化好了

  • 4.在传递数据的组件B中,让car对象通过$emit()调用传递数据的事件并传参
   export default {
      created(){
      // car.$on('事件名称', (形参,形参,形参...) => {事件处理过程 }) 
        Car.$on('callback', (arg1,arg2)=>{
          console.log(arg1,arg2)
        })
      }
    }
   <button @click="callback">发布命令button>
   <script>
    export default {
      methods:{
        send(){
          Car.$emit('callback', '1000元', '31号')
        }
      }
    }
  script>

通过button按钮点击触发传递数据的实现

    1. 将A、B组件引入并注册给根组件
  • 6.在模板中使用两个组件

组件中的this指向vue实例对象,当前组件

其他访问个别组件数据的方法

  • r o o t 可以访问根组件的数据( d a t a , m e t h o d s , c o m p u t e d 等),一些公共数据和方法可以放在根组件上通过 root可以访问根组件的数据(data,methods,computed等),一些公共数据和方法可以放在根组件上通过 root可以访问根组件的数据(datamethodscomputed等),一些公共数据和方法可以放在根组件上通过root获取数据
  • $root只适用于少量组件项目,一般中大型项目用Vuex更好
  • $parent可以用来访问到父级的数据

插槽

注:在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了废弃的 slot 和 slot-scope 语法。
1. 父组件中引用子组件位置标签之间添加要插入的内容
2. 在子组件中使用标签定义填充内容的填充位置,slot就是插槽
3. 插槽填充内容可以是文本、元素、组件
插槽优点:
1. 比较灵活,根据不同需要定义不同位置
2. 提高开发效率,避免定义多个组件

  • 父组件引用子组件位置
    <com-son>
       <span>今天是周二span>
       <span>天气很好span>
    com-son>
  • 子组件模板
    <template>
       <div id="son">
          <p>我是Son子组件p>
          
          <p id="keng1"><slot>slot>p>
          <p id="keng2"><slot>slot>p>
          <p id="keng3"><slot>slot>p>
        div>
    template>
  • 填充在子组件标签之间未被匹配的内容,都会填充到所有子组件模板的匿名插槽中
  • 如果子组件模板中未包含slot元素,填充内容将会被抛弃

后备(默认)内容和作用域

  • 在slot标签之间可以提供默认内容,如果slot未被填充,slot标签中的默认内容会显示在slot标签位置
  • 父组件提供内容对默认内容有覆盖作用
// 当不为子组件slot标签提供内容时,slot标签位置显示默认内容
<button type="submit"><slot>Submitslot>button>
  • 父级模板只能访问父级的数据,子级模板只能访问子级数据,在子组件引用位置不能访问子组件数据,设置的插槽内容中也不能访问(父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
具命插槽
  1. slot标签有一个特殊的属性name可以用来定义具名的插槽
  2. 一个不带name会带有隐含的name—“default”。
  3. 在向具名插槽提供内容的时候,我们可以在一个