1.组件化

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
在vue里,所有的vue实例都是组件。

(1)全局组件

我们通过Vue的component方法来定义一个全局组件。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//子组件
// 定义全局组件,两个参数:1,组件名称。2,组件参数
Vue.component("counter",{
template:'<button v-on:click="count++">你点了我 {{ count }} 次,我记住了.</button>',
data(){
return {
count:0
}
}
}) //父组件
var app = new Vue({
el:"#app"
})
</script>
</html>
  • 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等

  • 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。

  • 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板

  • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了。

  • data必须是一个函数,不再是一个对象。

效果图:

(2)组件的复用

<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>

效果:

(3)局部组件

一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。
因此,对于一些并不频繁使用的组件,我们会采用局部注册。
我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter1></counter1>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//局部组件
const counter = {
template:'<button v-on:click="count++">你点了我 {{ count }} 次,我记住了.</button>',
data(){
return {
count:0
}
}
}; //父组件
var app = new Vue({
el:"#app",
components:{
counter1:counter // 将定义的对象注册为组件
}
})
</script>
</html>
  • components就是当前vue对象子组件集合。

    • 其key就是子组件名称

    • 其值就是组件对象名

  • 效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用

(4)组件通信

通常一个单页应用会以一棵嵌套的组件树的形式来组织:

  • 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分

  • 左侧内容区又分为上下两个组件

  • 右侧边栏中又包含了3个子组件

各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。

<1>props(父向子传递)

  1. 父组件使用子组件时,自定义属性(属性名任意,属性值为要传递的数据)

  2. 子组件通过props接收父组件数据,通过自定义属性的属性名

父组件使用子组件,并自定义了title属性:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>打个招呼:</h1>
<!--使用子组件,同时传递title属性-->
<introduce title="大家好,我是lucky"/>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//子组件
Vue.component("introduce",{
// 直接使用props接收到的属性来渲染页面
template:'<h1>{{title}}</h1>',
props:['title'] // 通过props来接收一个父组件传递的属性
}) //父组件
var app = new Vue({
el:"#app",
})
</script>
</html>

效果:

<2>子向父的通信:$emit

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--使用子组件-->
<h2>num: {{num}}</h2>
<!--通过v-on指令(简写为@)将父组件的函数绑定到子组件counter上-->
<counter :count="num" @inc="increment" @dec="decrement"></counter>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//子组件counter
Vue.component("counter", {
template:'\
<div>\
<button @click="plus">加</button> \
<button @click="reduce">减</button> \
</div>',
props:['count'],
//vue提供了一个内置的this.$emit()函数,用来调用父组件绑定的函数
methods:{
plus(){
this.$emit("inc");
},
reduce(){
this.$emit("dec");
}
}
}) //父组件
var app = new Vue({
el:"#app",
data:{
num:0
},
methods:{ // 父组件中定义操作num的方法
increment(){
this.num++;
},
decrement(){
this.num--;
}
}
})
</script>
</html>

效果图:

2.路由vue-router

(1)场景模拟

现在我们来实现这样一个功能:

一个页面,包含登录和注册,点击不同按钮,实现登录和注册页切换:

<1>编写父组件

为了让接下来的功能比较清晰,我们先新建一个文件夹:src

然后新建一个HTML文件,作为入口:index.html

然后编写页面的基本结构:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<span>登录</span>
<span>注册</span>
<hr/>
<div>
登录页/注册页
</div>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app"
})
</script>
</html>

样式:

<2>编写登录及注册组件

接下来我们来实现登录组件,以前我们都是写在一个文件中,但是为了复用性,开发中都会把组件放入独立的JS文件中,我们新建一个user目录以及login.js及register.js

编写组件,这里我们只写模板,不写功能。

login.js内容如下:

const loginForm = {
template:'\
<div>\
<h2>登录页</h2> \
用户名:<input type="text"><br/>\
密码:<input type="password"><br/>\
</div>\
'
}

register.js内容:

const registerForm = {
template:'\
<div>\
<h2>注册页</h2> \
用&ensp;户&ensp;名:<input type="text"><br/>\
密&emsp;&emsp;码:<input type="password"><br/>\
确认密码:<input type="password"><br/>\
</div>\
'
}

(2)vue-router简介和安装

使用vue-router和vue可以非常方便的实现 复杂单页应用的动态路由功能。

官网:https://router.vuejs.org/zh-cn/

使用npm安装:npm install vue-router --save

在index.html中引入依赖:

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

示例:

新建vue-router对象,并且指定路由规则:

// 创建VueRouter对象
const router = new VueRouter({
routes:[ // 编写路由规则
{
path:"/login", // 请求路径,以“/”开头
component:loginForm // 组件名称
},
{
path:"/register",
component:registerForm
}
]
})
  • 创建VueRouter对象,并指定路由参数

  • routes:路由规则的数组,可以指定多个对象,每个对象是一条路由规则,包含以下属性:

    • path:路由的路径

    • component:组件名称

页面跳转控制:

<!--页面跳转控制:-->
<div id="app">
<!--router-link来指定跳转的路径-->
<span><router-link to="/login">登录</router-link></span>
<span><router-link to="/register">注册</router-link></span>
<hr/>
<div>
<!--vue-router的锚点-->
<router-view></router-view>
</div>
</div>
  • 通过<router-view>来指定一个锚点,当路由的路径匹配时,vue-router会自动把对应组件放到锚点位置进行渲染

  • 通过<router-link>指定一个跳转链接,当点击时,会触发vue-router的路由功能,路径中的hash值会随之改变

总体页面:index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--页面跳转控制:-->
<div id="app">
<!--router-link来指定跳转的路径-->
<span><router-link to="/login">登录</router-link></span>
<span><router-link to="/register">注册</router-link></span>
<hr/>
<!--指定组件添加的位置-->
<div>
<!--vue-router的锚点-->
<router-view></router-view>
</div>
</div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script src="user/login.js"></script>
<script src="user/register.js"></script>
<script type="text/javascript">
// 创建VueRouter对象
const router = new VueRouter({
routes:[ // 编写路由规则
{
path:"/login", // 请求路径,以“/”开头
component:loginForm // 组件名称
},
{
path:"/register",
component:registerForm
}
]
}) //在父组件中引入router对象:
var vm = new Vue({
el:"#app",
router // 引用上面定义的router对象
}) </script>
</html>

效果图:

014 Vue学习笔记2的更多相关文章

  1. 014 Vue学习笔记1----Vue及Node、NPM

    1.前端开发模式的发展过程 (1)静态页面 最初的网页以HTML为主,是纯静态的网页.网页是只读的,信息流只能从服务端到客户端单向流通.开发人员也只关心页面的样式和内容即可. (2)异步刷新,操作DO ...

  2. Vue学习笔记-2

    前言 本文非vue教程,仅为学习vue过程中的个人理解与笔记,有说的不正确的地方欢迎指正讨论 1.computed计算属性函数中不能使用vm变量 在计算属性的函数中,不能使用Vue构造函数返回的vm变 ...

  3. Vue学习笔记-1

    前言 本文不是Vue.js的教程,只是一边看官网Vue的教程文档一边记录并总结学习过程中遇到的一些问题和思考的笔记. 1.vue和avalon一样,都不支持VM初始时不存在的属性 而在Angular里 ...

  4. vue 学习笔记(二)

    最近公司赶项目,一直也没时间看 vue,之前看下的都快忘得差不多了.哈哈哈,来一起回顾一下vue 学习笔记(一)后,继续向下看嘛. #表单输入绑定 基础用法 v-model 会忽略所有表单元素的 va ...

  5. vue学习笔记之:为何data是一个方法

    vue学习笔记之:为何data是一个方法 在vue开发中,我们可以发现,data中的属性值是在function中return出来的.可为何data必须是一个函数呢?我们先看官方的解释: 当一个组件被定 ...

  6. vue学习笔记(八)组件校验&通信

    前言 在上一章博客的内容中vue学习笔记(七)组件我们初步的认识了组件,并学会了如何定义局部组件和全局组件,上一篇内容仅仅只是对组件一个简单的入门,并没有深入的了解组件当中的其它机制,本篇博客将会带大 ...

  7. vue学习笔记(九)vue-cli中的组件通信

    前言 在上一篇博客vue学习笔记(八)组件校验&通信中,我们学会了vue中组件的校验和父组件向子组件传递信息以及子组件通知父组件(父子组件通信),上一篇博客也提到那是对组件内容的刚刚开始,而本 ...

  8. vue学习笔记(十)路由

    前言 在上一篇博客vue学习笔记(九)vue-cli中的组件通信内容中,我们学习组件通信的相关内容和进行了一些组件通信的小练习,相信大家已经掌握了vue-cli中的组件通信,而本篇博客将会带你更上一层 ...

  9. AntDesign vue学习笔记(七)Form 读写与图片上传

    AntDesign Form使用布局相比传统Jquery有点繁琐 (一)先读写一个简单的input为例 <a-form :form="form" layout="v ...

随机推荐

  1. 【spring】spring retry介绍

    一.为什么需要重试? 我们知道只要是网络请求都有失败的情况,这个时候增加retry机制是必要的.而spring全家桶中就有这么一套机制. 二.spring retry spring系列的spring ...

  2. redis的两种持久化方案

    前言 人生在于折腾系列,网络,多线程等系列博客楼主还在继续折腾也不会放弃.缓存的知识其实并不仅仅在于简单的增删改查,我觉得有必要全面深入的学习一波.记录学习的过程与体悟. RDB 什么是RDB 对re ...

  3. 编译OpenCV提示opencv_contrib缺少boostdesc_bgm.i等文件

    错误提示: ~/opencv_contrib/modules/xfeatures2d/src/boostdesc.:: fatal error: boostdesc_bgm.i: No such fi ...

  4. Gin-Go学习笔记一:Hello World

    Hello World 1>     Gin是一个golang的微框架,封装比较优雅,API友好.具有快速灵活,容错方便等特点.Gin自身的net/http足够简单,性能也非常不错. 2> ...

  5. ApiPost(中文版postman)如何发送一个随机数或者时间戳?

    什么是ApiPost内建变量:ApiPost提供了5个内建变量,如下: {{$guid}} //生成GUID {{$timestamp}} //当前时间戳 {{$microTimestamp}} // ...

  6. JavaScript中的类方法、对象方法、原型方法

    类方法:也叫函数方法,在JavaScript中函数也是一个对象,所以可以为函数添加属性以及方法: 对象方法:包括构造函数中的方法以及其原型上面的方法: 原型方法:一般用于对象实例共享,在原型上面添加该 ...

  7. 【转载】Gradle学习 第一章:引言

    转载地址:http://ask.android-studio.org/?/article/7 We would like to introduce Gradle to you, a build sys ...

  8. How to decode a H.264 frame on iOS by hardware decoding?

    来源:http://stackoverflow.com/questions/25197169/how-to-decode-a-h-264-frame-on-ios-by-hardware-decodi ...

  9. 第一篇 Scrum 冲刺博客

    一.各个成员在 Alpha 阶段认领的任务 姓名 Alpha 阶段认领的任务 林剑峰 用户信息页面:完成用户信息的上传 石竞贤 发布信息页面:完成用户图片上传云存储的功能,并且把发布信息上传到云数据库 ...

  10. Node.js官方文档:到底什么是阻塞(Blocking)与非阻塞(Non-Blocking)?

    译者按: Node.js文档阅读系列之一. 原文: Overview of Blocking vs Non-Blocking 译者: Fundebug 为了保证可读性,本文采用意译而非直译. 这篇博客 ...