美文网首页Vue
第4章 深入理解Vue组件

第4章 深入理解Vue组件

作者: 读书的鱼 | 来源:发表于2019-05-21 11:49 被阅读71次
4-1 使用组件细节点

1.is的使用
当我们写循环组件的时候,经常给
table中的tr
select中的option
ul中的li或者ol中的li
等等定义组件的时候,我们经常用is来定义组件的名称,为了让浏览器成功的渲染正确的dom结构

<div id="root">
    <table>
        <tbody>
        <tr is="row"></tr>
        <tr is="row"></tr>
        <tr is="row"></tr>
        </tbody>
    </table>
    <select name="" id="">
        <option is="selectOption"></option>
        <option is="selectOption"></option>
        <option is="selectOption"></option>
    </select>
    <ul>
        <li is="ulLi"></li>
        <li is="ulLi"></li>
        <li is="ulLi"></li>
    </ul>
</div>
<script>
    Vue.component('row', {
        template: '<tr><td>this is a row</td></tr>'
    });
    Vue.component('selectOption',{
        template: '<option>this is option</option>'
    });
    Vue.component('ulLi',{
        template: '<li>this is li</li>'
    });
    var app = new Vue({
        el: '#root',
        data: {},
    })
</script>

2.在子组件定义data的时候,必须是一个函数,而不能是一个对象,返回一个对象是为了每个子组件都能拥有一个独立的数据存储。这样子组件之间的数据不会互相影响
而在根组件中,data可以是一个对象。

<div id="root">
    <table>
        <tbody>
        <tr is="row"></tr>
        <tr is="row"></tr>
        <tr is="row"></tr>
        </tbody>
    </table>
</div>
<script>
    Vue.component('row', {
        data: function () {//返回的是一个函数
            return {
                content: 'this is row'
            }
        },
        template: '<tr><td>{{content}}</td></tr>'
    });
    var app = new Vue({
        el: '#root',
        data: {}
    })
</script>

3.有时候我们在开发过程中,因为一些业务的需求,少不了对dom的操作,那么我们就可以借助ref来实现

//实例一
<div id="root">
    <div ref="hello" @click="handleClick">hello world</div>
</div>
<script>
    var app = new Vue({
        el: '#root',
        data: {},
        methods: {
            handleClick: function () {
                console.log(this.$refs.hello.innerHTML);//通过refs属性 获取当前节点的文本
            }
        }
    });
</script>


//案例二 counter求和
<div id="root">
    <counter ref="one" @change="handleChange"></counter>
    <counter ref="two" @change="handleChange"></counter>
    <div>{{total}}</div>
</div>
<script>
    Vue.component('counter', {
        data: function () {
            return {
                number: 0
            }
        },
        template: '<div @click="handleClick">{{number}}</div>',
        methods: {
            handleClick: function () {
                this.number++;
                this.$emit('change');//触发一个监听器
            }
        }
    });
    var app = new Vue({
        el: '#root',
        data: {
            total: 0
        },
        methods: {
            handleChange: function () {
                this.total = this.$refs.one.number + this.$refs.two.number //通过refs 来回去组件的值
            }
        }
    });
</script>
4-2父子组件之间的数据传递

父组件向子组件传值:是通过属性的方式
子组件向父组件传值:可以通过$emit来触发一个事件

vue数据传递遵循的是单向数据流,
所以在下面的案例中我们并没有对content数据直接进行数据的累加,而是把content数据赋值给了number,对number进行数据的累加操作。

<div id="root">
    <counter :content="1" @inc="handleInc"></counter><!--父组件通过属性向子组件传值-->
    <counter :content="3" @inc="handleInc"></counter>
    <div>{{total}}</div>
</div>
<script>
    Vue.component('counter', {
        props: ['content'],
        data: function () {
            return {
                number: this.content //遵循单向数据流
            }
        },
        template: '<div @click="handleClick">{{number}}</div>',
        methods: {
            handleClick: function () {
                this.number += 2;
                //子组件通过方法向父组件传值
                this.$emit('inc', 2);
            }
        }
    });
    var app = new Vue({
        el: '#root',
        data: {
            total: 4
        },
        methods: {
            handleInc: function (step) {
                this.total += step
            }
        }
    })
</script>
4-3组件参数校验和非props特性

1.组件的的参数校验

<div id="root">
    <child content="hello"></child>
</div>
<script>
    Vue.component('child', {
        props: {
            content: {
                type: String,
                required: true,
                default: 'default Value',
                validator: function (value) {
                    return (value.length > 5)
                }
            }
        },
        template: '<div>{{content}}</div>'
    });
    var app = new Vue({
        el: '#root',
    })
</script>

2.props特性和非props特性的对比
props特性:
父组件传递属性,子组件要接受该属性
props属性不会显示在dom的标签之中
非props特性:
父组件传递属性,子组件没有去接受,而是直接调用
props属性会显示在dom的标签之中

4-4给组件绑定原生事件

通过.native属性来绑定原生事件

<div id="root">
    <child @click.native="handleClick"></child>
</div>
<script>
    Vue.component('child', {
        template: '<div>child</div>'
    })
    var app = new Vue({
        el: '#root',
        methods: {
            handleClick: function () {
                console.log('click');
            }
        }
    })
</script>
4-5 非父子组件间的传值
非父子组件间的传值

1.通过vuex
2.通过发布订阅模式(Bus/总线/发布订阅模式/观察者模式/)

<div id="root">
    <child content="sunny"></child>
    <child content="fan"></child>
</div>
<script>
    Vue.prototype.bus = new Vue();//定义bus
    Vue.component('child', {
        data: function () {
            return {
                newContent: this.content //保证单向数据流
            }
        },
        props: {
            content: String
        },
        template: '<div @click="handleClick">{{newContent}}</div>',
        methods: {
            handleClick: function () {
                this.bus.$emit('change', this.newContent); //在bus上发布一个事件,并且传值
            }
        },
        mounted: function () {//通过这个钩子,来监听change的变化,通过回调拿到相对应的的值
            var that = this;
            this.bus.$on('change', function (msg) {
                console.log(msg)
                that.newContent = msg//this 指向发生变更,所以上面要从新获取一下this的指向
            })
        }
    });
    var app = new Vue({
        el: '#root'
    })

4-6 在vue中使用插槽

插槽只能有一个
而剧名插槽可以有多个

  <div id="root">
    <body-content>
      <p slot="header">this is header</p>
      <p slot="footer">this is footer</p>
    </body-content>
  </div>
  <script>
    Vue.component('body-content',{
      template:
      `<div>
        <slot name="header">default header</slot> //设置默认值
        <p>this is content</p>
        <slot name="footer"></slot>
      </div>`
    })
    var app = new Vue({
      el:'#root'
    })
  </script>
4-7作用域插槽

父组件调用子组件的时候,给子组件传了一个插槽,这个插槽是一个作用域的插槽,这个插槽必须是一个<template slot-scope="props">{{props.item}}</template>
那什么时候使用作用插槽呢?
1.当子组件做循环
2.或者当子组件的dom结构由外部传递进来,或者有外部决定的时候

<div id="root">
    <child>
      <template slot-scope="props">
        <li>{{props.item}}</li>
      </template>
    </child>
  </div>
  <script>
    Vue.component('child', {
      data: function () {
        return {
          list: [1, 2, 3, 4]
        }
      },
      template: `<div>
        <ul>
          <slot v-for="item of list" :item=item></slot>
        </ul>
      </div>`
    })
    var app = new Vue({
      el: '#root'
    })
  </script>

4-8 动态组件和v-once 指令
<div id="root">
    <component :is="type"></component> <!--这就是动态组件-->
    <child-one v-if="type==='child-one'"></child-one>
    <child-two v-if="type==='child-two'"></child-two>
    <button @click="hanleBtnClick">change</button>
  </div>
  <script>
    Vue.component('child-one', {
      template: '<div v-once>child-one</div>'
    })

    Vue.component('child-two', {
      template: '<div v-once>child-two</div>'
    })

    var app = new Vue({
      el: '#root',
      data: {
        type: 'child-one'
      },
      methods: {
        hanleBtnClick: function () {
          this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
        }
      }
    })
  </script>

更多

上一篇:第3章 Vue 基础精讲
下一篇:第5章 Vue 表单
全篇文章:Vue学习总结
所有章节目录:Vue学习目录

相关文章

  • 深入理解vue组件

    一、使用组件的细节点当使用table、select等标签时,组件标签化可能会有bug,此时应该使用 is 接受组件...

  • 第4章 深入理解Vue组件

    4-1 使用组件细节点 1.is的使用当我们写循环组件的时候,经常给table中的trselect中的option...

  • vue起步(4)之组件

    vue组件:组件主要是扩展了HTML元素,使dom元素更加灵活,慢慢深入会发现组件是vue构建项目所必备的。全局组件:

  • 「vue 组件通信一」组件间通信、数据传递(父子组件,同级组件)

    总结一下对vue组件通信的理解和使用。 一、组件目录结构 父组件:app.vue 子组件:page1.vue 子组...

  • Vue组件深入

    vue组件深入 组件注册 全局注册 局部注册 prop prop的大小写 camelCase vs Kebab-c...

  • 深入理解vue.js——组件

    熟悉vue或者研究过vue源码的同学都知道,组件是vue最重要的部分之一,而写组件由两种常见的方式: templa...

  • vue学习笔记

    Vue组件 我们用以下几个步骤来理解组件的创建和注册: Vue.extend()是Vue构造器的扩展,调用Vue....

  • Vue学习笔记-插槽

    深入理解vue中的slot与slot-scope 插槽,也就是slot,是组件的一块HTML模板。 对于任何一个组...

  • Vue组件(compoent)

    自定义组件有两种方式1.全局组件,2.局部组件 全局组件:我们可以这样理解,一个vue组件就是一个vue实例 组件...

  • 深入理解Vue 组件之间传值

    在 Vue 中,可以使用props向子组件传递数据。 子组件部分: 这是 header.vue 的 HTML 部分...

网友评论

    本文标题:第4章 深入理解Vue组件

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