组件间的通信
- 父组件向子组件传值
父组件向子组件传值时通过prop,所有的prop都使得其父子prop之间形成一个单向下行绑定:
父级prop的更新会向下流动到子组件中,但是反过来则不行。这样可以防止从子组件意外变更父级组件的状态,从而导致应用的数据流向难以理解。
1.定义一个子组件,并且用props来接收父组件传过来的数据
2.定义一个父组件,并且将子组件注册,在template里面使用子组件
具体可以回头复习props的知识点
- 子组件向父组件传值
子组件通过发射事件$.emit(‘xxx’)给父组件,通知父组件数据改变,父组件通过@xxx监听
1.同样是创建好父、子组件
2.在子组件中自定义事件子组件通过发射事件$.emit(‘xxx’)给父组件
3.在父组件中使用从子组件中传递过来的自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>子组件向父组件传值</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<parent></parent>
</div>
</body>
<script>
// 1.定义一个子组件
const child=Vue.extend({
template:`
<div>
<h2>我是一个子组件{{name}}</h2>
<span @click='showChild'>点击触发父组件里的方法</span>
</div>
`,
props:['name'],
methods: {
showChild(){
console.log('我是子组件里的方法');
// 2.自定义事件,子组件通过发射事件$.emit('xxx')给父组件
this.$emit('showParent')
}
},
});
// 3.定义一个父组件
const parent=Vue.extend({
template:
`
//使用从子组件传递过来的自定义事件
<child @showParent='showHandler' name='child'></child>
`,
// 4.注册子组件
components:{
child
},
methods: {
showHandler(){
console.log("我是父组件里的方法");
// alert('999')
}
},
});
new Vue({
el:'#root',
components:{
//在容器里注册父组件
parent
}
})
</script>
</html>
插槽
插槽的分类
默认插槽,具名插槽,作用域插槽
默认插槽
//⽗组件中:
<Category>
<div>html结构</div>
</Category>
//子组件中
<template>
<div>
<!-- 默认插槽 就是挖一个坑-->
<slot>默认插槽 </slot>
</div>
</template>
具名插槽
//子组件中
<template>
<div>
<!-- 具名插槽,具有具体名字的插槽 -->
<slot name="center">默认插槽 </slot>
<slot name="footer">默认插槽 </slot>
</div>
</template>
//父组件中使用
<category>
<template v-slot:center> 内容插槽</template>
<template v-slot:footer> 底部插槽</template>
</category>
作用域插槽
理解:数据在组件的⾃身,但根据数据⽣成的结构需要组件的使⽤者来决定(games数据在category中,但使⽤数据在App中)
将数据放置在子组件中,父组件通过作用域插槽去调用
<template>
<div class="category">
<h3>{{title}}</h3>
<!-- 作用域插槽 -->
<slot :meishi='meishi'>我是默认值...</slot>
<slot :youxi='youxi'>我是默认值...</slot>
<slot :dianying='dianying'>我是默认值...</slot>
</div>
</template>
<script>
export default {
props:['title'],
data(){
return {
meishi:['牛肉面','螺蛳粉','刀削面'],
youxi:['王者荣耀','开心消消乐','刺激战场','英雄联盟'],
dianying:['长津胡','我和我的父辈','钢铁侠','蜘蛛侠']
}
}
}
</script>
父组件中
<template>
<div id="app">
<Category title='美食分类'>
<!-- <template v-slot:center>
<img width="100%" src="https://img0.baidu.com/it/u=3739810682,396808842&fm=253&fmt=auto&app=120&f=JPEG?w=830&h=485" alt="">
</template>
<template v-slot:footer>
<span>更多美食</span>
</template> -->
<!-- 作用域 -->
<template scope='meishi'>
<ul>
<li v-for='(m,i) in meishi.meishi' :key="i">{{m}}</li>
</ul>
</template>
</Category>
<Category title='游戏分类'>
<template scope='youxi'>
<ul>
<li v-for='(y,i) in youxi.youxi' :key="i">{{y}}</li>
</ul>
</template>
</Category>
<Category title='电影分类'>
<template scope='dianying'>
<ul>
<li v-for='(y,i) in dianying.dianying' :key="i">{{y}}</li>
</ul>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category.vue'
export default {
//组件名称
name: 'App',
components: {
Category
}
}
</script>
路由
route路由 就是一组key-value的对应关系
router路由器 多个路由需要经过路由器的管理
vue-router插件库 专门用来实现SPA (单页面程序)应用
对SPA 应用的理解
- 单页面web应用
- 整个应用只有一个完整的页面
- 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
- 数据需要通过ajax请求获取
路由的理解
一个路由就是一组映射关系
key为路径,value为component用于展示页面内容
工作过程:当浏览器的路径改变时,对应的组件就会显示
基本使用
1.安装vue-router
$npm install vue-router
2.在main.js 引入vue-router 并且使用插件Vue.use(vueRouter)
// 引入vueRouter
import vueRouter from 'vue-router'
// 使用插件
Vue.use(vueRouter)
3.创建一个管理路由的文件 例如目前创建在router文件夹下的index.js文件
- 在文件中引入vue-router插件
- 并且引入components文件下的子组件
- 创建router实例对象,去管理我们的对应关系
- 最后默认导出router实例
// 引入vue-router
import vueRouter from 'vue-router'
import Home from '../components/Home'
import About from '../components/About'
// 创建router实例对象,让他去管理我们的对应关系
const router=new vueRouter({
routes:[
{
path:'/home',
component:Home
},
{
path:'/about',
component:About
},
]
});
export default router;
4.使用路由在我们的组件组长App.vue中进行组件间的切换
具体实现路由的切换是使用
<router-link to='/about'>About</router-link>
其中使用 一下标签可以指定显示位置
<router-view></router-view>
完整代码如下:
<template>
<div id="app">
<!-- <a href="#"> Home</a>
<a href="#">About</a> -->
<!-- 用于路径跳转 -->
<router-link to="/home" >Home</router-link>
<router-link to="/about"> About</router-link>
<!-- 容器 告诉vue通过路径拿到的组件放到哪里去 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "App",
};
</script>