day69:Vue:组件化开发&Vue-Router&Vue-client

目录

组件化开发

  1.什么是组件?

  2.局部组件

  3.全局组件

  4.父组件向子组件传值

  5.子组件往父组件传值

  6.平行组件传值

Vue-Router的使用

Vue自动化工具:Vue-Client

组件化开发

1.什么是组件?

1.组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的网站之间,也存在同样的功能。

2.而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个功能相关的[HTML、css和javascript]代码封装在一起组成一个整体的代码块封装模式,我们称之为“组件”。

3.所以,组件就是一个html网页中的功能,一般就是一个标签,标签中有自己的html内容结构,css样式和js特效。

4.这样,前端人员就可以在开发时,只需要书写一次代码,随处引入即可使用。

5.我们在进行vue开发的时候,还记得我们自己创建的vm对象吗,这个vm对象我们称为一个大组件,根组件(页面上叫Root),在一个网页的开发中,根据网页上的功能区域我们又可以细分成其他组件,或称为子组件

 

2.局部组件

局部组件三步走:声子、挂子、用子,即声明子组件、挂载子组件、使用子组件

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>html</title>
    <meta charset="UTF-8">
</head>
<body>

    <div id="app">
        <div class="header">
            这是头部{{ appmsg }}
        </div>
        <Sonapp/> <!-- 3.使用子组件 -->
    </div>

</body>
<script src="vue.js"></script>
<script>
    let Sonapp = {
        data(){ // 注意:组件中必须写成函数形式
            return {
                'sonappmsg':'hello Sonapp!'
            }
        },
        template:`
         <div class="content">
                内容部分{{sonappmsg}}
            </div>
        `
    };
let vm
= new Vue({ el:'#app', data(){ return{ 'appmsg':'hello app!', } }, components:{ Sonapp, // 2.挂载子组件 } }) </script> </html>

3.全局组件

局部组件使用时需要挂载,全局组件使用时不需要挂载

局部组件就在某个局部使用的时候,全局组件是大家公用的,或者说每个页面都有这么一个功能的时候,在哪里可能都会用到的时候。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>html</title>
    <meta charset="UTF-8">
</head>
<body>

    <div id="app">
        <Addnum></Addnum> <!-- 使用全局组件 -->
    </div>

</body>
<script src="vue.js"></script>
<script>
Vue.component("Addnum",{ data(){ return{ num:1 } }, template:` <div><input type="text" v-model="num"><button @click="num+=1">点击</button></div> ` })
let vm
=new Vue({ el:'#app', data:{ // 全局组件不需要挂载 } }) </script> </html>

 4.父组件向子组件传值

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>html</title>
    <meta charset="UTF-8">
</head>
<body>

    <div id="show">
        <h1>hello !</h1>
        <Father></Father>
    </div>

</body>
<script src="vue.js"></script>
<script>
   let Son = {
       data(){
           return{
               sonmsg:'这是子组件信息'
           }
       },
       template:`
              <div class="Son">
                <h1>{{sonmsg}}</h1>
                 <h2>子组件Template</h2>
                 <h2>{{ xx }}</h2>
        </div>
       `,
       props:['xx'] // 1.在子组件中使用prop属性声明
   };
   let Father ={
       data(){
           return{
               msg:'这是father组件',
               num:100,
           }
       },
       template:`

       <div class="nav">

                <h1 style="color:blue;">{{Msg}}---{{num}}</h1>
                <!--
                <Naver xx="xiaobei"></Naver> 静态传值
                <Naver :xx="num"></Naver>  动态传值
                -->

                <Son :xx="num"></Son>

        </div>

       `,
       components:{
           Son,
       }
   };
   let vm = new Vue({
       el:'#show',
       data(){
           return{

           }
       },
       components: {
           Father,
       }
   })
</script>
</html>

父组件向子组件传值,其实大致可以分为两步:

1.首先我们在子组件需要定义prop属性

声明了prop属性有xx之后,在子组件就可以使用xx了

let Son = {
    data(){
        return{
            sonmsg:'这是子组件信息'
        }
    },
    template:`
<div class="Son">
<h1>{{sonMsg}}</h1>
<h2>子组件Template</h2>
<h2>{{ xx }}</h2>
</div>
`,
    props:['xx'] // 1.在子组件中使用prop属性声明

2.父组件要定义自定义的属性

let father ={
       data(){
           return{
               msg:'这是father组件',
               num:100,
           }
       },
       template:`
       <div class="nav">

                <h1 style="color:blue;">{{Msg}}---{{num}}</h1>
                <Son xx="xiaobei"></Son> // 静态传值
                <Son :xx="num"></Son>  // 动态传值

        </div>
       `
   }

5.子组件往父组件传值

子组件往父组件传值,分三步。

第一步既然是子组件往父组件传值,肯定是在父组件想使用子组件的值

        所以第一步就是在父组件使用子组件的地方加上自定义事件 

第二步:在父组件中定义自定义事件对应的方法。方法需要写参数,用来接收子组件传递过来的参数

第三步子组件中调用方法来实现传值动作emit(父组件自定义事件名称,数据)

step1.就是在父组件使用子组件的地方加上自定义事件 

 let App = {

     ......
        //1. 父组件使用子组件的地方加上自定事件
        // <Naver @fatherHandler="fuckSon"></Naver>
        template:
         `
          <div class="nav">

                <h1 style="color:blue;">{{Msg}}---子组件的num为:{{xx}}</h1>

                <Naver @fatherHandler="fuckSon"></Naver>
        </div>

        `,
      ......

step2.在父组件中定义自定义事件对应的方法

 let App = {
       ......
            // 2  在父组件中定义自定义事件对应的方法,方法需要写参数,用来接收子组件传递过来的数据
            fuckSon(val){
                this.xx = val;
            }
      ......
        }


    };

step3.子组件中调用方法来实现传值动作​emit

 let Naver = {
      ......

        methods:{
            zouni(){
                //
                console.log(this);
                // 3 子组件中调用$emit方法,来实现传值动作 $emit(父组件自定义事件名称,数据)
                this.$emit('fatherHandler',this.sonNum);
      ......
            }
        }

    };

所有代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <h1>你好</h1>
    <App></App>
</div>



</body>
<script src="vue.js"></script>
<script>
    // 1 声明子组件  声子
    let Naver = {
        data(){
            return {
                navMsg:'这是顶部导航栏',
                sonNum:80,
            }
        },

        template:
         `
          <div class="Naver">
                <h1>{{navMsg}}</h1>
                <button @click="zouni">走你</button>

        </div>

        `,
        methods:{
            zouni(){
                //
                console.log(this);
                // 3 子组件中调用$emit方法,来实现传值动作 $emit(父组件自定义事件名称,数据)
                this.$emit('fatherHandler',this.sonNum);

            }
        }

    };

    let App = {
        data(){
            return {
                Msg:'这是App组件',
                num:100,
                xx:'',
            }
        },
        //1. 父组件使用子组件的地方加上自定事件
        // <Naver @fatherHandler="fuckSon"></Naver>
        template:
         `
          <div class="nav">

                <h1 style="color:blue;">{{Msg}}---子组件的num为:{{xx}}</h1>

                <Naver @fatherHandler="fuckSon"></Naver>
        </div>

        `,
        components:{
            Naver,
        },
        methods:{
            // 2  在父组件中定义自定义事件对应的方法,方法需要写参数,用来接收子组件传递过来的数据
            fuckSon(val){
                this.xx = val;
            }

        }


    };


    let  vm = new Vue({
        el:'#app',
        data(){
            return {

            }
        },
        // 2 挂载子组件  挂子
        components:{
            // 挂载组件的简写形式
            App,
            // Naver,

        }


    })



</script>
</html>

6.平行组件传值

 

平行组件传值,需要在最外层声明一个公交车bus,通过上车和下车的动作来进行平行组件的传值功能。

平行组件传值,大致分为三步:

第一步:声明一个bus的Vue对象

第二步:假设是T1组件往T2组件传值,那么在T1的method中需要执行一个bus.$emit(‘name’,this.t1num)

第三步:在T2组件中需要执行一个bus.$on(‘name’,(val))=>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <h1>你好</h1>
    <App></App>
    <div class="t1"></div>
</div>



</body>
<script src="vue.js"></script>
<script>
    // 1.声明公交车对象
    let bus = new Vue();

    Vue.component('T1',{
        data(){
            return {
                t1Msg:'我是t1组件',
                t1Num:120,
            }
        },
        template:`
            <div class="t1">
                <h3>{{t1Msg}}</h3>
                <button @click="zouni">走你</button>
            </div>
        `,
        methods:{
            zouni(){
                // 2.通过公交车将t1的值传送出去
              bus.$emit('kkk',this.t1Num);
            }
        }
    });
    Vue.component('T2',{
        data(){
            return {
                t2Msg:'我是t2组件',
                t2Num:130,
                t1msg:'',
            }
        },
        template:`
            <div class="t1">
                <h3>{{t2Msg}}</h3>
                <h3>t1组件传递过来的数据:{{t1msg}}</h3>
            </div>
        `,
        created(){
            // 3.通过公交车将t1传送的值接收过来
            bus.$on('kkk', (val) => {
                console.log(this);
                this.t1msg = val;
            });

        },

    });





    let App = {
        data(){
            return {
                Msg:'这是App组件',
                num:100,
                xx:'',
            }
        },
        template:
         `
          <div class="nav">

                <h1 style="color:blue;">{{Msg}}---子组件的num为:{{xx}}</h1>
                <T1></T1>
                <T2></T2>

        </div>

        `,

        methods:{
            }

        }


    };


    let  vm = new Vue({
        el:'#app',
        data(){
            return {
            }
        },

        components:{
            App,
        }


    });
    console.log(vm);



</script>
</html>

Vue-Router的使用

1.Vue-Router的介绍

vue就是我们前面学习的vue基础,vue + vue-router 主要用来做SPA(Single Page Application),单页面应用

为什么要使用单页面应用呢?因为传统的路由跳转,如果后端资源过多,会导致页面出现’白屏现象’,所以我们希望让前端来做路由,

在某个生命周期的钩子函数中,发送ajax来请求数据,进行数据驱动,之前比如我们用django的MTV模式,我们是将后端的数据全部渲染给了模板,然后模板再发送给前端进行浏览器页面的渲染,一下将所有的数据都给了页面,

而我们现在使用vue,我可以在组件的钩子函数中发送对应的ajax请求去获取对应的数据,而不是一下子就把数据都放到页面上了,单页面应用给我们提供了很多的便利。

 

 

 

这样的网站我们通过django是可以来完成页面的渲染的,模板渲染嘛,但是这个论坛的数据资源有很多,我们通过django的MTV模式是一下子就将数据全部放到页面里面了,那么页面通过浏览器渲染的时候,浏览器可能没有那么快渲染出来,会出现几秒钟的白屏现象,也就是说几秒钟之后用户才看到页面的内容,这样体验起来就不好,为了用户体验好,就用到了我们说的单页面应用,django模板渲染做大型应用的时候,也就是页面很复杂,数据量很大的页面的时候,是不太合适的,当然如果你够nb,你也可以优化,但是一般它比较适合一些页面数据比较小的应用。

那么解释一下什么是单页应用,看下图:(react、angular也都是做单页面应用,很多大型的网站像网易云音乐,豆瓣等都是react写的单页面应用)

 

 

2.Vue-Router的简单操作

一共分四步

1.定义 (路由) 组件。

2.定义路由

3. 创建 router 实例,然后传 `routes` 配置

4.创建和挂载根实例。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <h1>你好</h1>
    <App></App>

</div>



</body>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>

    // 1.定义两个路由组件
    let Home = {
        data(){
            return {
                msg:'这是home页面'
            }
        },
        template:`
        <div class="home">
            <h1>{{msg}}</h1>

        </div>
        `
    };

     let Course = {
        data(){
            return {
                msg:'这是Course页面'
            }
        },
        template:`
        <div class="course">
            <h1>{{msg}}</h1>

        </div>
        `
    };


    let App = {
        data(){
            return {
                Msg:'这是App组件',
                num:100,
                xx:'',
            }
        },
        //1. 父组件使用子组件的地方加上自定事件
        // <Naver @fatherHandler="fuckSon"></Naver>
        template:
         `
          <div class="nav">

                <router-link to="/home">首页</router-link>
                <router-link to="/course">课程页</router-link>

                <router-view></router-view>

        </div>

        `,

        methods:{
            // 2  在父组件中定义自定义事件对应的方法,方法需要写参数,用来接收子组件传递过来的数据
            fuckSon(val){
                this.xx = val;
            }

        }


    };
    // 2.定义路由
    const routes = [
        {path:'/home', component:Home},
        {path:'/course', component:Course},
    ];

    // 3.建 router 实例,然后传 `routes` 配置
    let router = new VueRouter({
        routes,
    })


    let  vm = new Vue({
        el:'#app',
        router, // 4.挂载router
        data(){
            return {

            }
        },

        components:{

            App,

        }


    });
    console.log(vm);



</script>
</html>

Vue自动化工具:Vue-Client

。。。先留个坑。到时候再详细补充。