单页面应用和vite的基本使用(props,class,style)
一.单页面应用程序和组件化开发
single page application,指的是一个web中只有一个唯一的html页面,所有的功能和交互都在这唯一的一个页面内完成。
特点
a.在web页面初始化时加载相应的资源(html,javascript,css)
b.不会进行页面的重新加载或跳转。而是利用js动态变换html的内容,从而实现页面与用户的交互。
优点
a.良好的交互体验
单页应用内容的改变不需要重新加载整个页面,获取数据也是通过ajax异步获取,没有页面之间的跳转,不会出现白屏现象
b.良好的前后端工作分离模式
后端提供api接口,更易实现api接口复用
前端专注于页面渲染,更利于前端工程化的发展
c.减轻服务器的压力
服务器只提供数据,不负责页面的合成与逻辑的处理
缺点
a.首屏加载慢
路由懒加载,代码压缩,cdn加速,网络传输压缩
b.不利于seo
ssr服务器端渲染
二.快速创建vue的spa项目
a.基于vite创建spa项目
b.基于vue-cli创建spa项目
vite | vue-cli | |
支持vue版本 | vue3 | vue3,vue2 |
是否基于webpack | 否 | 是 |
运行速度 | 快 | 较慢 |
功能完整度 | 逐渐完善,小而巧 | 大而全 |
1.创建vite的项目
npm create vite@latest
cd 项目名称
npm install
npm run dev
2.项目结构
node_modules目录用来存放第三方依赖包
public是公共的静态资源
src是项目的源代码目录,写的所有代码都在此目录下
assets目录用来存放项目中所有的静态资源文件(css,fonts等)
components目录用来存放项目中所有的自定义文件
App.vue是项目的根文件
main.js是整个项目的打包入口文件
.gitignore是git的忽略文件
index.html是单页面应用程序中唯一的html页面
package.json是项目的包管理配置文件
3.vite项目的运行流程
通过main.js把App.vue渲染到index.html的指定区域。
a.App.vue用来编写待渲染的模板结构
b.index.html中需要预留一个el区域
c.main.js把App.vue渲染到了index.html所预留的区域中
// 从vue中按需导入createApp函数,用于创建vue的实例对象
import { createApp } from 'vue'
// 导入待渲染的App组件
import App from './App.vue'
import './style.css'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from "./routers/index.js";
// 创建spa的应用实例
const app = createApp(App)
app.use(ElementPlus)
app.use(router)
// 把App组件的模板结构渲染到指定的el区域中
app.mount('#app')
三.组件化开发思想
1.组件化开发
根据封装的思想,把页面上可重用的部分封装为组件,从而方便项目的开发和维护
2.组件化开发的好处
提高代码的复用性和灵活性
提升了开发效率和后期的可维护性
3.vue中的组件化开发
vue是一个完全支持组件化开发的框架。组件的后缀名是.vue
四.vue组件的构成
每个.vue组件都由3部分构成
1.template
组件的模板结构
template标签是vue提供的容器标签,只起到包裹性质的作用,不会被渲染为真正的dom元素
<template>
<RouterView></RouterView>
</template>
2.script
组件的js行为
<script setup>
//组合式
</script>
<script>
//选项式
export default{
name:'MyApp',
data(){
return{
}
},
methods:{
}
}
</script>
3.style
组件的样式
npm install less -D或者npm install sass -D
<style scoped lang="scss">
</style>
解决样式冲突问题
通过属性选择器来防止组件之间的样式冲突问题
scoped,如果给当前组件样式添加scoped属性,当前组件的样式对其子组件是不生效的,可以使用/deep/深度选择器或者:deep()
五.注册vue组件(选项式)
先注册后使用
全局注册和局部注册
1.全局注册
import Project from './project/index.vue'
// 创建vue的实例对象
const app = createApp(App)
app.component('my-project',Project)
2.局部注册
<script>
import Project from './project/index.vue'
export default{
name:'MyApp',
components:{
'my-project':Project
},
data(){
return{
}
}
}
</script>
组件注册时名称的大小写
使用kebab-case命名法,短横线命名法
使用PascalCae命名法,大驼峰命名法
六.组件的props
props是组件的自定义属性,组件的使用者可以通过props把数据传递到子组件的内部,供子组件内部使用
封装组件的原则:
组件的dom结构,style样式尽量复用
组件中要展示的数据,尽量由组件的使用者提供
<body>
<div id="app">
<Son :title="title" :msg="msg"></Son>
</div>
</body>
</html>
<script src="./vue3.js"></script>
<script>
let Son ={
props:['title','msg'],
template:
`<div id="son">
{{title}}{{msg}}
</div>`
}
let app =Vue.createApp({
components:{Son},
data(){
return{
msg:'111',
title:'abc'
}
}
})
app.mount('#app')
</script>
<template>
<div>父组件</div>
<DemoSon :msg="msg" :title="title"></DemoSon>
</template>
<script>
import DemoSon from './son.vue'
export default {
name:'demo',
components:{DemoSon},
data(){
return{
msg:'111',
title:'abc'
}
}
}
</script>
<template>
<div>子组件</div>
<p>{{ msg }}{{ title }}</p>
</template>
<script>
export default {
name:'demo-son',
props:['msg','title']
}
</script>
子组件无法使用未声明的props
七.在组件中进行样式绑定
1.动态绑定html元素的class
<template>
<p :class="isBold?'bold':''">组件xxxxxxxxxxxx</p>
<p :class="[isBold?'bold':'',isDel?'del':'']">组件xxxxxxxxxxxx</p>
<button @click="isBold=!isBold"> 按钮</button>
<button @click="isDel=!isDel"> 按钮</button>
</template>
<script>
export default {
name:'demo',
data(){
return{
isBold:false,
isDel:false
}
}
}
</script>
<style>
.bold{
font-weight: bold;
font-size: 20px;
}
.del{
text-decoration: line-through;
}
</style>
<template>
<p :class="classObj">组件xxxxxxxxxxxx</p>
<button @click="classObj.bold=!classObj.bold"> 按钮</button>
<button @click="classObj.del=!classObj.del"> 按钮</button>
</template>
<script>
export default {
name:'demo',
data(){
return{
classObj:{
bold:false,
del:false
}
}
}
}
</script>
<style>
.bold{
font-weight: bold;
font-size: 20px;
}
.del{
text-decoration: line-through;
}
</style>
2.动态绑定html的style
<template>
<p :style="{fontWeight:fw,fontSize:fs+'px',color:c}">组件xxxxxxxxxxxx</p>
</template>
<script>
export default {
name:'demo',
data(){
return{
fw:'bold',
fs:20,
c:'red'
}
}
}
</script>