Vue入门3——组件使用的细节点

116 阅读4分钟

组件使用的细节点

用js标签解决标签渲染中的小Bug

1. tbody、ol、ul、select标签内如何放置自定义组件?

  • tbody里只能写tr,如果想要放入一个自己的自定义组件呢?该如何实现 image.png
  • 同理,ol ul里只能写liselect里只能写option,该如何实现自定义组件呢?都可以按照如上方式用属性is

2. 子组件的data

在根组件里把data定义成一个对象不会有问题,但是在子组件里定义data,后面的值必须是函数,且返回一个对象,包含你所要的数据。

  • 子组件不会像根组件一样只被调用一次,每一个子组件的数据都不应该跟其他组件数据产生冲突,这样可以让每个子组件都拥有自己独立的数据
    data: {
        return {
            number: 0;
        }
    }
    

3 通过ref引用来获取DOM节点

  • $ref指的是JS中所有的引用。

  • $ref.hello指找到一个叫做hello的引用。

    image.png

以计数器为案例,如何计算并显示两个计数器的和?

  • 子组件值改变→触发一个事件告诉父组件 image.png image.png

Vue中父子组件之间传值

  • 父组件通过属性count的形式向子组件counter传值,子组件用props接收。子组件通过事件触发的形式向父组件传值。

  • 单向数据流:父组件可以向子组件传递数据,但是子组件不能修改,如果非要修改,就拷贝一个副本修改这个副本。

    image.png image.png image.png

组件中的参数校验与非Props特性

参数校验

父组件向子组件传递了内容,子组件有权对传入的数据进行约束,将原本值的数组形式props:['content']改为对象的形式props:{content:String}
当然也可以约束两个数据类型:

props: {
   content: [String, Number]
}

  • required=true表示参数必定要传入,假设不传入会默认为default值。
  • validator约束传入属性数据的长度。 image.png image.png

Props特性

  • 父组件通过属性传递数据进来,子组件就能读取显示出来。
  • 属性传递的内容是不会在DOM标签上显示出来的。

非Props特性

  • 父组件向子组件传递一个属性,子组件并没有去接收。
  • 非Props属性会展示在DOM标签的html属性里。

给组件绑定原生事件

  • 监听内部组件向外触发的自定义事件。
  • 监听原生事件nativeimage.png

非父子组件之间的传值

光靠Vue是不行的

  • Vuex
  • 总线机制 发布订阅模式 观察者模式 Bus 1636597591(1).jpg

兄弟节点,点击Dell的时候,下边的Lee也会变成Dell,相反如是。

  • Vue 原型挂一个 Bus 的属性指向Vue实例,那么每个新创建的 Vue 实例都会有一个Bus 属性。
  • this 作用域发生变化,先保存一下原来的 this。
  • 注意子组件不能修改父组件传递的值,要拷贝一个副本。
<div id="root">
    <child content="Dell"><child>
    <child content="Lee"><child>
</div>
<script>
    Vue.prototype.bus=new Vue()
    Vue.component('child',{
        data: function() {
            return {
                selfContent: this.content
            }
        }
    }, 
    props: {
        content: String
    },
    template: `<div @click="handleClick">{{selfContent}}</div>`
    methods: {
        handleClick: function() {
            this.bus.$emit('change',this.selfContent)
        }
    },
    mounted: function() {
        var this_ = this
        this.bus.$on('change', function(msg) {
            this_.content = msg
        })
    })
    var vm = new Vue({
        el:"#root"
    })
</script>

在Vue中使用插槽

子组件除了展示p标签外,还要展示父组件传递过来的内容。 通过content传值并展示,必须在子组件模板里加一个div标签,且模板里只能有一个根标签,因此还要包裹。再加上如果传递的内容很多,代码太冗余。

<body>
    <div id="root">
        <child content='<p>Dell</p>'></child>
    </div>
    <script>
        Vue.component('child', {
            props:['content'],
            template:`<div>
                        <p>hello</p>
                        <div v-html="this.content"></div>
                      </div>`
        })
        var vm = new Vue({
            el:"#root"
        })
    </script>
</body>

如何优雅地传递?——插槽

image.png

<body>
    <div id="root">
        <child>
            <h1>Dell</h1>
        </child>
    </div>
    <script>
        Vue.component('child', {
            template:`<div>
                        <p>hello</p>
                        <slot>默认内容</slot>
                      </div>`
        })
        var vm = new Vue({
            el:"#root"
        })
    </script>
</body>A

当外部没有传入的时候,slot显示默认值。

具名插槽

  • 需求:body-content组件里,内容区域是自己的,header和footer是由外部传递进来的。 1636600042.png

作用域插槽

  • 子组件实现循环展示列表的功能。让外部决定如何循环。当子组件用slot的时候,会向slot里传递一个item数据。

  • 父组件调用子组件的时候,给子组件传递了一个作用域插槽,作用域插槽是<template></template>形式的,且插槽要声明从子组件接收的数据都放在哪(props,slot-props="props"),且要告诉子组件模板信息。 image.png image.png

动态组件与v-once指令

  • button 点击时,两个child做一个toggle,每次切换都要创建一个组件、销毁一个组件,代码写起来比较麻烦。 image.png {6EBB8326-49F4-4636-8FAA-8FD652B83C02}.png.jpg

动态组件怎么编写?

  • component会根据is里面数据的变化,自动加载不同的组件 image.png

v-once

  • 上述方法是耗费性能的,如果加了v-once指令,就是把你创建的组件放到了内存里,再次切换到它的时候,直接从内存中读取就可以了。有效提高了一些静态内容的展示效率。 image.png