面试:vue中组件通信的方式有哪些
父子:props+emit 插槽 $parent $children ref
兄弟:bus
爷孙:$attrs
$parent
子组件this.$parent获取父组件对象
使用this.$parent.属性/方法等
获取之后可以操作父组件对象的data、methods等
$children
父组件this.$children获取子组件数组对象,没有顺序可言,因此使用场景是该父组件只有一个子组件时使用
使用:this.$children[0].属性/方法等
获取之后可以操作子组件对象的data、methods等
ref和$refs
通过ref给子组件一个标记,然后父组件可以通过this.$refs.标记名 来获取子组件对象
<子组件标签 ref="s"
this.$refs.s.属性/方法等
$attrs
爷爷组件想要把数据传递给孙子(儿子是不能要该数据的)
父组件
<template>
<div>
<h1>Father</h1>
<Son :name="name"/>
</div>
</template>
<script>
import Son from './Son.vue'
export default {
components:{
Son
},
data(){
return{
name:"张三"
}
},
}
</script>
<style>
</style>
子组件 (只有该组件发生了改变)
<template>
<div>
<h1>Son</h1>
<hr>
<Sun v-bind="$attrs"/>
</div>
</template>
<script>
import Sun from './Sun.vue'
export default {
//儿子使用了$attrs传递给孙子后就不能使用 props:['name'],获取父亲的参数
// props:['name'],
components:{
Sun
},
data(){
return{
age:18
}
}
}
</script>
<style>
</style>
孙组件
<template>
<div>
<h1>孙子</h1>
{{name}}
</div>
</template>
<script>
export default {
props:["name"]
}
</script>
<style>
</style>
vue全家桶
所谓全家桶指的是:
基本功能 + 路由router +状态机vuex
创建vue全家桶项目:
vue create 项目名
Manually select features
(*) Babel ---转换插件
( ) TypeScript
( ) Progressive Web App (PWA) Support
(*) Router ---路由
(*) Vuex ---状态机
>(*) CSS Pre-processors --scss
Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) n
选y:代表配置成history模式 http://localhost:8080/xxxx
选n:代表配置默认hash模式 http://localhost:8080/#/xxxx
> Sass/SCSS (with dart-sass) --安装dart-sass
Less
Stylus
? Where do you prefer placing config for Babel, ESLint, etc.? ---随意
> In dedicated config files --单独配置
In package.json ---合并到 package.json 中
项目结构
src
router
index.js
store
index.js
......
路由
后端路由: 请求地址 和 后端js文件中函数的映射
前端路由: 请求地址 和 组件的映射
SPA (single page application)
单页面应用:整个vue只有一个index.html页面
特点:首次加载时就会把所有资源(组件等)都加载进内存 ,属于客户端渲染(F12 源码中是看不到节点)
弊端:第一次很慢,不利于SEO搜索引擎优化
优势:以后都是在做组件的切换,不会请求新的资源,所有切换速度快
vue的常用:后台管理网站
SSR nuxt.js --属于服务端渲染 能够把单页面应用转为多页面应用(里面的语法同vue)----》为了解决SEO优化问题
路由的单独安装
vue add router
路由的配置
src/router/index.js
目的: 配置,暴露路由对象
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//核心配置(配置组件和地址的映射)
const routes = [
]
const router = new VueRouter({
routes
})
export default router
main.js
import Vue from 'vue'
import App from './App.vue'
//如果目录中只有一个index.js文件,则引入时可以不用写完
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
//注入
router,
store,
render: h => h(App)
}).$mount('#app')
路由的模式
history模式 http://localhost:8080/xxxx
弊端:怕F2刷新,可以在配置后端服务器nginx来避免
hash模式(默认) http://localhost:8080/#/xxxx
优势:不怕刷新,就算刷新,程序访问的依然是前端
配置:router/index.js:
const router = new VueRouter({
mode:"hash|history",
routes
})
路由组件和非路由组件
非路由组件:
概念:直接通过import+components来引入并且把组件当成标签来使用特色:和地址无关,
特色:和地址无关,只要访问localhost:8080,都会渲染
路由组件:
概念:组件渲染与否和地址有关
路由的使用:
1 配置路由文件:router/index.js:
import Home from '../components/Home.vue'
import Stu from '../components/stu/Stu.vue'
const routes = [
{
path:"/home",
component:Home
},
{
path:"/stu",
component:Stu
}
]
2 在组件中配置路由出口
<router-view></router-view>
路由的跳转
标签版:
<router-link to="/stu">跳转到stu</router-link>
js版:
this.$router.push("/home")
路由的其他配置
1 重定向:
可以重新定向到一个新的地址
const routes = [
//重定向
{
path:"/",
redirect:"/home"
},
2 路由懒加载
概念:
普通情况: import Home from '../components/Home.vue'
在首次渲染页面时,就会把所有的组件全部加载到内存(第一次加载时长很长)
而路由懒加载功能就是:让指定的组件在一开始时是不会加载的,只有当跳转到对应路由时才会加载,好处:缩短首屏加载时间 坏处:切换到懒加载对应的组件时耗时更多
使用场景: 访问评率很低的组件 , 组件内容少
使用:
方式1: 直接使用
{
path:"/stu",
component:()=>import('../components/stu/Stu.vue')
},
方式2:先定义变量后使用
let Stu=()=>import('../components/stu/Stu.vue');
const routes = [
{
path:"/stu",
component:Stu
},
3 路由的别名
给路由额外起一个地址
{
path:"/home",
alias:"/home2",
component:Home
},
4 通用路由
如果路由匹配不到对应的组件,可以进入指定的组件
{
path:"*",
component:My404
},
5 子路由(路由的嵌套)
{
path:"/stu",
component:Stu,
children:[
{
path:"stuList",
component:StuList
},
{
path:"stuAdd",
component:StuAdd
},
]
},
口诀:
如果父路由下配置了子路由,则应该在父路由对应的组件下编辑子路由的路由出口<router-view></router-view>
动态路由(路由传参)
1 配置路由文件
方式1:
1 配置:router/index.js:
path:"/stu/:id/:name/:age",
2 传递参数:
<router-link to="/stu/1/张三/18">跳转到stu</router-link>
<router-link :to="`/stu/${id}/${name}/${age}`">跳转到stu</router-link>
this.$router.push(`/stu/${this.id}/${this.name}/${this.age}`)
3 获取参数:
this.$route.params
方式2:
1 配置:router/index.js:
{
path:"/stu/:id/:name/:age",
props:true,
2 传递参数:
<router-link to="/stu/1/张三/18">跳转到stu</router-link>
<router-link :to="`/stu/${id}/${name}/${age}`">跳转到stu</router-link>
this.$router.push(`/stu/${this.id}/${this.name}/${this.age}`)
3 接受参数
export default {
props:["id","name","age"],
关于?的妙用
以上方式有一个弊端:如果路由文件配置的参数和需要传递的参数不匹配则直接404,如何解决:
通过?解决:在路由文件中对应的参数后配置?,能够使得当前参数可传可不传
path:"/stu/:id?/:name?/:age?",
2 非配置路由文件
方式1:
1 传递参数
<router-link to="/stu?id=1&&name=张三&&age=18">跳转</router-link>
2 接受参数
this.$route.query
方式2:
1 传递参数
<router-link :to="{path:'/stu',query:{id:1,name:'张三',age:20}}">跳转</router-link>
this.$router.push({
path:"/stu",
query:{
id:this.id,
name:this.name
}
})
2 接受参数
this.$route.query
本文介绍了Vue.js中多种组件间通信的方法,包括父子组件间的props和emit、兄弟组件间的事件总线(bus)、以及跨级组件间的$attrs等。此外还详细阐述了Vue全家桶的构成及其项目创建过程。

被折叠的 条评论
为什么被折叠?



