Vue3组件

组件就像一个功能比较强大的标签,也可以理解成一个功能模块。

创建组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <hello></hello><!--hello组件-->
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const app = Vue.createApp({//用常量接收Vue的createApp
            data(){
                return {
                    msg:"hello world"
                }
            }
        })

        //自定义组件
        app.component("hello",{//组件的标签名,组件的模板template
            template:`
                <h1>hello template</h1>
            `
        })

        app.mount("#app");
    </script>
</body>
</html>

组件扩展

app.component("hello",{})花括号里可以有template,也可以有data()以及methods,还能进行组件的嵌套

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <hello2></hello2><!--hello2组件-->
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const app = Vue.createApp();

        //自定义组件
        app.component("hello2",{//组件的标签名,组件的模板template
            data(){
                return {
                    msg:"hello template2"
                }
            },
            methods:{
                showData(){
                    alert("hello world")
                }
            },
            template:`
                <h1>{{msg}}
                    <button @click="showData">按钮</button>    
                </h1>
            `
        })

        app.mount("#app");
    </script>
</body>
</html>

如果将程序中一些公共的东西提取出来做成组件,那该组件就能多次被应用,即组件的复用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <my-fruit-list></my-fruit-list>
        <my-fruit-list></my-fruit-list>
        <my-fruit-list></my-fruit-list>
        <my-fruit-list></my-fruit-list><!--fruits组件的复用-->
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const app = Vue.createApp();

        app.component("my-fruit-list",{//水果组件
            template:`
                <div>水果</div>
                <my-counter></my-counter>
            `//组件嵌套
        })

        app.component("my-counter",{//计数器组件
            data(){
                return {
                    number:0
                }
            },
            methods:{
                increase(){
                    this.number++
                },
                decrease(){
                    this.number--
                }
            },
            template:`
                <button @click="decrease">-</button>
                <span>{{number}}</span>
                <button @click="increase">+</button>
            `
        })

        app.mount("#app");
    </script>
</body>
</html>

根组件

之前用app.component()创建的组件都是全局组件,而
const app = Vue.createApp();
app.mount("#app")的返回值就是根组件root component
Vue程序会通过Vue.createApp方法创建一个vue的应用实例(对象)
Vue.createApp({})中的配置项如data(),methods等都是根组件的配置项
整个程序所有的东西都是在根组件下发展出来的

这是一个组件树,顶部是根组件,my-fruit-list是子组件,组件树代表的就是整个程序了

this是根组件,如果this === app,则是false,因为app只是Vue的对象,不是组件
根组件没有template,它挂载的容器里的东西就作为模板

全局组件与局部组件


app.component这个过程也叫注册组件,然后才能在

中使用
使用component注册的组件叫全局组件
一个应用如果有1000个组件,假设它有200个组件是不用的,如果用component注册的话,程序在打包的时候,它也会将1000个组件打包

我们可以换种方式注册组件,使用components属性实现局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <my-hello></my-hello>
        <my-counter></my-counter>
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const myHello = {
            template:`
                <h1>hello</h1>
            `
        }
        const myCounter = {
            template:`
                <h1>计数器</h1>
            `
        }

        const app = Vue.createApp({
            components:{//注册两个局部组件
                "my-hello":myHello,//my-hello是局部组件名,后面的myHello是返回值
                "my-counter":myCounter
            }
        })
        app.mount("#app")
    </script>
</body>
</html>


如果my-counter想要嵌套进my-hello中还需要在my-hello中注册一个局部组件

以后开发中尽量用局部组件

组件的生命周期钩子(函数)

组件是先创建再挂载,才能应用到html中

组件的生命周期分为两个阶段,创建和挂载,进一步细分为4个情形。创建前后和挂载前后
生命周期的钩子就是在data(){}的同级,我们可以定义一些函数,我们可以在组件的不同阶段去执行这些函数

创建前beforeCreate

undefined是因为在创建前没有data的,调用msg自然没有返回值

创建后created
把beforeCreate改成created,data就有了,msg也就有值了

挂载前beforeMount挂载后mounted也是有msg的
create和mount的区别在于挂载前找不到html元素的,没有dom


ref属性

使用场景

一刷新页面就会自动做一些事,比如判断登录、获取数据、切换内容
以切换内容为例,类似于欢迎光临

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{msg}}</h1>
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const app = Vue.createApp({
            data(){
                return {
                    list:["你好","亲爱的用户","很高兴见到你"],
                    msg:""
                }
            },
            created(){
                this.showData();
            },
            methods:{
                showData(){
                    let i = 0;
                    let t = setInterval(() => {
                        this.msg = this.list[i];
                        i++;
                        if(i === 3){
                            clearInterval(t);
                        }
                    },500)
                }
            }
        })
        app.mount("#app")
    </script>
</body>
</html>
posted @ 2022-11-30 22:26  ben10044  阅读(147)  评论(0编辑  收藏  举报