★组件-概念
概念:
JS模块:对一个逻辑的封装,说白了就是一个js文件(模块)
vue组件:把网页分成若干块,针对界面功能的封装,一个组件包含(HTML,CSS,JS)
vue组件也是一个vue实例,在定义组件的时候可以使用
vue的配置选项
,例如你可以使用 data method ... 这样的配置选项,有一个选项不能使用el
优点:
- 组件与组件之间是相互独立的,拥有自己的数据data、函数methods...,可维护性提高。
- 可复用
★组件-全局注册
全局注册的意思:在任何vue实例下都可以使用。
具体语法:
定义
Vue.component(组件名称,组件配置对象)
组件配置对象 和 vue实例配置对象 是几乎一样,没有el选项。
template选项,声明组件结构的(组件自己的模板)。有且只有一个根标签。必须有这个选项
data选项,必须指定一个函数,函数的返回对象是用来声明数据的。
使用组件:
- 在vue实例管理的视图中#app,把 组件名字 当中一个标签来使用,组件的名字不能用原生的标签来命名。
- 例如:div span a article footer header section ... 原生标签。
演示代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app">
<btn-add></btn-add>
</div>
<hr>
<div id="app2">
<btn-add></btn-add>
</div>
<script src="./vue.js"></script>
<script>
// 全局注册
Vue.component('btn-add',{
// 这是一个字符串,模板字符的原因是:可换html的结构清晰些
// 细节:需要有且只有一个根标签
template: `<div>
结果:{{count}}
<button @click="add()">累加</button>
</div>`,
// 在组件中data必须是一个函数,返回的对象中来声明数据
data () {
return {
count: 0
}
},
methods: {
add () {
this.count ++
}
}
})
const vm = new Vue({
el: '#app',
})
const vm2 = new Vue({
el: '#app2',
})
</script>
</body>
</html>
★组件-局部注册
局部注册的意思:仅仅在注册组件的当前vue实例管理的视图中才可以使用。
具体语法:
语法:
new Vue({ components:{组件的名字:组件配置对象} })
组件配置对象 和 vue实例配置对象 是几乎一样,没有el选项。
template选项,声明组件结构的(组件自己的模板)。有且只有一个根标签。必须有这个选项
data选项,必须指定一个函数,函数的返回对象是用来声明数据的。
使用组件:
- 在vue实例管理的视图中#app,把 组件名字 当中一个标签来使用,组件的名字不能用原生的标签来命名。
- 例如:div span a article footer header section ... 原生标签。
演示代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app">
<btn-add></btn-add>
</div>
<div id="app2">
<btn-add></btn-add>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
// 局部注册组件
components: {
'btn-add': {
template: '<div>结果:{{count}} <button @click="add()">累加</button></div>',
data () {
return {
count: 0
}
},
methods: {
add () {
this.count ++
}
}
}
}
})
const vm2 = new Vue({
el: '#app2'
})
</script>
</body>
</html>
★组件-组件嵌套
演示代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<!-- <div id="app">
<com-parent></com-parent>
</div>
<script src="./vue.js"></script>
<script>
// 嵌套:在父组件中使用子组件
Vue.component('com-parent',{
template: '<div>我是父组件 <com-child></com-child></div>'
})
Vue.component('com-child',{
template: '<div>我是子组件</div>'
})
const vm = new Vue({
el: '#app',
})
</script> -->
<div id="app">
<com-parent></com-parent>
</div>
<script src="./vue.js"></script>
<script>
// 嵌套:在父组件中使用子组件
// 局部:局部定义的组件仅仅只能在当前注册的vue实例管理的模板(视图)中使用。
const vm = new Vue({
el: '#app',
components: {
'com-parent': {
template: '<div>我是父组件 <com-child></com-child></div>',
components: {
'com-child': {
template: '<div>我是子组件</div>'
},
}
}
}
})
</script>
</body>
</html>
注意:局部定义的组件仅仅只能在当前注册的vue实例管理的模板(视图)中使用。
08-★★组件-组件传值
组件特点:组件与组件之间是相互独立的,数据也是相互独立的,但是组件与组件之间不可避免的要进行数据通信。
组件与组件之间的关系不同,传值的方式也不同。分为三种关系:
- 父组件传值给子组件
- 子组件传值给父组件
- 非父子传值 (后面项目中讲解)
父传子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app">
<com-parent></com-parent>
</div>
<script src="./vue.js"></script>
<script>
Vue.component('com-parent',{
template: '<div>我是父组件 {{msg}}<com-child abc="abc属性值" :message="msg"></com-child></div>',
data () {
return {
msg: '父组件的数据com-parent'
}
}
})
// 把父组件的msg数据传递给子组件在来使用
Vue.component('com-child',{
template: '<div>我是子组件 {{abc}} {{message}} <button @click="update()">改props</button></div>',
// 接收使用组件的时候,添加的属性数据
// 接收 abc 属性数据,abc可以像data中的数据一样使用
// 通过props接收的数据,特点:仅读(只可以访问,不可以修改)
// 数据传递值单向的,这种方式是能:父传子
props: ['abc','message'],
methods: {
update () {
this.message = 'xxx'
}
}
})
const vm = new Vue({
el: '#app',
})
</script>
</body>
</html>
总结:
- 使用子组件的时候写属性
:message="父组件数据"
- 定义子组件的时候写props配置选项
props:['message']
子传父
- 铺垫知识:组件的自定义事件(绑定,触发)
- 原生事件 dom元素|标签能支持的事件
- 自定义事件 给组件添加的事件,需要通过代码才能触发。
<!-- 此处的input是com-a组件的自定义事件绑定 -->
<com-a @input="fn"></com-a>
// 触发组件的自定义事件 vue实例提供$emit是用来触发自定义事件的函数
组件实例.$emit('input')
jquery的自定义事件的绑定和触发
- 通过自定义事件的绑定和触发可以实现,子组件传值给父组件。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app">
<com-parent></com-parent>
</div>
<script src="./vue.js"></script>
<script>
Vue.component('com-parent', {
template: '<div>我是父组件 {{msg}} <com-child @childToParent="fn($event)" ></com-child></div>',
data () {
return {
msg: ''
}
},
methods: {
// fn 是自定义事件的处理函数
// 这里会有一个默认的传参 $event 此时:触发自定义事件的传参
fn (e) {
console.log(e)
console.log('自定义事件触发了')
this.msg = e
}
}
})
// 值组件的数据传递给父组件使用
Vue.component('com-child', {
template: '<div>我是子组件 <button @click="fn2">触发子传父</button></div>',
data () {
return {
msg: '子组件数据com-child'
}
},
methods: {
fn2 () {
// 点击按钮的时候
// 触发自定义事件
// 第一个参数:自定义事件的名称
// 第二个参数:传递的数据
this.$emit('childToParent', this.msg)
}
}
})
const vm = new Vue({
el: '#app'
})
</script>
</body>
</html>
画图分析:
总结:
- 使用子组件的时候,绑定自定义事件
- 在子组件内部,通过 $emit 触发自定义事件,此时可以传参
- 当你触发自定义事件的时候,在事件函数中 $event 就是触发自定义事件时候的传参。
★vue-router-使用步骤
vue-router是一个基于vue的插件,实现前端路由功能的,在基于vue的项目当中使用。
文档地址: https://router.vuejs.org/zh/
下载地址:https://unpkg.com/vue-router/dist/vue-router.js
使用步骤:
- 引入,vue.js的下面。
<script src="./vue.js"></script>
<script src="./vue-router.js"></script>
- vue-router控制的是 (地址------>组件),所以是先准备组件。
- vue-router实现的是 不同的地址对应不同的组件。
// 组件配置对象
const Home = {template:'<b>首页界面</b>'}
const My = {template:'<b>我的音乐界面</b>'}
const Friend = {template:'<b>朋友界面</b>'}
- 定义路由规则(什么地址------>什么组件)
// routes路由规则配置
const routes = [
// path:路径 component:组件 固定写法
{path: '/', component: Home},
{path: '/my', component: My},
{path: '/friend', component: Friend}
]
- 初始化vue-router这个插插件,使用路由规则。
// 引入插件后 全局变量 VueRouter 构造函数
// router路由实例
const router = new VueRouter({
// 路由插件配置对象
// routes 配置选项作用是:指定路由规则
routes
})
- 把实例好的router对象,挂载到vue的根实例(#app的vue实例)中,才能vue+vue-router配合使用。
// 其实所有的组件都是在#app容器下显示渲染的
// 所以也可以把#app容器称为根容器,管理这个容器的vue实例,称为:根vue实例
new Vue({
el: '#app',
// router 选项:配置路由实例
router
})
- 使用 router-link 来当跳转连接 (默认解析成a标签)
<!-- 顶部导航 -->
<nav>
<router-link to="/">首页</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>
</nav>
- 使用 router-view的指定路由对应的组件显示的位置
<div id="page">
<!-- 显示路由对应的组件 -->
<router-view></router-view>
</div>
案例代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<div id="app">
<nav>
<!-- 第六步 使用router-link来声明连接 -->
<router-link to="/">首页</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>
</nav>
<div id="page">
<!-- 第七步 使用router-view指定渲染组件的位置 -->
<router-view></router-view>
</div>
</div>
<script src="./vue.js"></script>
<!-- 第一步 引入-->
<script src="./vue-router.js"></script>
<script>
// 第二步 组件配置对象
const Home = {template:'<b>首页界面</b>'}
const My = {template:'<b>我的音乐界面</b>'}
const Friend = {template:'<b>朋友界面</b>'}
// 第三步 定义路由规则
const routes = [
{path: '/', component: Home},
{path: '/my', component: My},
{path: '/friend', component: Friend}
]
// 第四步 初始化 vue-router
const router = new VueRouter({ routes })
const vm = new Vue({
el: '#app',
// 第五步 挂载router到vue根实例下
router
})
</script>
</body>
</html>