vuejs组件化开发

vuejs 组件化

什么是组件化开发?

组件化开发是近两年流行起来的一个开发模式,把日常项目开发中一些常用的代码块封装起来,封装成一个一个的功能块,这个功能块里面包含了 结构、样式、行为、数据(state)、生命周期等。然后在做项目开发时候,项目的那些页面就由这些小的组件然后进行构成,类似乐高积木。

网站:(网页—>组件—>封装代码块)

常见的可以复用的代码:

  • 按钮
  • 弹出框
  • 模态框
  • badge 徽章
  • Icon

组件化图片
组件其实就是开发者自己封装好的 HTML标签。因为原生的html标签非常的有限。

为什么要引入组件化开发?

就是为了代码的复用,后期的维护方便。同时为了后期的扩展功能也是非常方便,同时后期别人接受也是很好接受。

vuejs如何进行组件化开发?

Vue.component()

vuejs 常见的第三方的组件库有哪些?

  • ElementUI (pc端项目) (饿了么前端团队)

    • https://element.eleme.cn/#/zh-CN/component/drawer
  • MintUI (移动端项目) (饿了么前端团队)

    • http://mint-ui.github.io/docs/#/
  • iview (个人)

    • https://weapp.iviewui.com/components/switch
  • uview (一般配合 uniapp 做小程序和其他的移动端使用)

    • https://www.uviewui.com/components/button.html
  • vantUI(移动端UI)(有赞团队)

    • https://vant-contrib.gitee.io/vant/#/zh-CN/goods-action

组件

全局组件的基本用法

先学习自己自定义组件尝试一下.
vuejs 组件: 1. 全局组件 2. 局部组件 定义组件,必须写在实例化之前。
参数1(string): 组件的名称,
1.1 一般使用烤串法进行命名(abc-def-ghi)每个单词使用小写,中间使用中线串起来。
1.2 同时也可以使用小驼峰的方式,但是如果是以小驼峰的方式命名的话,则在调用的时候,要使用烤串法调用。
参数2(object):组件的描述对象(1. 结构 html代码 2. 样式 Css 3. 行为 js事件 4. data 5.生命周期函数)

Vue.component('mycompoent1', {
        /* tempalate 必须的,同时在写的过程中,这个模板文件有且仅有一个根节点*/
        template: `
          <div>
            <h2>组件的HTML结构</h2>
            <h2>组件的HTML结构</h2>
          </div>
        `
    });
//html页面里之间引用定义好的组件名
<mycompoent1></mycompoent1>

在这里插入图片描述
烤串法和小驼峰命名

	Vue.component('my-compoent2', {
        template: `
          <div>
            <h2>组件的HTML结构</h2>
            <h2>组件的HTML结构</h2>
          </div>
        `
    });

    /*小驼峰命名法*/
    /* 调用:myCompoent3--->my-component3*/
    Vue.component('myCompoent3', {
        template: `
          <div>
            <h2>组件的HTML结构</h2>
            <h2>组件的HTML结构</h2>
          </div>
        `
    });
	<my-compoent2></my-compoent2>
    <hr>
    <my-compoent3></my-compoent3>

在这里插入图片描述
总结: 在用户自定义组件的时候,组件的名称建议使用 烤串法命名,这样的定义的时候不出错,调用时候自然不会出错!

全局组件的样式和行为

		Vue.component('mycompoent1', {
        created() {
            console.log('组件 mycomponent1产生了');
            // 一般会发生网络请求
            this.getCommentList();
        },
        /*属于组件自己的数据要使用一个 data函数来定义,该函数的返回值是一个对象,该对象里面的数据我们一般称之为 模型数据,模型数据里面的属性称之为模型变量,模型变量可以在template里面使用*/
        data() {
            return {
                title: 'hi component!',
                counter: 0,
                result: [],
                page: 1,
                limit: 5,
            }

        },
        /*组件也是可以存在 methods 的这个里面就写我们事件的回调函数*/
        methods: {
            async getCommentList() {
                // axios 发生网络请求
                let url = `http://localhost:3000/api/v1/comment/list?page=${this.page}&limit=${this.limit}`;
                try {
                    // 请求完成
                    this.isLoading = false;
                    const res = await axios.get(url); // res.data 响应体
                    this.result = res.data.data.result;
                    console.log('this.result ', this.result);
                } catch (e) {
                    this.result = [];
                    alert('获取信息失败!');
                    return;
                }
            },
            clickHandler() {
                this.counter++;
                console.log('clickHandler');
            }
        },
        template: `
          <div style="color:red;">
            <h2>我的第一个组件</h2>
            <p>行为:事件</p>
            <h3>{{ title }}</h3>
            <p>counter: {{ counter }}</p>
            <button @click="clickHandler()">点击我</button>
            <hr>
            <hr>
             <ul v-for="ele in result">
                <li>序号:{{ ele._id }}</li>
                <li>用户名:{{ele.username}}</li>
                <li>评论日期:{{ele.addTime}}</li>
                <li>评论内容:{{ele.content}}</li>
            </ul>
</div>
        `
    });

在这里插入图片描述

	<mycompoent1></mycompoent1>
    <mycompoent1></mycompoent1>
    <mycompoent1></mycompoent1>

组件是可以高度复用的,想用多少次就用多少次

局部组件

要先定义

	new Vue({
        el: '#app',
        data: {},
        /*定义局部组件的位置*/
        components: {
           /*key:组件名称 烤串法; value:组件描述对象*/
            'my-component2': myComponent1,
            'my-component1': myComponent2,
        }
    });

将组件描述对象提取出来了,可以不提取,但是提取了会更精简一些。

const myComponent1 = {
		//支持生命周期函数
        created() {
            console.log('created');
        },
        data() {
            return {
                counter: 0,
            }
        },
        methods: {
            clickHandler() {
                this.counter++;
                console.log('clickHandler');
            }
        },
        template: `
                    <div style="color: blue;">
                    <h1>我是第二个局部组件!</h1>
                    <p>counter:{{ counter }}</p>
                    <button @click="clickHandler">点击我</button>
                    </div>
                `
    };

    const myComponent2 = {
        created() {
            console.log('created');
        },
        data() {
            return {
                counter: 0,
            }
        },
        methods: {
            clickHandler() {
                this.counter++;
                console.log('clickHandler');
            }
        },
        template: `
                    <div style="color: blue;">
                    <h1>我是第一个局部组件!</h1>
                    <p>counter:{{ counter }}</p>
                    <button @click="clickHandler">点击我</button>
                    </div>
                `
    };

组件调用:1. 双标签 2. 单标签 自闭合
建议:双标签调用;如果是一单一双,有一个出不来

    <!--<my-component1/>-->
    <my-component1></my-component1>
    <hr>
    <my-component2></my-component2>

在这里插入图片描述

动态组件

官方提供:
component 特点:该组件显示什么内容,取决于我们给该组件的is属性对应的属性是哪个组件,就显示哪个组件的内容

 <component :is="my-component1"></component>
	Vue.component('my-compoent1', {
        template: `
          <div>
            <h2>组件的HTML结构</h2>
            <h2>组件的HTML结构</h2>
          </div>
        `
    });

在这里插入图片描述
一般可以去做一个选项卡

<!DOCTYPE html>
<html lang="zh_CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .list {
            width: 200px;
            height: 50px;
            display: flex;
        }
        .list li {
            border: 1px solid #000;
            width: 80px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            list-style: none;
            cursor: pointer;
        }
        .list li.active {
            background-color: gold;
        }
    </style>
</head>
<body>
<div id="app">
    <ul class="list">
        <li :class="{'active': currentComponent == 'my-component1'}" @click="selectComponent('my-component1')">正在热映...
        </li>
        <li :class="{'active': currentComponent == 'my-component2'}" @click="selectComponent('my-component2')">即将上映...
        </li>
    </ul>
    <!--keep-alive 也是官方提供的,可以直接使用,该组件的作用可以保存组件的状态,不会让组件重新的生成和销毁-->
    <keep-alive>
        <component :is="currentComponent"></component>
    </keep-alive>
</div>
</body>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>
    Vue.component('my-component1', {
        template: `
            <div>
                <h2>我是第一个组件!</h2>
                <p>正在热映...</p>
                <hr>
            </div>
        `
    });

    Vue.component('my-component2', {
        template: `
            <div>
                <h2>我是第二个组件!</h2>
                <p>即将上映...</p>
                <hr>
            </div>
        `
    });

    new Vue({
        el: '#app',
        data: {
            currentComponent: 'my-component1',
        },
        methods: {
            selectComponent(item) {
                console.log('item', item);
                this.currentComponent = item;
            }
        }
    });
</script>
</html>

在这里插入图片描述
在这里插入图片描述

组件间的通信问题

(vuejs面试必问)

什么是组件间的通信问题?

由于页面是由组件构成的,那么组件间存在关系。

常见的关系如下:

  • 嵌套关系
    • 父子嵌套(父组件,子组件)
    • 爷孙嵌套
  • 平级
    • 兄弟组件

有了这种关系后,组件是需要进行数据的传递,这个时候就称之为 组件间的通信问题。
常见的通信:

  • 父子通信(属性传递)
  • 子父通信(回调函数)
  • 兄弟通信(1. 公共的父组件 2. EventBus 事件车)

上面的这些通信方式全部可以使用一个叫做 vuex 方案进行解决。

父子通信(属性传递)

Vue.component('father-component', {
        template: `
            <div>
            <h2>父组件</h2>
            <p>父亲的钱:{{ money }}</p>
            <hr>
            //直接在父组件里用子组件
            <son-component></son-component>
			</div>
        `
    });

    Vue.component('son-component', {
        template: `
            <div>
            <h3>子组件</h3>
            <hr>
            </div>
        `
    });
<father-component></father-component>

在这里插入图片描述
如果父组件要往子组件传东西,父亲定义一个data放东西,子组件定义prpos拿东西

		Vue.component('father-component', {
        data() {
            return {
                money: 1000,
                title: '我是父组件的内容!'
            }
        },
        template: `
            <div>
            <h2>父组件</h2>
            <p>父亲的钱:{{ money }}</p>
            <hr>
            <son-component :qian="money" :title="title"></son-component>
            </div>
        `
    });

    Vue.component('son-component', {
        props: ['qian', 'title'],
        template: `
            <div>
            <h3>子组件</h3>
            <p>来自父亲的钱:{{ qian }}</p>
            <hr>
               <p>{{ title }}</p>
            <hr>
            </div>
        `
    });

在这里插入图片描述

子父通信(回调函数)

1.需要在父组件自定义一个事件(事件的名称用户自定义),然后在 methods 定义好自定义事件的回调函数

<son-component @giveMoney="callback" :qian="money" :title="title"></son-component>

定义方法

		methods: {
            callback(data) {
                console.log('来自儿子的问候:', data); // data 儿子传递过来的信息(儿子:子组件)
            }
        },
  1. 在子组件里面触发父组件里面自定义的事件
<button @click="giveMeSameMoney">老爸,给我点生活费</button>

定义方法

		methods: {
            giveMeSameMoney() {
                console.log('giveMeSameMoney');
                /*第一个参数,父组件里面定义的自定义事件,第二个参数传递该事件回调函数的参数*/
                /*第二个参数:一般叫做 payload 载荷*/
                this.$emit('giveMoney', {money: 2000}); //  this.$emit 是 vuejs 提供的
            }
        },

3.父亲接收
方法接收

this.message = data.money;
<p>来自儿子的问候:{{ message }}</p>

整个代码

		Vue.component('father-component', {
        data() {
            return {
                money: 1000,
                title: '我是父组件的内容!',
                message: '',
            }
        },
        methods: {
            callback(data) {
                console.log('来自儿子的问候:', data); // data 儿子传递过来的信息(儿子:子组件)
                this.message = data.money;
            }
        },
        /* 子父通信:1.需要在父组件自定义一个事件(事件的名称用户自定义),然后在 methods 定义好自定义事件的回调函数*/
        template: `
            <div>
            <h2>父组件</h2>
            <p>父亲的钱:{{ money }}</p>
            <p>来自儿子的问候:{{ message }}</p>
            <hr>
            <son-component @giveMoney="callback" :qian="money" :title="title"></son-component>

</div>
        `
    });

    Vue.component('son-component', {
        props: ['qian', 'title'],
        methods: {
            giveMeSameMoney() {
                console.log('giveMeSameMoney');
                /*第一个参数,父组件里面定义的自定义事件,第二个参数传递该事件回调函数的参数*/
                /*第二个参数:一般叫做 payload 载荷*/
                this.$emit('giveMoney', {money: 2000}); //  this.$emit 是 vuejs 提供的
            }
        },
        /*子父通信:2. 在子组件里面触发父组件里面自定义的事件*/
        template: `
            <div>
            <h3>子组件</h3>
            <p>来自父亲的钱:{{ qian }}</p>
            <p>需求:儿子觉得父亲给的钱不够,那么希望父亲给多一点?(回调函数实现?)</p>
            <button @click="giveMeSameMoney">老爸,给我点生活费</button>
            <hr>
               <p>{{ title }}</p>
            <hr>
            </div>
        `
    });
    new Vue({
        el: '#app',
        data: {}
    });
<div id="app">
    <father-component></father-component>
</div>

在这里插入图片描述

兄弟通信

例子:熊大要发送一个信息给熊二,告知熊二,今天下午五点一起去揍光头强;熊二回复熊大,信息已收到,没有问题。

	<xiong-da-component></xiong-da-component>
    <hr>
    <xiong-er-component></xiong-er-component>
		Vue.component('xiong-da-component', {
        template: `
            <div>
            <h2>熊大-组件</h2>
            </div>
        `
    });

    Vue.component('xiong-er-component', {template: `
            <div>
            <h3>熊二二-组件</h3>
            </div>
        `
    });

公共的父组件 1. 熊大信息给父组件(回调函数)2. 父组件信息给熊二(属性传递)
EventBus 事件车 计算机网络里的三大总线 1. 地址总线 2. 控制总线 3. 寻址总线 2^64

  • 事件车:1. 实例化一个事件车
 const EventBus = new Vue();
  • 通信:存在一个主动方(信息是谁发起的),被动方(信息的接受者)
  • 事件车:2. 需要在被动方的 created 生命周期函数里面设置监听事件(用户自定义)
  • 事件车:3. 需要在主动方的业务代码去触发第二步里面的监听事件

一开始熊二是被动方,在熊二组件的生命周期函数里用到事件车,通过.$on设置监听函数(函数用户自定义)

		created() {
            /*被动方:onClick*/
           EventBus.$on('waitForMyBigBrotherGiveMeCall', (data) => {
                console.log('来自大哥的电话:', data);
            });
        },

熊大作为主动方来触发这件事情,在熊大组件里button创建一个点击事件

<button @click="callMyLitterBrother">打电话告知熊二</button>
		data() {
            return {
                message: '今天下午五点一起去揍光头强',
            }
        },
		methods: {
            /*主动方:触发监听事件*/
            callMyLitterBrother() {
                EventBus.$emit('waitForMyBigBrotherGiveMeCall', {message: this.message});
            }
        },

熊二接收到信息之后

		data() {
            return {
                myMessage: '',
            }
        },
        created() {
            /*被动方:onClick*/
            EventBus.$on('waitForMyBigBrotherGiveMeCall', (data) => {
                console.log('来自大哥的电话:', data);

                this.myMessage = data.message;

            });

        },
<p>来自大哥的电话信息:{{ myMessage }}</p>

在这里插入图片描述
熊二收到信息后要给熊大回信息,此时熊二为主动方,熊大为被动方。
此时熊大做事件监听:

		created() {
            /*被动方:熊大等待熊二传递信息*/
            EventBus.$on('waitForMyLitterBrotherGiveMeCall', (data) => {
                console.log('来自小弟熊二的问候', data);
            })

        },

熊二回消息:

<button @click="giveMeMyBigBrotherCall">回个电话给熊大</button>
		data() {
            return {
                myMessage: '',
                message: '信息已收到,没有问题!!!',
            }
        },
		methods: {
            giveMeMyBigBrotherCall(){
                /*熊二 主动方*/
                EventBus.$emit('waitForMyLitterBrotherGiveMeCall', {message: this.message});
            }
        },

熊大接收到信息之后拿出来:

		data() {
            return {
                message: '今天下午五点一起去揍光头强',
                myMessage: '',
            }
        },
		created() {
            /*被动方:熊大等待熊二传递信息*/
            EventBus.$on('waitForMyLitterBrotherGiveMeCall', (data) => {
                console.log('来自小弟熊二的问候', data);
                this.myMessage = data.message;
            })

        },
<p>来自熊二的回复:{{ myMessage }}</p>

整个代码:

	const EventBus = new Vue();

    Vue.component('xiong-da-component', {

        created() {
            /*被动方:熊大等待熊二传递信息*/
            EventBus.$on('waitForMyLitterBrotherGiveMeCall', (data) => {
                console.log('来自小弟熊二的问候', data);
                this.myMessage = data.message;
            })
        },
        data() {
            return {
                message: '今天下午五点一起去揍光头强',
                myMessage: '',
            }
        },
        methods: {
            /*主动方:触发*/
            callMyLitterBrother() {
                EventBus.$emit('waitForMyBigBrotherGiveMeCall', {message: this.message});
            }
        },
        template: `
            <div>
            <h2>熊大-组件</h2>
            <button @click="callMyLitterBrother">打电话告知熊二</button>
            <p>来自熊二的回复:{{ myMessage }}</p>
</div>
        `
    });
    Vue.component('xiong-er-component', {
        data() {
            return {
                myMessage: '',
                message: '信息已收到,没有问题!!!',
            }
        },
        created() {
            /*被动方:onClick*/
            EventBus.$on('waitForMyBigBrotherGiveMeCall', (data) => {
                console.log('来自大哥的电话:', data);
                this.myMessage = data.message;
            });
        },
        methods: {
            giveMeMyBigBrotherCall(){
                /*熊二 主动方*/
                EventBus.$emit('waitForMyLitterBrotherGiveMeCall', {message: this.message});
            }
        },
        template: `
            <div>
            <h3>熊二二-组件</h3>
            <p>来自大哥的电话信息:{{ myMessage }}</p>
            <button @click="giveMeMyBigBrotherCall">回个电话给熊大</button>
</div>
        `
    });
    new Vue({
        el: '#app',
        data: {}
    });
	<xiong-da-component></xiong-da-component>
    <hr>
    <xiong-er-component></xiong-er-component>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue.js是一种流行的JavaScript框架,广泛应用于Web应用程序的开发中。使用Vue.js开发甘特图项目可以提供丰富的交互和可视功能。下面是使用Vue.js开发甘特图项目的一些主要步骤和考虑因素: 1. 数据结构和状态管理:在Vue.js中,可以使用组件和数据驱动的方式来管理甘特图中的任务和时间信息。可以创建一个主组件来承载整个甘特图,并在该组件中定义任务和时间信息的数据结构。同时,可以使用Vue的响应式属性来跟踪和更新任务的状态、进度和时间。 2. 组件设计和交互:在Vue.js中,可以创建各种组件来实现甘特图的功能和交互。例如,可以创建一个任务组件来显示单个任务的详细信息和状态。可以创建一个时间轴组件来显示甘特图的时间范围和刻度。可以创建一个进度条组件来表示任务的完成进度。可以使用Vue的事件机制来实现各个组件之间的通信和交互。 3. 数据绑定和模板语法:Vue.js提供了灵活且易于使用的数据绑定和模板语法。可以使用双向绑定来实现任务和时间信息的动态更新。可以使用条件渲染和循环来根据任务的状态和时间来显示不同的组件和元素。可以使用Vue的计算属性和过滤器来处理任务和时间的计算和格式。 4. 样式和布局:Vue.js可以与CSS和样式预处理器(如Sass或Less)结合使用,以实现甘特图项目的样式和布局。可以使用Vue的样式绑定和动态类绑定来实现任务、进度和时间的样式。可以使用CSS网格或Flexbox来实现甘特图的布局和响应式设计。 总之,通过使用Vue.js开发甘特图项目,可以轻松地实现交互性和可视的功能。Vue.js的灵活性和易用性使得开发者可以方便地构建和管理甘特图项目。 ### 回答2: Vue.js是一款流行的JavaScript框架,经过许多开发者的认可和广泛应用。使用Vue.js进行甘特图项目开发具有以下优势: 1. 组件开发:Vue.js支持组件开发,将各个功能模块拆分成多个组件,使得代码结构清晰、易于维护。可以为甘特图中的不同部分(如任务列表、时间轴、进度条等)分别创建对应的组件,进行高效开发和复用。 2. 响应式设计:Vue.js采用了双向数据绑定和虚拟DOM的技术,使得数据的变能够自动反映到界面上。在甘特图项目中,可以通过Vue.js实时更新任务的状态、进度等信息,并自动生成相应的图表展示给用户。 3. 强大的工具库和插件:Vue.js拥有丰富的工具库和插件生态系统,可以大大提高开发效率。比如,可以使用element-ui或vuetify等UI组件库快速构建甘特图的界面;使用moment.js等日期时间处理库来处理任务的开始时间和结束时间等。 4. 单页应用(SPA)优势:Vue.js可以实现单页应用(SPA),在甘特图项目中可以充分发挥这一优势。用户可以无需刷新页面,在同一页面上进行任务调整、进度更新等操作,提高用户的交互体验。 5. 丰富的社区支持:Vue.js拥有庞大的开发者社区和活跃的贡献者群体,可以从中获得各种问题的解答、教程和开源项目。这为开发者提供了良好的学习和交流平台,节约了开发时间和精力。 综上所述,使用Vue.js开发甘特图项目将能够提高开发效率、加强代码结构、响应快速、提升用户体验,并且拥有丰富的社区支持,是一种理想的选择。 ### 回答3: Vue.js是一个用于构建用户界面的渐进式JavaScript框架,可以轻松开发甘特图项目。 首先,我们可以使用Vue.js的组件开发方式来构建甘特图。我们可以创建一个甘特图组件,该组件包含项目的时间轴、任务列表和任务条。使用Vue.js的数据绑定功能,我们可以将任务数据动态地绑定到任务条上。这样,当任务数据发生变时,任务条也会相应地更新。 其次,Vue.js提供了丰富的生命周期钩子函数,可以帮助我们在各个阶段进行逻辑处理。例如,在甘特图组件的mounted钩子函数中,我们可以初始甘特图的样式和布局。在甘特图的更新周期中,可以使用updated钩子函数来处理任务条的位置和长度的更新。 此外,Vue.js提供了强大的路由功能,可以帮助我们实现不同页面的导航。我们可以使用Vue Router来定义甘特图项目的不同视图,并通过路由参数来传递项目的ID等信息。 最后,Vue.js还支持组件间的通信,这对于甘特图项目非常有用。例如,我们可以创建一个任务编辑组件,用于编辑任务的详细信息。当用户点击某个任务条时,我们可以通过触发一个自定义事件,将该任务的数据传递给任务编辑组件,使用户可以对任务进行编辑和保存。 总而言之,利用Vue.js开发甘特图项目非常方便,可以帮助我们快速构建交互性强、功能丰富的甘特图应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值