Vue学习笔记(二)组件化和模块化

  • 前言
  • 组件化
    • 什么是组件化
    • 1、基础使用
    • 2、全局组件和局部组件
    • 3、语法糖和模板抽离
    • 4、组件的data为什么是函数
    • 5、父子组件
      • 5.1 父子组件
      • 5.2 父子组件通信
        • 5.2.1 父传子值
        • 5.2.2 子传父值
        • 5.2.3 父访问子
        • 5.2.4 子访问父
    • 6、插槽slot
      • 6.1 插槽的基本使用
        • 6.1.1 插槽的使用
        • 6.1.2 插槽的默认值
        • 6.1.3 多个值替换插槽
      • 6.2 具名插槽
        • 6.3 作用域插槽
  • 模块化
    • 什么是前端模块化
    • es5模块化解决方案
    • es6模块化解决方案
  • 联系题

前言

本章记录一下vue的组件化和模块化,这是vue比较重要的知识点。会在实际开发中大量的使用到,因此,会比较详细的记录。
如需转载,请标明出处。
若发现问题,还望指正。

组件化

什么是组件化

组件化是一种思想,将一个复杂的页面分解成多个小的组件,每个组件都是独立的个体,互不影响,这样管理和维护起来就非常的容易。
组件化也是vue.js中重要的思想。
1、它提供了一种抽象,我们开发出一个个的组件来构成我们的应用。
2、每一个应用都可以抽象成一颗组件树。

1、基础使用

分为三个步骤:创建组件构造器 -> 注册组件 -> 使用组件

    <div id="app"><!-- 步骤三:使用组件 --><cpn></cpn></div><script src="../js/vue.js"></script><script>// 步骤一:创建组件构造器const comp = Vue.extend({template: '<div>这是组件</div>'});// 步骤二:注册组件Vue.component('cpn', comp);const app = new Vue({el: '#app'});</script>

注意:前两个步骤必须放在创建vue实例之前,否者无效。
组件必须挂载在某个vue实例下,否者无效。

2、全局组件和局部组件

如上的使用方式即为全局组件的使用,它可以在任何的vue实例下使用,然后平时开发时通常都是使用局部组件。
局部组件的使用如下,在需要的vue中添加属性components,并进行注册,此时,只有在该vue实例里是可以使用该组件,其他地方皆不可使用。

    <div id="app"><!-- 步骤三:使用组件 --><cpn></cpn></div><script src="../js/vue.js"></script><script>// 步骤一:创建组件构造器const comp = Vue.extend({template: '<div>这是组件2</div>'});// 步骤二:注册组件// Vue.component('cpn', comp);const app = new Vue({el: '#app',components: {//cpn:组件的标签名//创建的组件名。步骤一的对象cpn: comp}});

3、语法糖和模板抽离

我们实际开发时是不会如上的方式去开发的,过于复杂了,我们会将代码进行简化,因为比较简单,此处直接上代码。

    <div id="app"><cpn></cpn></div><template id="mytemp"><div>我是组件</div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',components: {cpn: {template: '#mytemp'}}});</script>

模板抽离除了这种方式,还可以使用script标签的方式,此处不详细说明。
template标签里必须有且只有一个根标签

4、组件的data为什么是函数

本来是记住的,但是记录的时候就又忘记了,因此这里记录下来。
组件,是会复用的,如果将data设计成属性,那么,他们将指向同一个对象,一旦一个地方改变,复用的地方都会改变,这是有问题的。
如果设计成函数,函数是有作用域,因此每个组件都有自己的作用域,返回的都是自己的对象。不会影响其他组件的值。

5、父子组件

5.1 父子组件

父子组件即父组件和子组件,当一个组件在另一个组件里时,外层的组件即为里层组件的父组件,里层组件为子组件
vue实例为root组件,即根组件,也是它里面组件的父组件。

5.2 父子组件通信

5.2.1 父传子值

父传子值主要使用到了props属性,它是一个数组,里面每一个值都是字符串,如下。props里的值为val,在父组件里使用时,需要用到v-bind。

    <div id="app"><cpn :val='vals'></cpn></div><template id="mytemp"><div>我是组件 {{val}}</div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',data: {vals: '这是父传子值'},components: {cpn: {template: '#mytemp',props: ['val']}}});</script>

5.2.2 子传父值

需要注意两点:
1、按钮上的属性是@click,而非@onclick
2、this.$emit(‘bclick’, “hello”)需要加this

<div id="app"><cpn @bclick="btnClick"></cpn></div><template id="mytemp"><div>我是组件<button @click="ccc">按钮</button></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',data: {vals: '这是父传子值'},methods: {btnClick(val) {console.log(val);}},components: {cpn: {template: '#mytemp',methods: {ccc() {this.$emit('bclick', "hello")}}}}});</script>

5.2.3 父访问子

父组件访问子组件的内容,如方法、属性等。
children:

children这个很少使用,通常我们获取子组件的内容不使用它,一般在获取所有子组件时才使用

<div id="app"><button @click="btnClick">父访问子</button><cpn></cpn></div><template id="mytemp"><div>我是组件</div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',data: {vals: 'parent'},methods: {btnClick(val) {console.log(this.$children[0].va);this.$children[0].ccc();}},components: {cpn: {template: '#mytemp',data() {return {va: 'son'}},methods: {ccc() {console.log("this is child");}}}}});</script>
son
this is child

这里打印出this.$children[0]的值可见子组件的内容。如下

refs:
既然不适用children,那么肯定有其他的代替,没错,就是refs,它的使用可以规避掉children的弊端(children需要下标去获取对应的组件,一旦动态改变的组件的顺序等就无法准确获取到相应的子组件)。
它的使用需要在父组件的子组件标签中添加ref=“”的属性,类似于id的意思,需要唯一。然后再通过this.$refs获取对应的子组件。

<div id="app"><button @click="btnClick">按钮</button><cpn></cpn><cpn ref="aa"></cpn><cpn ref="bb"></cpn></div><template id="mytemp"><div>我是组件</div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',data: {vals: 'parent'},methods: {btnClick() {this.$refs.aa.c1();}},components: {cpn: {template: '#mytemp',data() {return {va: 'son'}},methods: {c1() {console.log("子组件1");},c2() {console.log("子组件2");},c3() {console.log("子组件3");}}}}});</script>

5.2.4 子访问父

子组件访问父组件的内容,如方法、属性等。
子访问父可以使用parent,它的使用与parent,它的使用与parent,它的使用与children类似。这里就不再赘述。并且它使用的很少,因为如果使用了它就意味着于父组件的耦合度高了,不利于开发。
还有另一个属性$root,它可以获取到顶级父元素,也就是vue实例的内容。不过它同样使得的比较少,此处也不再多说。

6、插槽slot

6.1 插槽的基本使用

6.1.1 插槽的使用

以前的代码是不具备扩展的,但是有了插槽就不一样了,可以很好的扩展,也可以很好的自定义。
在子组件需要扩展的地方使用上slot,然后在父组件的子组件标签中写入需要的内容即可。

<div id="app"><cpn><button>按钮</button></cpn><cpn><span>嘿嘿</span></cpn><cpn><i>hhha</i></cpn></div><template id="mytemp"><div>我是组件<slot></slot></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',components: {cpn: {template: '#mytemp'}}});</script>

6.1.2 插槽的默认值

如果插槽里有很多地方都需要使用相同的内容,此时我们就可使用默认值,那么不使用默认值的地方加入新内容即可,其他需要就可以不写内容了。

<div id="app"><cpn></cpn><cpn><span>嘿嘿</span></cpn><cpn><i>hhha</i></cpn></div><template id="mytemp"><div>我是组件<slot><button>按钮</button></slot></div></template>

6.1.3 多个值替换插槽

如果需要插入多个标签的内容,也是可以的,他会直接将这些内容整体替换。

<div id="app"><cpn></cpn><cpn><span>嘿嘿</span><b>呵呵呵呵呵呵</b><span>哈哈</span></cpn><cpn><i>hhha</i></cpn></div><template id="mytemp"><div>我是组件<slot><button>按钮</button></slot></div></template>

6.2 具名插槽

说简单点,就是给插槽取个名字,使用的时候指明替换哪一个,例如导航组件部分,html内容部分如下。

    <div id="app"><cpn><button slot="center">替换</button></cpn></div><template id="mytemp"><div><slot name="left"><button>左</button></slot><slot name="center"><button>中</button></slot><slot name="right"><button>右</button></slot></div></template>

6.3 作用域插槽

**slot-scope: **被废弃了,但是也能使用
组件是有作用域的,父子之间也是可以进行通信的。
使用插槽的时候也会涉及到作用域。当父组件需要使用子组件的值时,需要将值抛出,父组件通过slot-scope进行获取。下面的方式可能有些过时,如下。

<div id="app"><cpn></cpn><cpn><!--这种方式最后一项会多一个分隔符出来--><div slot-scope="slot2"><span v-for="item in slot2.data">{{item}} </span></div></cpn><cpn><!--join()就可以规避上面那种的问题--><div slot-scope="slot3"><span>{{slot3.data.join(" - ")}}</span></div></cpn></div><template id="mytemp"><div><slot :data="comics"><ul><li v-for="item in comics">{{item}}</li></ul></slot></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app',components: {cpn: {template: '#mytemp',data() {return {comics: ['斗破苍穹', '斗罗大陆', '灵笼', '完美世界', '雾山五行', '吞噬星空']}}}}});</script>


**v-slot:**新版本使用

<div id="app"><cpn><template v-slot:default="slot2"><!--此处必须是template,否者无效--><span>{{slot2.data}} </span></template></cpn></div><template id="mytemp"><div><slot :data="comics"><ul><li v-for="item in comics">{{item}}</li></ul></slot></div></template>

独占默认插槽的缩写语法:
在上述情况下,当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上:

 <div id="app"><cpn v-slot:default="slot2"><span>{{slot2.data}} </span></cpn></div>

这种写法还可以更简单。就像假定未指明的内容对应默认插槽一样,不带参数的 v-slot 被假定对应默认插槽:

 <div id="app"><cpn v-slot="slot2"><span>{{slot2.data}} </span></cpn></div>

只要出现多个插槽,请始终为所有的插槽使用完整的基于 的语法:也就是简写前的方式

模块化

背景:JavaScript设计初期只是实现简单的页面交互逻辑,当时的js代码直接写在script标签里。但是随着各方面的发展,很多后端的业务逻辑交给了前端完成,比如表单验证等,特别是随着ajax的广泛应用,前端的代码量迅速增长,使得不能使用原来的方式,这时,大量的js代码放入了js文件中,通过外部引入进html中,但是也会出现一些问题,比如命名问题,数据共享等,模块化就应运而生。

什么是前端模块化

将一个复杂的程序依据一定的规范封装成多个部分(文件),每个部分的内部数据和实现都是独立的,对外暴露一部分内容供其他部分调用。

es5模块化解决方案

在es5(ECMAScript第五个版本)中,为了解决作用域的问题,很多时候我们都是通过闭包的形式。但是,使用闭包也会有它的问题,比如,一个js文件确实需要用到另一个js里的变量、函数等。不重写几乎是用不到的。因为此时每个js都是一个独立的作用域,无法相互使用。
我们会通过返回对象、再调用的方式去解决。如下。
a.js

var module1 = (function () {let obj = {}let name = '张三'obj.name = namereturn obj
})()

c.js

(function () {console.log(module1.name);
})()

此处需要注意的是module1 不能重复,每一个模块使用唯一的名称

es6模块化解决方案

到了es6(ECMAScript第六个版本),自带了模块化。只需在html引用js时添加属性type=“module”,并在js使用export和import完成。

 <script src="./a.js" type="module"></script><script src="./c.js" type="module"></script>

a.js

let name = '张三'
export {name
}

c.js

import { name } from './a.js'
console.log(name);

export不仅可以导出变量,还可以将函数、类等导出,并且还能不在最后导出,声明时就导出。如下

export function sum(num1,num2){return num1 + num2
}

联系题

1、完成如下功能。

2、加强功能,未完待续

Vue学习笔记(二)组件化和模块化相关推荐

  1. Vue学习笔记02 = 组件化

    目录 一.组件化基本概念 什么是组件化?组件化有什么作用? 人面对复杂问题的处理方式: 组件化也是类似的思想: Vue组件化思想: 组件化思想的应用: 二.组件的基本使用: 2.1.创建组件的构造器. ...

  2. Vue学习笔记_组件化

    文章目录

  3. Vue学习笔记05 组件的自定义事件-组件通信-$nextTick-脚手架解决ajax跨域-插槽-过渡动画

    文章目录 Vue学习笔记05 父组件给子组件传值 注意点 子组件给父组件传值 父组件接受子组件的传值 通过函数 组件的自定义事件 事件绑定的第一种写法 @或v-on 事件绑定的第二种写法:使用ref ...

  4. 【Vue】Vue学习笔记——UI组件库和常用插件

    文章目录 6. UI组件库和常用插件 6.1 Element-ui 6.2 Vue-router 6.2.1 基本用法 6.2.2 跳转 6.2.3 路由嵌套 6.2.4 路由参数传递 6.3 Axi ...

  5. 少侠请重新来过 - Vue学习笔记(二) - Vue生命周期

    Vue 生命周期和钩子 每一个vue实例创建时,会经历一段初始化的过程,同时会调用其生命周期钩子,实例的钩子this指向它的Vue实例,不需要在钩子用箭头函数. <template>< ...

  6. vue学习笔记(1)-组件通信

    vue.js官方教程上讲的也挺清楚的了,自己整理一遍以加深印象,同时也完成自己的项目中需要的动态创建表单提交编辑修改功能. 表单主要是v-model双向绑定实现父组件与子组件的双向数据传递,所以首先说 ...

  7. Vue学习笔记(八) 组件进阶

    1.插槽 (1)插槽内容 像 HTML 元素一样,我们常常需要给组件传递内容 比如在下面的例子中,我们给自定义组件 prompt-info 传入 出错啦 的文本 <!DOCTYPE html&g ...

  8. day4 vue 学习笔记 组件 生命周期 数据共享 数组常用方法

    系列文章目录 day1学习vue2笔记 vue指令 day2 学习vue2 笔记 过滤器 侦听器 计算属性 axios day3 vue2 学习笔记 vue组件 day4 vue 学习笔记 组件 生命 ...

  9. Vue学习笔记(2) 在html文件中创建Vue实例,并使用http-vue-loader注册单文件组件

    本篇博客基于Vue2.x 官方文档:https://cn.vuejs.org/v2/guide/instance.html 最近和同学合作一个设备信息管理的小项目,而同学找的模板不是前后端分离的 因此 ...

最新文章

  1. win合适做服务器的系统,win系统做云服务器
  2. UC浏览器代理流量解密
  3. Netty+SpringBoot+FastDFS+Html5实现聊天App
  4. 程序员修炼之道:从小工到专家读后感02
  5. SCI期刊拒稿看看什么原因?
  6. Java基础复习---线程创建
  7. 论文查重率这么高,是由什么原因造成的?
  8. python如何调用hslcommunication_C#读写PLC数据问题
  9. C语言每个语句的最后必须有一个分号,C语言选择题附答案
  10. 东营市初中计算机考试查询系统,东营市初中学业水平考试管理平台2021年东营中考成绩查询系统入口...
  11. 补丁(patch)的制作与应用
  12. MySQL根据输入的查询条件排序
  13. 十年经验教你如何学习嵌入式系统
  14. Android应用内加载pdf 使用pdf.js
  15. 全国高校计算机能力挑战赛试题,2019年全国高校计算机能力挑战赛 C语言程序设计决赛(示例代码)...
  16. SDK是什么?与API有什么关系?
  17. first-order-model学习笔记(二):运行参数
  18. 深圳09年各行薪水大全
  19. 解决Ubuntu和Windows不能相互复制粘贴的问题
  20. Python OpenCV 彩色图像与灰度图像的转换

热门文章

  1. 【计算机毕业文章】中小连锁零食企业进销存管理系统的设计与实现
  2. 如何设置Adobe Acrobat DC为pdf的默认打开方式
  3. KS检验学习[转载]
  4. Java 泛型中的 PECS 原则
  5. 显卡、显卡驱动版本、cuda版本和Pytorch相互之间的依赖关系
  6. C++ decltype类型推导完全攻略
  7. linux远程开发——使用vs2019远程连接linux
  8. PHP之在朗沃最后一段感想
  9. day23面向对象小案例
  10. 论文翻译一:A Faster Maximum-Likelihood Modulation Classification in Flat Fading Non-Gaussian Channels