一、模块化与组件化

  • 模块化的定义

模块化在Node中是一个规范,定义一些模块的相关的规则,从代码角度上来说,方便做区别,如果不使用模块化,写在js文件中不利于后期维护和扩展,从代码的层面上就把相关的功能脱离出来,所以模块化从从代码的角度触发,分析项目,把项目中一些功能类型的代码,单独抽离为一个个的模块,那么为了保证大家以相同的方式去封装模块,于是我们就创造了CommentJS规范

  • 模块化的优点

在我们项目中,如果需要是实现相同的功能,就不需要再重写,所以模块化从一定程度上提高我们的开发效率,有一些相关模块,直接调用就可以了,方便项目开发,和后期的维护与扩展

  • 组件化:

把页面中样式差不多的东西抽为单独的小组件,把需要经常复用的东西封装为一个单独的,今后需要用的时候直接拿就可以,不用再重写,从ui的角度触发去考虑问题,把页面中代码结构类似的区域抽离出来,封装成一个单独的小组件 ;前端的组件化,方便UI组件的重用;

  • 组件化的优点:

随着项目规模的发展,我们手中的组件会越来越多,我们今后一个页面的ui,几乎都可以从手中拿现成的组件拼接出来,方便项目的开发和维护

二、创建全局组件的方式

1. 创建全局组件的方式一

  1. 先调用 Vue.extend()得到组件的构造函数
 var com1 = Vue.extend({
template: '<h2>这是创建的第一个全局组件</h2>'
// template 属性,表示这个组件的 UI 代码解构
})
  1. 通过vue.component('组件的名称',组件的构造函数)来注册全局组件
    Vue.component('mycom1', com1)
//com1就是组件的构造函数

注意:

组件的名称如果是驼峰命名,那么引入的时候表名称得加连字符 -

1.如果 Vue.component('myCom1','com1')

对应的组件标签是

2. 如果是Vue.component('myCom1Test','com1')

对应组件标签为:

3. 如果Vue.component('my-com1','com1')

对应组件标签为:

  1. 把注册好的组件名称,以标签的形式引入到vm实例区域的页面中即可
<div id="app">
<!-- 引入全局的vue组件-->
<mycom1></mycom1>
</div>

来吧展示:

2. 创建全局组件的方式二

  1. 直接使用vue.component('组件的名称','组件对象')
// Vue.component 的第二个参数,既接收 一个 组件的构造函数, 同时,也接受 一个对象
Vue.component('mycom2', {
template:'<h2>这是直接使用 Vue.component 创建出来的组件</h2>'
})
  1. 把注册好的组件名称,以标签的形式引入到vm实例区域的页面中即可
<div id="app">
<mycom2></mycom2>
</div>

来吧展示:

注意:

1.template 属性中,不能单独放一段文本,必须用标签包裹起来;

2. 如果在 template 属性中,想要放多个元素了,那么,在这些元素外,必须有唯一的一个根元素进行包裹;

Vue.component('mycom2', {
template:'<div><p>嘿嘿嘿嘿嘿</p><h2>这是直接使用 Vue.component 创建出来的组件</h2><h1>哈哈哈哈</h1> </div>'
})

3. 创建全局组件的方式三

  1. template添加一个id选择器
Vue.component('mycom3', {
template: '#tpl'
})
  1. 定义一个 template 标签元素

    使用 Vue 提供的 template 标签,可以定义组件的UI模板解构
<div id="app">
<mycom3></mycom3>
</div>
<template id="tpl">
<h2>这是创建全局组件的第三种方式</h2>
</template>

注意:

template标签中里面也必须有唯一的一个根元素进行包裹

也就是如果没有根元素包裹,那么下面代码是执行不出来了会报错

<template id="tmpl">
<h2>这是创建全局组件的第三种方式</h2>
<p>哟哟哟哟哟哟</p>
</template>

正确写法:

<template id="tmpl">
<div>
<h2>这是创建全局组件的第三中方式</h2>
<p>嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿</p>
</div>
</template>



既然是全局组件,那么就可以重复调用,栗子:

<div id="app">
<mycom3></mycom3>
</div>
<div id="app2">
<mycom3></mycom3>
</div>
<template id="tmpl">
<h2>这是创建全局组件的第三中方式</h2>
</template>
<script>
Vue.component('mycom3', {
template: '#tmpl'
})
var vm = new Vue({
el: '#app',
});
var vm2 = new Vue({
el: '#app2',
});
</script>

三、创建私有组件

创建一个私有组件

<div id="app">
<mycom4></mycom4>
</div>
var vm = new Vue({
el: '#app',
data: {},
methods: {},
components: {
// 定义实例中私有组件的 组件的名称 和组件的 解构
'mycom4': {
template: '<h6>这是定义的私有组件</h6>'
}
}
});

创建多个私有组件:

<div id="app">
<mycom4></mycom4>
<mycom5></mycom5>
</div>
components:{
mycom4:{
template:'<h2>这是我定义的私有组件1</h2>'
},
mycom5:{
template:'<h2>这是我定义的私有组件2</h2>'
}
}

四、组件中相应数据和展示方法

 Vue.component('mycom', {
template: '<h3 @click="show">这是自定义的全局组件 ------ {{ msg }}</h3>',
data: function () { //
// 在 组件中,可以有自己的私有数据
// 但是,组件的 data 必须是一个 function
// 并且内部 return 一个 数据对象
return {
msg: '我是组件的内部data'
}
},
methods: { // 尝试定义组件的私有方法
show() {
// console.log('出发了组件的私有show方法!')
alert('我是组件内部的方法')
}
}
})

思考:

为什么要把 组件中的 data 定义为一个function呢?

因为这样做的话,每当我们在页面上引用一次组件,必然会先调用 这个 data function,

从而得到一个当前组件私有的 数据对象;

五、切换组件

1. 结合flag标识符和 v-ifv-else 实现组件的切换

<div id="app">
<!-- 使用按钮去控制显示login和res-->
<input type="button" value="显示登录" @click="flag=true"/>
<input type="button" value="显示注册" @click="flag=false"/>
<login v-if="flag"></login>
<!-- 当flag:true的时候显示login-->
<!-- 当flag:false的时候显示res-->
<res v-else="flag"></res>
</div>
<script>
Vue.component('login', {
template: '<h2>登录</h2>'
})
Vue.component('res', {
template: '<h2>注册</h2>'
})
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data:{
flag:false
},
methods:{}
})
</script>

2. 切换多个组件

<div id="app">
<!--想要显示哪个组件就在:is属性的后面传入(字符串)=====> '组件的名字'-->
<component :is="'com1'"></component>
<component :is="'com3'"></component> </div>
Vue.component('com1', {
template: '<h2>我是第1个组件</h2>'
})
Vue.component('com2', {
template: '<h2>我是第2个组件</h2>'
})
Vue.component('com3', {
template: '<h2>我是第3个组件</h2>'
})
Vue.component('com4', {
template: '<h2>我是第4个组件</h2>'
})



进行多组件的切换

<div id="app">
<!--点击a链接,修改component的值
component标签结合is属性进行组件的切换-->
<a href="#" @click="comname='com1'">显示组件1</a>
<a href="#" @click="comname='com2'">显示组件2</a>
<a href="#" @click="comname='com3'">显示组件3</a>
<a href="#" @click="comname='com4'">显示组件4</a> <component :is="comname"></component>
</div>
 var vm = new Vue({
el: '#app',
data:{
comname:'com1'
},
//当vue解析文件到component标签时,如果有:is属性就会解析后面的字符串"comname"
//然后去data中寻找这个变量
//comname:'com1'
//正好是一个字符串的变量的名称,就会显示名称叫com1的组件
methods:{}
})

3.为组件切换添加动画

 <transition>
<component :is="comname"></component>
</transition>
<style>
.v-enter,
.v-leave-to{
opacity:0;
transform: translate(100px);
}
.v-enter-active,
.v-leave-active{
transition: all 0.4s ease;
}
</style>



如上图效果显示,有标准流的影响,所以要脱离标准流的影响,让离开的组件脱离标准流

<style>
..... .v-enter-active,
.v-leave-active{
transition: all 0.4s ease;
position: absolute;
}
</style>



如图动画效果是先进入再离开,如果想要实现先离开再进入,则只需要在transition中添加mode="out-in"

 <transition mode="out-in"> -
<component :is="comname"></component>
</transition>



如果想要实现离开往左走,进入往右走的效果,则:

<style>
.v-enter {
/* 即将进入时候的坐标 */
opacity: 0;
transform: translateX(100px);
} .v-leave-to {
/* 离开时候,最终到达的位置 */
opacity: 0;
transform: translateX(-100px);
}
</style>

六、父组件通过属性绑定向子组件传递数据

  1. 把要传递给子组件的数据,作为自定义属性,通过v-bind绑定到子组件身上
 <com :sonmsg="pmsg"></com>
  1. 在子组件中,不能直接使用父组件传递过来的数据,需要先用props 来接收一下
   props: ['sonmsg']
  1. 在接收父组件传递过来的props的时候,一定要和父组件中传递过来的自定义属性名称保持一致
 template: '<h2>我是子组件-----{{sonmsg}}</h2>',

具体代码如下:

<body>
<div id="app">
<com :sonmsg="pmsg"></com>
<!-- 以属性绑定的方式将父组件中的值传递给子组件-->
<!-- 这里相当于把 '我是父组件中的数据'放在这边 也就是 msg123='我是父组件中的数据'-->
<!-- 但是如果子组件想用msg需要在子组件中定义一下-->
</div> <script>
var vm = new Vue({
el: '#app',
data: {
pmsg:'我是父组件中的数据'
},
methods: {},
components: { // 定义私有组件
'com': { // 在Vue中,默认,子组件无法直接获取父组件中的数据
template: '<h2>我是子组件-----{{sonmsg}}</h2>',
props: ['sonmsg']
// 在Vue中,只有 props 是数组,其它带 s 后缀的属性都是 对象
}
}
});
</script>
</body>

七、父组件向子组件传递对象

  1. 把要传递给子组件的对象,作为自定义属性,通过v-bind绑定到子组件身上
  <com1 :msgobj123="msgObj"></com1>
  1. 在子组件中,不能直接使用父组件传递过来的对象,需要先用props 来接收一下
 props: ['msgobj123']
  1. 在接收父组件传递过来的props的时候,一定要和父组件中传递过来的自定义属性名称保持一致
 template: '<h3>后面传递的是父组件中对象 ---- {{ JSON.stringify(msgobj123) }}</h3>'
template: '<h3>哈哈 {{ JSON.stringify(msgobj) }}</h3>',

具体代码如下:

<body>
<div id="app">
<com1 :msgobj123="msgObj"></com1>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msgObj: {
id:1,
name:'千夏Chinatsu',
age:18
}
},
methods: {},
components: {
'com1': {
template: '<h3>后面传递的是父组件中对象 ---- {{ JSON.stringify(msgobj123) }}</h3>',
props: ['msgobj123']
}
}
});
</script>
</body>

八、父组件向子组件传递方法

  1. 把要传递给子组件的方法,通过v-on绑定事件到子组件身上
<com v-on:func="show()"></com>
  1. 在子组件中,不能直接使用父组件传递过来的方法,需要先用$emit() 来接收一下
  this.$emit('func')
  1. 在接收父组件传递过来的$emit()中,一定要和父组件中传递过来的方法名称保持一致

具体代码:

<body>
<div id="app">
<com v-on:func="show()"></com>
</div> <script>
var vm = new Vue({
el:'#app',
data:{},
methods:{
show(){
console.log('触发了父组件中的show()方法')
}
},
components: {
'com': {
template: '<input type="button" value="这是子组件的按钮" @click="btnClick()"/>',
methods:{
btnClick(){
// console.log('hhhh')
this.$emit('func')
}
} }
}
})
</script>
</body>

总结:

1.如果要向子组件传递 data 中的数据,则 使用 属性绑定的形式 v-bind:

2. 如果要向子组件传递 methods 中的 方法,则 使用 事件绑定的形式 v-on:

九、子组件向父组件传递数据

<body>
<div id="app">
<!-- 方式一:-->
<com v-on:func="show"></com>
<!-- $emit('func',1)后面要传递参数-->
<!-- 方式二:-->
<!-- <com v-on:func="show(2)"></com>-->
<!-- 然后$emit('func')后面就不用传递参数-->
</div>
<script>
var vm = new Vue({
el:'#app',
data:{},
methods:{
show(arg){
console.log('触发了父组件中的show()方法' + arg)
// '--------'
}
},
components: {
'com': {
template: '<input type="button" value="这是子组件的按钮" @click="btnClick()"/>',
data:function(){
return{
sonmsg:'这是子组件中的数据'
}
},
methods:{
btnClick(){
this.$emit('func','嘿嘿嘿嘿嘿')
}
} }
}
})
</script>
</body>



所以可以直接在show()方法中传入子组件中的data数据

methods:{
show(arg){
console.log('触发了父组件中的show()方法' +'--------'+ arg)
// '--------'
}
},
components: {
'com': {
template: '<input type="button" value="这是子组件的按钮" @click="btnClick()"/>',
data:function(){
return{
sonmsg:'这是子组件中的数据'
}
},
methods:{
btnClick(){
// console.log('hhhh')
this.$emit('func','嘿嘿嘿嘿嘿')
// this.$emit('func',this.sonmsg)
}
} }
}



把子组件传递过来的数据,保存到 父组件的 data 中

methods: {
show(arg) {
// console.log('触发了父组件中的show()方法' +'--------'+ arg)
// 把子组件传递过来的数据,保存到 父组件的 data 中
this.msgFormSon = arg
console.log(this.msgFormSon)
}
},

总结:

子组件向父组件传值,本质上,还是调用了父组件传递过来的方法

只不过,子组件在调用的时候,把 数据 当作参数,传给这个方法了;

十、练习列表案例(结合父子组件传值)

<body>
<div id="app">
<!-- 评论框区域 -->
<cmt-box @func="addNewCmt"></cmt-box>
<ul>
<cmt-item v-for="(item, i) in list" :item="item" :key="i"></cmt-item>
</ul>
</div>
<script> Vue.component('cmt-item', {
template: `<li>
<h3>评论人:{{ item.name }}</h3>
<h5>评论内容:{{ item.content }}</h5>
</li>`,
props: ['item']
}) Vue.component('cmt-box', {
template: `<div>
<label>评论人:</label>
<br>
<input type="text" v-model="name">
<br>
<label>评论内容:</label>
<br>
<textarea v-model="content"></textarea>
<br>
<input type="button" value="发表评论" @click="postComment">
</div>`,
data: function () {
return {
name: '',
content: ''
}
},
methods: {
postComment() { // 发表评论
// console.log('ok')
const cmt = { name: this.name, content: this.content }
// 子组件中,调用父组件传递过来的方法,然后可以把 子组件的数据,当作参数,传递给父组件的方法去使用
this.$emit('func', cmt)
this.name = this.content = ''
// console.log(cmt)
}
}
})
var vm = new Vue({
el: '#app',
data: {
list: [
{ name: 'zs', content: '沙发' },
{ name: 'ls', content: '板凳' },
{ name: 'qqq', content: '凉席' },
{ name: 'eee', content: '砖头' }
]
},
methods: {
addNewCmt(cmt) { // 添加新评论
// console.log(cmt)
this.list.push(cmt)
}
}
});
</script>
</body>

十一、使用rel属性来获取页面中的元素

<body>

<div id="app">
<input value="按钮" type="button" @click="show()"/>
<!--<h2 id="myh2">{{msg}}</h2>-->
<!--加入ref属性-->
<h2 id="myh2" ref="hhh">{{msg}}</h2>
</div> <script>
var vm = new Vue({
el:'#app',
data:{
msg:'嘿嘿嘿嘿嘿'
},
methods:{
show(){
//原生想要获取h2中的数据的方法
// var res = document.getElementById('myh2').innerHTML
//console.log(res)
console.log(this)
console.log(this.$refs.hhh)
console.log(this.$refs.hhh.innerHTML) }
}
}) </script>
</body>

在h2标签中没有加入ref属性的打印console.log(this)结果



在h2标签加入ref属性的打印console.log(this)结果



所以可以通过rel可以很方便的来获取元素

 console.log(this)
console.log(this.$refs.hhh)
console.log(this.$refs.hhh.innerHTML)

十二、使用rel属性来获取页面中的组件





所以可以根据msg去修改组件内部的数据或者调用子组件中的方法

<body>

<div id="app">
<input value="按钮" type="button" @click="getCom()" />
<com1 ref="xxxxx"></com1> </div>
<script>
Vue.component('com1', {
template:'<h2>这是一个小组件---{{msg}}</h2>',
data:function () {
return {
msg:'这是组件内部数据'
}
},
methods:{
show(){
console.log('子组件中的方法被调用了')
}
}
})
var vm = new Vue({
el:'#app',
data:{
msg:'这是父组件的数据'
},
methods:{
getCom(){
// console.log(this)
this.$refs.xxxxx.msg = '组件内部数据被修改了'
this.$refs.xxxxx.show()
} }
})
//页面上可以为很多元素创建ref的引用 </script>
</body>

十三、在vue组件中data和props的区别

  • data 在组件中,要被定义成一个function,并且要返回一个对象
  • props 在组件中,要被定义成数组,其中,数组的值都是字符串名,表示从父组件传递过来的数据
  • props中的数据,不要直接拿来修改,如果想要修改,必须在data上重新定义一个属性,然后把属性的值从this.props直接拿过来
  • data 上的数据,都是组件自己私有的,数据都是可读可写的
  • props 都是外界传递过来的数据,数据只能读取,不能重新写入

vue学习笔记(六) ----- vue组件的更多相关文章

  1. vue学习笔记(六)表单输入绑定

    前言 在上一章vue学习笔记(四)事件处理器这一篇博客的内容中,我们已经了解vue是如何绑定事件的,而本篇博客主要讲解的是vue中表单输入的绑定,通常我们自己提交信息的时候都是通过表单将信息到服务器的 ...

  2. Vue学习笔记之Vue组件

    0x00 前言 vue的核心基础就是组件的使用,玩好了组件才能将前面学的基础更好的运用起来.组件的使用更使我们的项目解耦合.更加符合vue的设计思想MVVM. 那接下来就跟我看一下如何在一个Vue实例 ...

  3. 【Vue学习笔记】—— vue的基础语法 { }

    学习笔记 作者:oMing vue v-on: 简称 @ <div id='app'> <button v-on:click='Show1'> </button> ...

  4. vue学习笔记(二)vue的生命周期和钩子函数

    前言 通过上一章的学习,我们已经初步的了解了vue到底是什么东西,可以干什么,而这一篇博客主要介绍vue的生命周期和它常用的钩子函数,如果有学过java的园友可能有接触到在学习servlet的时候学过 ...

  5. vue学习笔记:vue的认识与特点与获取

    Vue了解 Vue:读作 view Vue是一个渐进式框架 与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计. Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整 ...

  6. Vue学习笔记六:v-model 数据双向绑定

    目录 v-model简介和适用范围 新建HTML 所见即所得 v-model模拟简易计算器 v-model简介和适用范围 Vue的一大特点之一就是数据的双向绑定,v-model就是实现这个功能的指令, ...

  7. vue学习笔记—bootstrap+vue用户管理

    vue,读音view,简单易用的前端框架.特点如下: 1.一个mvvm的前端框架,内部做好了html中dom对象和后台用js语言定义的变量的双向绑定 2.中国人尤雨溪维护的个人项目,中文资料多,和go ...

  8. Vue学习笔记之Vue指令系统介绍

    所谓指令系统,大家可以联想咱们的cmd命令行工具,只要我输入一条正确的指令,系统就开始干活了. 在vue中,指令系统,设置一些命令之后,来操作我们的数据属性,并展示到我们的DOM上. OK,接下来我们 ...

  9. Vue学习笔记之Vue学习前的准备工作

    0x00 起步 1.扎实的HTML/CSS/Javascript基本功,这是前置条件. 2.不要用任何的构建项目工具,只用最简单的<script>,把教程里的例子模仿一遍,理解用法.不推荐 ...

  10. VUE学习笔记之vue cli 构建项目

    一.环境搭建: 1.安装node.js 从node.js官网下载并安装node,安装过程很简单,一路"下一步"就可以了.安装完成之后,打开命令行工具(win+r,然后输入cmd), ...

随机推荐

  1. springboot:This application has no explicit mapping for /erro

    springboot启动没有报错,但是访问的时候返回如上图的错误.看报错内容感觉是没有这个mapping对应的接口.但是确实写了. 最终发现是因为springboot的启动类放的位置不对.启动类所在的 ...

  2. 目标检测算法(一):R-CNN详解

    参考博文:https://blog.csdn.net/hjimce/article/details/50187029 R-CNN(Regions with CNN features)--2014年提出 ...

  3. CentOS7 【linux系统】配置 JDK 教程

    1. 下载 [linux版本] JDK 1.8 的包. 2. 导入linux系统里面. 如何导入,下载一个winSCP 软件 破解安装,然后再linux 系统里面 查询IP,连接即可. 在linux解 ...

  4. Centos-网络下载文件-wget

    wget 指定URL从网络上下载某个文件,需要网络连接 相关选项 -nc 不覆盖同名文件 -q    安静下载,无输出 -v    显示下载详情 -O   指定保存目录或重命名下载文件名 -c 断点续 ...

  5. Windows控件的属性与事件

    Treeview控件重要属性和事件 属性 说明 Nodes Treeview控件中所有树节点 SelectdNode 当前Treeview控件中选定的树节点,如果当前没有选定树节点,返回值为null ...

  6. 015 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 09 Unicode编码

    015 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 09 Unicode编码 本文知识点:Unicode编码以及字符如何表示? ASCII码是美国提出的标准信息 ...

  7. weblogic 安装+部署(一)

    昨天刚接触weblogic,在windows下搭建了一个weblogic,没什么技术,留个笔记. 1.首先要有jdk,添加环境变量这个没什么好说的. 2.下载weblogic:可以去官网下:http: ...

  8. C++中头文件简介(stdio.h & chrono)

    参考: 1. https://baike.baidu.com/item/stdio.h 2. https://www.cnblogs.com/jwk000/p/3560086.html 1. stdi ...

  9. IDEA设置External Tools之Javap反编译字节码

    通过Jdk的命令javap可以反编译查看字节码,但是在使用idea的时候一直用命令行去操作不太好操作,而且因为idea会把class码 放在target里面,经常会忘记切换目录.这个时候idea的Ex ...

  10. RHSA-2019:0201-低危: systemd 安全更新

    [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...