美文网首页
Vue组件深入

Vue组件深入

作者: MajorDong | 来源:发表于2020-01-08 17:19 被阅读0次

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动态赋值

<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post>

<!-- 动态赋予一个复杂表达式的值 -->
<blog-post
  v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>
  1. 传入一个数字
  2. 传入一个布尔值
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>
  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: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

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

<base-checkbox v-model="lovingVue"></base-checkbox>

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

.sync修饰符

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

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

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

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

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

<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>
//doc.title = newTitle 
1.当updata:title事件被触发时,将newTitle通过自定义的updata:title事件抛出
2. 在父组件上监听并绑定本地数据,实现双向绑定

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

<text-document v-bind:title.sync="doc.title"></text-document>
//子组件
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的<input>有value属性 所以为了父到子通信

举个例子

父->子

父自定义组件的data->

父的this.msg ->

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

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

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

子的JavaScript<input>

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

子->父

子组件的JavaScript<input> ->

子组件输入改变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事件,在父组件上监听input事件

插槽slot

一条规则

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

编译作用域

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
  <!--
  这里的 `url` 会是 undefined,因为 "/profile" 是
  _传递给_ <navigation-link> 的而不是
  在 <navigation-link> 组件*内部*定义的。
  -->
</navigation-link>

后备内容

<button type="submit">
  <slot>Submit</slot>
</button>

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

具名插槽slot

新语法v-slot或#

v-slot:default

v-slot:name

作用域插槽slot

V-slot:name = "slotProps"

动态组件&异步组件

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

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

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

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

处理边界情况

访问元素&组件

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

依赖注入

provide inject

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

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

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

程序化的事件侦听器

组件之间的循环应用

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

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

相关文章

网友评论

      本文标题:Vue组件深入

      本文链接:https://www.haomeiwen.com/subject/kvmsactx.html