组件基础
vue单文件组件,它是一种特殊的文件格式。每一个文件都可以看做一个单独的组件
一个组件内可以把html、css、js封装在一起,文件名后缀是.vue
一个vue文件大致结构如下图所示,css和js可以没有,但是HTML代码是必须要有的
加载组件
我们的组件有了之后就该考虑怎么使用了,分为三步
引入组件
我们的vue项目里面有一个叫app.vue的根组件。其他的组件都是基于这个显示的
我们想引入一个组件需要使用import。
如果我有一个组件alpha.vue我想导入这个组件,就需要在app.vue里面使用import alpha form "相对于app.vue的相对路径"
导入部分是要写在js部分的
挂载组件
我们引入组件之后就需要挂载组件,我们需要在js部分的export default{ }里面写一个components:{组件的名称(比如上面说的alpha)}
显示组件
只需要在HTML代码部分以标签的形式写出来就ok。比如我想显示alpha组件,我只需要<alpha />就可以显示了,它的显示不是单开一个页面。而是添加到原来的页面内
大概就是这个意思,如果组件的名字是多个英文单词,可以使用单词-单词的方式拼接,这样不会更快但是会更好看,而且比较支持这个方法
我们再来扩展一下style标签的一个知识。
我们在组件内设置了css的属性,并且把这个组件导入了app,alpha的css样式也是会影响到app的。这时候我们只需要在组件的style 标签上设置一个属性scoped就可以让组件内的属性只影响组件内的HTML元素
组件之间的交互
组件与组件之间的关系是互相引用的,既然是互相引用就需要有数据的传输,由于代码不好展示,就通过图片来展示了
父组件传递给子组件
这是引用传递给被引用组件(app -》alpha),要注意的是如果我们需要传递数组和对象,它的默认值(props里面的default要通过函数来返回)
即:
props:{
arr:{
type:Arry,default:()=> []//数字
}
obj:{
yupe:Object,default:()=>({})//要加括号,不然会被认为是箭头函数的大括号{}
}
}
子组件传递给父组件
子组件传递给父组件需要用到 $emit
大概的逻辑如图所示
子组件通过事件监听触发this.$emit("自定事件",数据)把数据传递给父组件。父组件在子组件标签里面添加一个事件监听,监听自定事件,监听到之后运行处理函数,处理函数有一个形参用于接收子组件传递的数据
vue路由(组件之间跳转,这个了解过程即可)
要使用路由功能,就需要先下载。我们再终端里面输入:vue install --save vue-router下载vue的路由。
然后我们可以在src的路径下添加一个新的目录router,并在此目录下建立index.js文件。这个文件就是路由所在之地
这个文件里面要写什么呢?
import { createRouter,createWebHashHistory} from "vue-router"//导入需要的包
import index from "../views/index.vue"//导入我们要当作跳转目标的组件
import noindex from "../views/noindex.vue"
const routes = [//定义一个路由数组,数组内的每一个元素都是一个对象。对象信息包含path路径和component也就是组件的名字
{
path: "/index",
component: index
},
{
path: "/noindex",
component: noindex
//或者写成:component : ()=> import ('../views/noindex.vue')这样写就不用在前面提前导入了
//import noindex from "../views/noindex.vue"这一条语句就可以省略了
}
]
const router = createRouter(//创建一个createrouter对象,里面包含了我们的信息
{
history: createWebHashHistory(),//为了后台的方便。我们建议都是用这个
routes,//这个就是我们刚写的routers数组
}
)
export default router;//返回router对象
这样,我们的index.js就写完了。然后我们再找到main.js这个文件
在这个文件内添加:
import router from './router'
然后在CreateApp(app).mount(`#app`)中添加.use(router)也就是我们index.js最后返回的那个router
使他成为CreateApp(app).use(router).mount(`#app`)
接下来就是在app.vue内使用这些了
我们在app.vue的HTML代码部分写一个:<router-view></router-view>。它的作用类似于占位符,我们之后跳转的页面都会显示在这个位置。这只是显示的位置。我们需要使用router-link to="路径"
来确认跳转到哪个组件内。它是双标签,标签内圈起来的文字就是连接的载体
to的路径就是我们在index.js的那个数组里面设置的path( path: "/index",)
路由嵌套
有的时候我们一个路由下面可能会跟随多个不同的模块
比如index首页可能会有index/zhuce index/denglu index/zhuxiao等多个子页面。
这时候我们就可以设置嵌套的路由,即路由之下还有路由
我们的路由设置都在index.js文件里面
我们如果想在index里面再添加路由,再index所在的对象里面添加children数组,这个数组就相当于一个routes mini(小型的routes
注意的是嵌套的数组path就不需要再添加 / 了。但是路由访问的时候还是要的(/index/denglu
vue路由(简单便捷版本,不想看上面就看这个(相对来说便捷很多))
这个方法最终实现效果和上一个一样,但是相对于上一个来说简单得多。
我们只需要再新建项目的时候勾选上对应的router即可
这样项目就会自动生成route对应的目录以及index.js文件。并且会在main.js里面配置好相关的操作。我们只需要做两步即可:1.添加路由 2.把路由实现到网页中
我们可以看到它已经有该有的东西了,我们只需要修修改改就成自己写的了。
路由案例
为了方便了解,我们来写一个嵌套的路由
我们假设有三个组件a.vue、b.vue和c.vue
我们在主页index通过连接可以跳转到a.vue 然后a.vue里面又包含两个子组件b、c
关系图大致如上
我们通过index 加载出a 通过a加载出bc
我们首先编写index的文件,有些注释可以看看,写的时候不要这样写注释因为格式不对
<template>
<div id="a">//整个页面都在内
<div class="d">//这里是我们的一级导航,通过它跳转到二级导航a
我是index
<router-link to="/a">点击加载a</router-link>//按钮设置
</div>
<div class="ddd"><router-view></router-view></div>//导航的跳转,出现的组件渲染到这个div里面
</div>
</template>
<style>
.d{//设置组件index(app.vue的显示大小样式
height: 1000px;
text-align: center;
width :100px;
border :2px solid black;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
}
.ddd{//这里设置的是a组件出现的范围
height: 1000px;
text-align: center;
width :1000px;
border :2px solid black;
border-radius: 15px;
display: flex;
align-items: center;
}
#a{
display: flex;
给整个页面都设置一个flex布局
}
</style>
<script setup lang="ts">
</script>
然后我们再来看a组件的内容,这里要注意的是我们会通过按按钮来决定显示c组件还是b组件
<script setup>
</script>
<template>
<div id="qwe">
<h1>i am a</h1>//a组件的内容
<br>
<router-link to="/a/b">点击去b</router-link>//跳转的b组件连接
<br>
<router-link to="/a/c">点击去c</router-link>//跳转c组件的连接
<div class="sss"><router-view></router-view></div>//组件显示的范围
</div>
</template>
<style scoped>
div{
}
#qwe{
height: 1000px;
width: 1000px;
display: flex;
align-items: center;
}
.sss{
height: 100%;
width: 100%;
display: flex;
align-items: center;
border :2px solid pink;
}
</style>
b、c组件就不展示了,它们只是起到显示的作用,实际意义不大。我们需要明确一点
在index组件内决定但是二级导航怎么显示,不关心三级导航
在二级导航内只关心三级导航如何显示。最终的效果图👇
我们再来看路由(index.js的配置)的配置
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
path: '/a',
component : () => import('../views/a.vue'),
children: [
{
path: 'b',
component: () => import('../views/b.vue'),
},
{
path: 'c',
component: () => import('../views/c.vue'),
}
]
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
我们通过children设置了路由的嵌套,并且通过箭头函数来在调用的时候才会加载导入相应的组件。