Vue组件深入

vue组件深入

组件注册

  1. 全局注册
  2. 局部注册

prop

prop的大小写

camelCase vs Kebab-case

kebab-case

prop类型

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

传静态或动态prop

prop可以通过v-bind动态赋值






  1. 传入一个数字
  2. 传入一个布尔值


  1. 传入一个数组
  2. 传入一个对象

v-bind告诉JavaScript表达式是动态的而不是一个字符串

prop单向数据流

  1. 在组件中使用props来从父亲组件接受数据,在props中定义的属性,都可以在组件中直接使用
  2. props来自父级,而组件中的data return的数据就是组件自己的数据,两种情况作用域就是组件本身,可以直接在template,computed,methods中直接使用
  3. 使用v-bind动态绑定来自父组件的值。input

单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。

两种常见的prop情形

一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域 下可以随意使用和修改。这种情况可以在组件 data 内再声明一个数据,引用父组件 的 prop

步骤一:注册组件

步骤二:将父组件的数据传递进来,并在子组件中用props接收 步骤三:将传递进来的数据通过初始值保存起来

props: ['initialCounter'],
data: function () {
 return {
   counter: this.initialCounter
 }
}

另一种情况就是 prop 作为需要被转变的原始值传入。这种情况用计算属性就可以了

步骤一:注册组件

步骤二:将父组件的数据传递进来,并在子组件中用props接收 步骤三:将传递进来的数据通过计算属性进行重新计算

props: ['size'],
computed: {
 normalizedSize: function () {
   return this.size.trim().toLowerCase()
 }
}

自定义事件

v-model

一个组件上的v-model会利用名为value的prop和名为input的事件,但是像但是像单选框、复选框等类型的输入形控件可能会将value特性用于不同的目的

model选项可以用来避免这样的冲突

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    
  `
})

现在在这个组件上使用v-model的时候


这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 `` 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的属性将会被更新。

.sync修饰符

对prop进行双向绑定,但真正的双向绑定会带来维护上的问题,因为子组件可以修改父组件,但在父组件和子组件都没有明显的改动来源

推荐updata:myPropName的模式取而代之。

在一个包含title prop的假设组件中,我们可以用以下方法表达对其复新值的意图

this.$emit('updata:title',newTitle)

然后父组件可以监听那个事件并根据需要更新一个本地的数据属性。


//doc.title = newTitle 
1.当updata:title事件被触发时,将newTitle通过自定义的updata:title事件抛出
2. 在父组件上监听并绑定本地数据,实现双向绑定

为了方便起见,给这种模式提供一个缩写.sync修饰符


//子组件
this.$emit('updata:title',newTitle)

关于prop的双向绑定

举个例子就以title改变为例

父 ->子

父的本地数据 data下的doc.title ->

父组件v-bind:title="doc.title"->

子组件的props title:{type:String}

子组件使用props可写在子组件data中

子 -> 父

子组件 this.$emit('updata:title',newTitle) ->

父组件 v-on:update:title="doc.title = $event" ->

父组件 v-bind:title="doc.title" ->

父组件 data doc.title 改变

prop双向绑定相比v-model更灵活,总结父子组件上的v-bind时双向绑定的数据接口,父到子通过props ,子到父通过自定义事件。

关于在组件上使用v-model的双向绑定

因为原生的JavaScript的有value属性 所以为了父到子通信

举个例子

父->子

父自定义组件的data->

父的this.msg ->

父组件v-bind:value= 'msg' ->

子组件的props value:{type:String}改变 ->

子组件v-bind:value = value(来自子props)>

子的JavaScript

因为原生的JavaScript的有value属性 所以为了父到子通信 父和子都要动态绑定value属性。

子->父

子组件的JavaScript ->

子组件输入改变v-bind:value->

子组件v-on:input:$emit('input' , $event.target.value) ->

父组件v-on:input(msg = $event) ->

父的this.msg ->

父的data ->

父的{{msg}}

因为原生的JavaScript的有input事件,所以为了子到父通信,子组件触发input事件时采用自定义input事件,在父组件上监听input事件

插槽slot

一条规则

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

编译作用域


  Clicking here will send you to: {{ url }}
  

后备内容


如果提供内容Submit就会被取而代之

具名插槽slot

新语法v-slot或#

v-slot:default

v-slot:name

作用域插槽slot

V-slot:name = "slotProps"

动态组件&异步组件

用is在多标签的界面来切换不同组件的时候,有时需要保持这些组件的状态,避免反复冲渲染导致的性能问题

让重新创建的动态组件能够在它们被第一次创建的时候缓存下来。为了解决这个问题,可以用个元素将其动态组件包裹起来。


  

里面的组件一定要有自己的名字

处理边界情况

访问元素&组件

  1. 访问根实例$root: 对于小型的有少量的组件应用来说是很方便,大型项目使用vuex来管理应用的状态
  2. 访问父组件实例$parent:用与简单直接的父子组件,当需要向任意更深层的组件提供上下文信息使,使用依赖注入
  3. 访问子组件实例或子元素$refs:在组件渲染完成后生效。

依赖注入

provide inject

  • provide选项,允许我们指定我们想要提供给后代组件的数据方法。
  • inject选项,在后代组件里,使用inject选项来接受指定的想要添加在这个实例上的属性

可以;把依赖注入看作一部分"大范围有效的prop"一样

  • 祖先组件不需要知道哪些后代组件使用它提供的属性
  • 后代组件不需要知道被注入的属性来自哪里

程序化的事件侦听器

组件之间的循环应用

两个相互依赖的组件A、B ,需要给系统一个点,告诉系统A是需要B的,但我们不需要向解析B

  1. 在生命周期钩子beforeCreate时注册
  2. 在本地注册组件的时候,使用webpack的一步import

你可能感兴趣的:(Vue组件深入)