美文网首页
Vue(篇幅二)

Vue(篇幅二)

作者: HW_____T | 来源:发表于2017-09-26 22:50 被阅读0次

    关于如何学习Vue,Vue的缔造者尤雨溪前辈曾经在知乎发表过一篇新手向:Vue 2.0 的建议学习顺序
    关于Vue其他知识介绍:篇幅一

    5. 组件
    1. 创建(注册)组件
    // 注册(全局注册)
    Vue.component('my-component', {
      template: '<div>A custom component!</div>'
    })
    

    组件在注册之后,便可以在父实例的模块中以自定义元素 <my-component></my-component> 的形式使用。要确保在初始化根实例之前注册了组件:

    <div id="example">
      <my-component></my-component>
    </div>
    //这里注册
    // 创建根实例
    new Vue({
      el: '#example'
    })
    
    1. data
      通过Vue构造器创建的组件中,data属性必须是函数。
    Vue.component('my-app',{
     template: '<span>{{message}}</span>',
    data: function(){
      return {
        message: 'hello'
      }
    }
    })
    
    1. Props
      子组件通过显式地用props选项声明它期待获得的数据。
    2. 单向数据流
      prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。
      为什么我们会有修改 prop 中数据的冲动呢?通常是这两种原因:
      (1)prop 作为初始值传入后,子组件想把它当作局部数据来用;
      (2)prop 作为初始值传入,由子组件处理成其它数据输出。
      对这两种原因,正确的应对方式是:
      定义一个局部变量,并用 prop 的值初始化它:
    props: ['initialCounter'],
    data: function () {
      return { counter: this.initialCounter }
    }
    

    定义一个计算属性,处理 prop 的值并返回。

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
    
    1. Prop验证
      组件传入的props可以进行数据验证。要指定验证规格,需要用对象的形式,而不能用字符串数组。如:
    Vue.component('my-app',{
      props: {
        propA: Number,//基本类型,null表示任何类型都行
        propB: [String,Number],//多种类型
        propC: {
          type: String,
          required: true //必须传,且时字符串
        },
        propD: {
          type: Number,
          default: 100  // 数字,有默认值
        },
        propE: {
          type: Object,
          default: function () {
            return { message: 'hello' }
          } // 数组/对象的默认值应当由一个工厂函数返回
        }, 
        propF: {
          validator: function (value) {
            return value > 10  // 自定义验证函数
          }
        }
      }
    })
    

    注意:props会在组件实例创建之前进行校验,所以在 defaultvalidator 函数里,诸如datacomputedmethods 等实例属性还无法使用。

    1. 自定义事件
      子组件通过自定义事件跟父组件通信。
      5.1 使用v-on绑定自定义事件
      每个Vue实例都实现了事件接口,即:
    • 使用 $on(eventName) 监听事件
    • 使用 $emit(eventName) 触发事件
      另外,父组件可以在使用子组件的地方直接用v-on来监听子组件触发的事件。
      注意:不能用 $on 侦听子组件释放的事件,而必须在模板里直接用 v-on 绑定。例如:
    <template>
    <div id = "app">
       {{ count }}
      <child v-on:add="addcount"></child>
    </div>
    </template>
    Vue.component('child',{
      template: '<button @click="increment">父组件count +1={{number}}</button>',
      data: function(){
        return {
          number : 0
        },
        method : {
          increment: function(){
            this.number++
            $.emit(add)
          }
        }
      }
    })
    
    new Vue({
      el: '#app',
      data: {
        count  : 0
      },
      methods: {
        addcount: function(){
          this.count++
        }
      }
    })
    

    以上代码表示,点击子组件按钮时候,会触发父组件的addcount() 事件
    5.2 .sync修饰符
    .sync作为一个编译语法糖存在,他会被扩展为一个自动更新父组件属性的v-on侦听器,如:
    <comp :foo.sync="bar"></comp>
    扩展为:
    <comp :foo="bar" @update:foo="val => var =val"></comp>
    当组件需要需要更新foo的值时,它需要显示地触发一个更新事件:
    this.$emit('update:foo',newValue)
    5.3 非父子组件通信
    有时候两个组件也需要通信(非父子关系),简单的场景下,可以使用一个空的Vue实例作为中央事件总线:
    var bus = new Vue()
    bus.$emit('id-selected',1) //触发组件A中的事件
    bus.$on('id-selected',function(id){})//在组件B创建的钩子中监听事件
    注意:复杂情况下,应该考虑专门的状态管理模式

    1. 使用插槽分发内容
      为了让组件可以结合,我们需要一种方式来混合组租间的内容与子组件自己的模板,这个过程被称为内容分发,Vue使用<slot>作为原始内容的插槽。如下:
    //app-layout 组件模板如下
    <div class="container">
      <header>
        <slot name="header"></slot> //具名插槽
      </header>
      <main>
        <slot></slot> //默认插槽
      </main>
      <footer>
        <slot name="footer"></slot>
      </footer>
    </div>
    
    //父组件模板:
    <app-layout>
      <h1 slot="header">这里可能是一个页面标题</h1>
      <p>主要内容的一个段落。</p>
      <p>另一个主要段落。</p>
      <p slot="footer">这里有一些联系信息</p>
    </app-layout>
    
    渲染结果为:
    <div class="container">
      <header>
        <h1>这里可能是一个页面标题</h1>
      </header>
      <main>
        <p>主要内容的一个段落。</p>
        <p>另一个主要段落。</p>
      </main>
      <footer>
        <p>这里有一些联系信息</p>
      </footer>
    </div>
    

    6.1 编译作用域
    分发内容实在父作用域内编译。
    6.2 作用域插槽
    作用域插槽是一种特殊类型的插槽,用作一个替换已渲染元素的 (能被传递数据的) 可重用模板。
    在子组件中,只需将数据传递到插槽,就像你将 props 传递给组件一样:

    <div class="child">
      <slot text="hello from child"></slot>
    </div>
    

    在父级中,具有特殊属性 scope 的 <template> 元素必须存在,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 props 对象:

    <div class="parent">
      <child>
        <template scope="props">
          <span>hello from parent</span>
          <span>{{ props.text }}</span>
        </template>
      </child>
    </div>
    

    如果我们渲染以上结果,得到的输出会是:

    <div class="parent">
      <div class="child">
        <span>hello from parent</span>
        <span>hello from child</span>
      </div>
    </div>
    

    作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项:

    <my-awesome-list :items="items">
      <!-- 作用域插槽也可以是具名的 -->
      <template slot="item" scope="props">
        <li class="my-fancy-item">{{ props.text }}</li>
      </template>
    </my-awesome-list>
    

    列表组件的模板:

    <ul>
      <slot name="item"
        v-for="item in items"
        :text="item.text">
        <!-- 这里写入备用内容 -->
      </slot>
    </ul>
    
    1. 子组件索引
      有时候需要在js中直接访问子组件,为此可以使用ref为子组件制定一个索引 ID,如下:
    <div id="parent">
      <user-profile ref="profile"></user-profile>
    </div>
    var parent = new Vue({ el: '#parent' })
    // 访问子组件
    var child = parent.$refs.profile
    

    注意:$refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案——应当避免在模板或计算属性中使用 $refs

    相关文章

      网友评论

          本文标题:Vue(篇幅二)

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