014 Vue学习笔记2
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(父向子传递)
父组件使用子组件时,自定义属性(属性名任意,属性值为要传递的数据)
子组件通过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> \
用 户 名:<input type="text"><br/>\
密  码:<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>
效果图:
最新文章
- 浅谈redis和memcached的区别
- xp
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q19-Q20)
- C#微信公众号开发系列教程五(接收事件推送与消息排重)
- kettle作业中的js如何写日志文件
- AES 推荐文章
- 告别div,可以代替div的几个标签
- Oracle表空间管理
- Import user&#39;s Environment path into Linux cron task
- android 9Path图片的使用
- Junit技巧
- iOS两个关于对象的关键字
- memcached的安装以及php两个扩展软件安装(memcache、memcached)
- spring 动态创建数据源
- 【装逼利器效率软件】一张图问你想不想用Launchy
- JVM内存异常与常用内存参数设置总结
- 分布式-JOB(XXL-Job)
- 洛谷P1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
- 转:C#中Undo/Redo的一个简易实现
- CI框架中集成CKEditor编辑器的教程
热门文章
- Java程序员需要掌握的技能
- 操作系统与进程.md
- express和express-generator搭建web应用
- 英语dialogite红纹石dialogite菱锰矿
- 结对项目(JAVA)
- Jmeter(四十四)启动提示 Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
- jieba模块
- pptpd pptpctrl[25553]: segfault at 0 ip 00007fb6fe23ebdc sp 00007ffdef6334e8 error 4 in libc-2.17.so[7fb6fe0dd000+1c2000] pptp拨号连接失败
- 37 树莓派识别opencv-dnn
- Mongo 服务器的安装