Vue组件基础大全

组件基础

组件介绍

  • 模块化就是将系统功能分离成独立的功能部分的方法,一般指的是单个的某一种东西,例如js、css
  • 而组件化针对的是页面中的整个完整的功能模块划分,组件是一个html、css、js、image等外链资源,这些部分组成的一个聚合体
  • 优点:代码复用,便于维护
  • 划分组件的原则:复用率高的,独立性强的
  • 组件应该拥有的特性:可组合,可重用,可测试,可维护

Vue组件是可复用Vue 实例,且带有一个名字:例如 <button-counter>。我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:

<div id="app">
  <button-counter></button-counter>
</div>

组件的注册

全局组件注册
  • 全局组件注册代码
		//创建组件
 		const Hello=Vue.extend({
            template:`<h1>hello world</h1>`
        })
        // 全局注册
        Vue.component('hello',Hello)
  • 全局组件注册的组件可以在任意vue实例下使用
  <div id="app">
        <hello></hello>
    </div>

    <div id="app2">
        <hello></hello>
    </div>



    <script src="./base/vue.js"></script>
    <script>

 		 // 创建组件
        const Hello=Vue.extend({
            template:`<h1>hello world</h1>`
        })

        // 全局注册
        Vue.component('hello',Hello)

        new Vue({
            el:"#app",
        })

        new Vue({
            el:"#app2",
        })
    </script>
  • 注册成功并复用,会出现两个hello world
    在这里插入图片描述
局部组件注册
  • 局部组件注册代码
// // 创建组件
        const Hello=Vue.extend({
            template:`<h1>hello world</h1>`
        })

        new Vue({
            el:"#app",
            // 局部注册
            components:{
                hello:Hello
            }
        })
  • 局部组件注册的组件只能在当前注册的vue实例下使用
<div id="app">
        <hello></hello>
    </div>

    <div id="app2">
        <hello></hello>
    </div>

    <script src="./base/vue.js"></script>
    <script>
 // // 创建组件
        const Hello=Vue.extend({
            template:`<h1>hello world</h1>`
        })

        new Vue({
            el:"#app",
            // 局部注册
            components:{
                hello:Hello
            }
        })

        new Vue({
            el:"#app2",
        })

        new Vue({
            el:"#app"
        })
    </script>
  • 只会出现一个hello world ,并报错
    在这里插入图片描述

组件注册简写

全局组件注册简写
  • Vue.component('组件名',{template:''})
 Vue.component("hello",{
            template:`<h1>hello Vue</h1>`
        })
局部组件注册简写
  • components{hello:{template:""}}
   new Vue({
            el:"#app",
            components:{
                hello:{
                    template:`<h1>hello Vue</h1>`
                }
            }
        })

data必须是一个函数

一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

  • 简单案例
    • 注册一个组件,定义数据msg=1,当点击按钮时,msg=2,
  • 如果data方法不返回一个对象的话,当组件复用时,点击一个按钮,另一个按钮的数据也会改变
    因为如果data方法不返回对象浏览器会直接报错,所以我们这里用一个Vue实例来模拟这种情况
    在这里插入图片描述
 <div id="app">
        <button @click='change'>msg={{msg}}</button>
        <hr>
        <button @click='change'>msg={{msg}}</button>
    </div>

    <script src="./base/vue.js"></script>
    <script>

        // Vue实例
        new Vue({
            el:"#app",
            data:{
                msg:1
            },
             //点击按钮数据改变
             methods:{
                change(){
                    this.msg=2
                }
            }
        })
    </script>

在这里插入图片描述

  • 如果data方法返回一个对象的话,当组件复用时,点击一个按钮,每一个组件实例都拥有独立的data属性
	<div id="app">
        <!-- 组件复用 -->
        <hello></hello>
        <hr>
        <hello></hello>
    </div>
    <script src="./base/vue.js"></script>
    <script>

        // 注册全局组件
        Vue.component("hello",{
            // 模板
            template:"<button @click='change'>msg={{msg}}</button>",
            // data方法返回一个对象
            data(){
                return {
                    msg:1
                }
            },
            //点击按钮数据改变
            methods:{
                change(){
                    this.msg=2
                }
            }
        })
        // Vue实例
        new Vue({
            el:"#app"
        })
    </script>

在这里插入图片描述

template组件模板

  • 可以在body里创建template标签在组件里指定template
  • 模板内容必须有根元素
  • 必须用id作为标记
  • template标签不会被渲染在页面上
 <div id="app">
        <hello></hello>
    </div>

    <!-- 必须是id作为标记 -->
    <template id="hello">
          <!-- 必须有根元素 -->
        <div>
            <h1>这是h1标签</h1>
            <p>这是p标签</p>
        </div>
    </template>


    <script src="./base/vue.js"></script>
    <script>
        //注册全局组件
        Vue.component("hello", {
            template: "#hello"
        })

        new Vue({
            el: "#app",
        })
    </script>
  • 运行结果如下,且template标签不会被渲染在页面上
    在这里插入图片描述

注意浏览器规则,利用is放入组件

vue在解析模板的时候会根据某些html的规则,
例如,在table里只能放tr,td,th…,如果放入组件不会解析 这个时候我们可以放入tr使用is方式来标识这个tr其实是组件

  • 不使用is方式
    • 没有在tr标签中
	<div id="app">
        <table>
            <tbody>
                <tr>
                    <hello></hello>
                </tr>
            </tbody>
        </table>
    </div>
    <script src="./base/vue.js"></script>
    <script>
        Vue.component("hello", {
            template: "<p>这是一个组件</p>"
        })

        new Vue({
            el: "#app",
        })
    </script>

在这里插入图片描述

  • 使用is方式
	<div id="app">
        <table>
            <tbody>
                <tr is="hello"></tr>
            </tbody>
        </table>
    </div>
    <script src="./base/vue.js"></script>
    <script>
        //注册全局组件
        Vue.component("hello", {
            template: "<p>这是一个组件</p>"
        })

        new Vue({
            el: "#app",
        })
    </script>

在这里插入图片描述

动态组件(is切换)

在不同组件之间进行动态切换,可以通过Vue 的 component元素加一个特殊的 is attribute 来实现

  • 简单案例,点击按钮切换组件
	<div id="app">
		<!-- 添加点击事件  利用三目运算符  如果msg的值为my-a就切换成my-b 否则 切换为my-a -->
        <button @click="msg=msg==='my-a'?'my-b':'my-a'">切换a,b组件</button>
        <!--实现组件切换  msg是组件名称  component 不会渲染在页面上-->
        <component :is="msg"></component>
    </div>

    <script src="./base/vue.js"></script>
    <script>

        	new Vue({
            el: "#app",
            data:{
                msg:"my-a"
            },
            //两个组件
            components:{
                "my-a":{
                    template:"<h1>这是a组件</h1>"
                },
                "my-b":{
                    template:"<h1>这是b组件</h1>"
                },
            }
        })
    </script>

在这里插入图片描述
-component不会被渲染在页面上
在这里插入图片描述

组件嵌套

应用中划分的组件可能会很多,为了更好的实现代码复用,所以必然会存在组件的嵌套关系
组件设计初衷就是要配合使用的,最常见的就是形成父子组件的关系:组件 A 在它的模板中使用了组件 B。

 	<div id="app">
        <father></father>
    </div>
    <script src="./base/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                msg: "my-a"
            },
            components: {
                // 父组件
                father: {
                    // 在父组件中引用子组件
                    template: "<div>这是父亲组件<son></son></div>",
                    // 子组件
                    components: {
                        son: {
                            template: "<p>这是儿子组件</p>"
                        },
                    }
                },
            }
        })
    </script>

在这里插入图片描述

插槽

  • vue里提供了一种将父组件的内容和子组件的模板整合的方法:内容分发,通过slot插槽来实现
  • <slot></slot>
匿名插槽

在父组件中使用子组件的时候,在子组件标签内部写入内容。在子组件的模板中可以通过<slot></slot>来使用

	<div id="app">
        <hello>
            <div>联通卡</div>
            <div>移动卡</div>
        </hello>
    </div>
    <!-- 匿名插槽 -->
    <template id="hello">
        <div>
            <slot></slot>
        </div>
    </template>

    <script src="./base/vue.js"></script>
    <script>

        new Vue({
            el:"#app",
            components:{
                hello:{
                    template:"#hello"
                }
            }
        })

    </script>

在这里插入图片描述

  • 不管什么内容都被放在一个插槽中,如果有两个<slot></slot>,运行之后
	<template id="hello">
        <div>
            <slot></slot>
            <slot></slot>
        </div>
    </template>

在这里插入图片描述

具名插槽
  • 父组件在子组件标签内写的多个内容我们可以给其设置slot属性来命名,在子组件的模板通过通过使用带有name属性的slot标签来放置对应的slot。
  <div id="app">
        <hello>
            <div slot="a">联通卡</div>
            <div slot="b">移动卡</div>
        </hello>
    </div>
    
    <!-- 具名插槽 -->
    <template id="hello">
        <div>
            <slot name="a"></slot>
            <hr>
            <slot name="b"></slot>
        </div>
    </template>

    <script src="./base/vue.js"></script>
    <script>

        new Vue({
            el:"#app",
            components:{
                hello:{
                    template:"#hello"
                }
            }
        })

    </script>

在这里插入图片描述

  • 新版本2.6+支持v-slot方式
  • v-slot在使用时,需要在template标签内
  <div id="app">
        <hello>
        <!-- v-solt方式-->
            <template v-slot:a>
                <div>联通卡</div>
            </template>
            <template v-slot:b>
                <div>移动卡</div>
            </template>
        </hello>
    </div>
  
    <template id="hello">
        <div>
            <slot name="a" ></slot>
            <hr>
            <slot name="b" ></slot>
        </div>
    </template>
    
    <script src="./base/vue.js"></script>
    <script>

        new Vue({
            el:"#app",
            components:{
                hello:{
                    template:"#hello"
                }
            }
        })

    </script>

在这里插入图片描述

接收props的具名槽口

<slot name="b" :msgb="msg"></slot>
<template v-slot:b="info"></template>


    <div id="app">
        <hello>
            <template v-slot:a>
                <div>联通卡</div>
            </template>
            <!-- info 自己写的一个名字,可以随便起 -->
            <template v-slot:b="info">
                <div>移动卡 {{info.msgb}}</div>
            </template>
        </hello>
    </div>

    <template id="hello">
        <div>
            <slot name="a"></slot>
            <hr>
            <slot name="b" :msgb="msg"></slot>
        </div>
    </template>
    <script src="./base/vue.js"></script>
    <script>

        Vue.component("hello", {
            template: "#hello",
            data() {
                return {
                    msg: "你好"
                }
            }
        })
        new Vue({
            el:"#app"
        })

    </script>

在这里插入图片描述

过滤器

过滤器必须要要有返回值 return,通过管道符| 连接
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。

  • 在双花括号中
    {{ message | capitalize }}

  • v-bind
    <div v-bind:id="rawId | formatId"></div>

vue1.0的有默认的过滤器,但是在2.0的时候全部给去掉了
所以在vue中如果想要使用过滤器就需要自定义
自定义的方法有两种:全局定义和局部定义,

  • 全局定义的过滤器在任意的实例、组件中都可以使用,
  • 局部定义就是在实例、组件中定义,只能在这个实例或组件中使用
  • 当全局过滤器和局部过滤器重名时,会采用局部过滤器。
  1. 全局定义
    Vue.filter(name,handler)
    name是过滤器的名字,handler是数据格式化处理函数,接收的第一个参数就是要处理的数据,返回什么数据,格式化的结果就是什么
    在模板中通过 | (管道符) 来使用,在过滤器名字后面加()来传参,参数会在handler函数中第二个及后面的形参来接收
    Vue.filter('firstUpper',function (value,num=1,num2) {
    	console.log(num2)
    	return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase()
    })
  1. 局部定义
    在实例、组件的配置项中设置 filters,键名为过滤器名,值为handler
  filters:{
            firstUpper:function (value,num=1,num2) {
            console.log(num2)
            return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase()
            }
        }
  • 运行上述代码查看结果
  • 从0到第num位大写,从num+1位到最后小写,默认num为1,并打印输出num2
    <div id="app">
        <p>{{msg | firstUpper(2,3)}}</p>
    </div>
    <script src="./base/vue.js"></script>
    <script>
        // 全局过滤器
        Vue.filter('firstUpper', function (value, num = 1, num2) {
            console.log(num2)
            return value.substr(0,num).toUpperCase() + value.substr(num).toLowerCase()
        })
        new Vue({
            el: "#app",
            data: {
                msg: "world"
            },
            //局部过滤器
            // filters: {
            //     firstUpper: function (value, num = 1, num2) {
            //         console.log(num2)
            //         return value.substr(0, num).toUpperCase() + value.substr(num).toLowerCase()
            //     }
            // }
        })
    </script>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值