美文网首页
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