第一章:Vue概述
1.hello World
Vue:易学易用 性能出色 适用场景丰富的web前端框架
vue是一款构建用户界面的JavaScript框架 它基于标准的html css JavaScript构建 并提供了一种声明式 组件化的编程模型 帮助你高效的开发 用户界面 无论是简单还是复杂的页面 vue都可以胜任
vue特点:组件化开发 声明式的编程(命令行的方式)
2.hello Vue的书写
方式一:在网页中直接使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入Vue-->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="root"></div>
<script>
<!--2.编写vue代码-->
//在写vue的时候一切皆组件
/*1.:创建一个根组件 在vue3中组件就是一个普通的js对象
* */
//1.创建一个vue组件
const Root={
template:"<h1>你好 Vue!</h1>"//这个就是模板样式在 希望在页面中呈现的样子
};//在使用过程中组件用来创建组件实例 组件是组件实例的模板 组件->组件生成组件实例->虚拟dom->dom(在页面中呈现)
//2.创建一个App实例(应用实例)
const app=Vue.createApp(Root)
//3.将实例在页面中挂载
app.mount("#root")
</script>
</body>
</html>
2.data函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入Vue-->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="root"></div>
<script>
<!--2.编写vue代码-->
//在写vue的时候一切皆组件
/*1.:创建一个根组件 在vue3中组件就是一个普通的js对象
* */
//1.创建一个vue组件
const Root={
data(){
//在这里书写一个data 注意:data是一个函数 需要一个对象作为返回值
return{
message:"Vue 计算机科学与技术学院", //data方法返回的对象 其中的属性会自动添加到组件的实例中
button:"我是计算机科学与技术学院按钮"
}
},
//在模板中科院直接访问组件实例中的属性
//在模板中使用插值语法 {{属性名}} 来访问组件实例中属性
template:"<h1>你好 Vue!{{message}} , {{button}}</h1>"//这个就是模板样式在 希望在页面中呈现的样子
};//在使用过程中组件用来创建组件实例 组件是组件实例的模板 组件->组件生成组件实例->虚拟dom->dom(在页面中呈现)
//2.创建一个App实例(应用实例)
const app=Vue.createApp(Root)
//3.将实例在页面中挂载
app.mount("#root")
</script>
</body>
</html>
3.按钮练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入Vue-->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="root"></div>
<script>
<!--组件是用来创建组件实例-->
//练习:创建按钮 点击按钮时 显示按钮点击的时间
const Root={
data(){
return{
//定义一个变量 记录点击次数
//data中的数据湖自动和使用它的视图绑定 数据发生变化视图会自动刷新
count:0,
message:"Vue 计算机科学与技术学院",
}
},
template:" <button @click='count++'>点我一下</button> --点了{{count}}次"
};
const app=Vue.createApp(Root)
//3.将实例在页面中挂载
app.mount("#root")
</script>
</body>
</html>
4.模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--1.引入Vue-->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="root">
<!-- 方式二:如果追定义在网页中 此时模板必须符合html的规范
如果我们在组件中定义template 则会优先使用template作为模板 同时根元素中的所有内容都会被替换
如果在组件中没有定义template 则会使用根元素innerHtml作为模板使用
-->
<button @click='count++'>点我一下</button> --点了{{count}}次
<p>我是{{count}}</p>
</div>
<script>
const Root={
data(){
return{
count:0,
message:"Vue 计算机科学与技术学院",
}
},
//template是模板 它决定了组件最终的样子
//定义模板的方式有三种 1.在组件中通过template属性去指定 2.直接在网页的根元素中指定
// 方式一: template:" <button @click='count++'>点我一下</button> --点了{{count}}次"
//方式三:使用render()函数直接渲染
};
const app=Vue.createApp(Root)
//3.将实例在页面中挂载
app.mount("#root")
</script>
</body>
</html>
6.使用构建工具去书写Vue
1.打开终端 初始化项目 npm init -y
2.安装vite依赖:npm add -D vite
2.安装vue依赖 :npm add vue
第一步创建html页面:
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Hello Vue 计算机科学与技术学院!</ title>
< script type = " module" src = " ./src/index.js" > </ script>
</ head>
< body>
< div id = " app" > </ div>
</ body>
</ html>
import { createApp} from "vue/dist/vue.esm-bundler.js" ;
const App= {
data ( ) {
return {
message : "计算机科学与技术学院欢迎你!"
}
} ,
template : "<h1>{{message}}</h1>"
}
createApp ( App) . mount ( "#app" )
1. 直接在网页中使用:
import { createApp} from "vue/dist/vue.esm-bundler.js" ;
2. 使用vite npm add vite - D
3. 代码:
const App= { }
const app= createApp ( App)
app. mount ( "#root" )
第二章:组件化编程
1.Vue组件化
html页面代码:
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> 计算机科学与技术学院</ title>
< script type = " module" src = " ./src/index.js" > </ script>
</ head>
< body>
< div id = " root" > </ div>
</ body>
</ html>
index程序入口代码:
import { createApp} from "vue/dist/vue.esm-bundler.js" ;
import App from "../../1.helloVue/src/App" ;
const vm= createApp ( App ) . mount ( "#root" )
子组件App代码:
import MyButton from "../../2.helloVue/src/MyButton" ;
export default
{
data ( ) {
return {
msg : "计算机科学与技术学院" ,
count : 0
}
} ,
components : {
MyButton : MyButton
} ,
template : '<h1>{{msg}}</h1>' +
'<button @click="count++">点我一下{{count}}</button>' +
'<h1>{{count}}</h1>' +
'<h2>{{count}}</h2>' +
'<MyButton></MyButton>' +
'<MyButton></MyButton>'
}
子组件MyButton代码:
export default {
data ( ) {
return {
count : 0
}
} ,
template : '<button @click="count++">{{count}}</button>'
}
2.单文件组件
当前template是用字符串的形式去编写模板 1. 这些字符串会在项目运行时 在浏览器中会被编译为js的函数 ( 性能不太好)
2. 在字符串中编写代码 体验感差
为了我解决这种问题 vue为我们提供了一种单文件组件 单文件组件的格式就是vue 后缀名为vue
在Vscode中要装 Vue language Features插件
vue文件用来编写单文件组件 vue本省不能被浏览器识别 所以要用构建工具打包才可以使用
同时vue文件在打包时 构建工具会直接将template替换为函数 无需再浏览器中中去编译
要想使用 需要安装插件:终端输入:npm add - D @vitejs/ plugin- vue
开始配置 vite. config. js文件
vue. vue组件代码:
< template>
< ! -- 在这里书写模板-- >
< h1> { { msg} } < / h1>
< / template>
< script>
export default {
data ( ) {
return {
msg : "计算机科学与技术欢迎你!"
}
}
}
< / script>
< style scoped>
< / style>
App. js代码:
import MyButton from "../../2.helloVue/src/MyButton" ;
import vue from "../../2.helloVue/src/vue" ;
export default
{
data ( ) {
return {
msg : "计算机科学与技术学院" ,
count : 0
}
} ,
components : {
MyButton : MyButton,
Vue : vue
} ,
template : '<h1>{{msg}}</h1>' +
'<button @click="count++">点我一下{{count}}</button>' +
'<h1>{{count}}</h1>' +
'<h2>{{count}}</h2>' +
'<MyButton></MyButton>' +
'<MyButton></MyButton>' +
'<Vue></Vue>'
}
index. js组件代码:
import { createApp} from "vue/dist/vue.esm-bundler.js" ;
import vue from "./vue" ;
const vm= createApp ( App) . mount ( "#root" )
vite. config. js配置文件:
import vue from "@vitejs/plugin-vue" ;
export default {
plugin : [ vue ( ) ]
}
3.自动创建项目
每次手动创建项目会很麻烦:因此我们使用自动工具来创建:
命令:npm create vue
npm init vue@latest(推荐)
选择完成后 自动创建完成vue项目
4.代码分析
目录分析:
--public 静态资源目录 一般是图标
<script>
export default {
//组件就是一个普通的js对象
//组件:一个组件可以创建多个组件实例
data(){
//data是一个函数
//在data中this this就是当前的组件实例化
//如果使用箭头函数就无法通过this来访问组件实例
//data会返回一个对象作为返回值 vue会对该对象进行代理 从而将其转换为响应式数据
//响应式数据会直接通过组件实例化
return{
msg:"计算机科学与技术学院"
}
}
}
</script>
<template>
<h1>{{msg}}</h1>
</template>
import App from "./App";
import {createApp} from 'vue'
createApp(App).mount('#app')
/*
* App.vue是根组件 createApp(App) 将组件关联到应用上
* --会返回一个应用的实例化
*
* app.mount("#app")将应用挂载到页面中 会返回一个根组件的实例 组件的实例的通常命名为vm
*
* */
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/2.Vue教程/05.使用vite/3.Vuetest/src/main.js"></script>
</body>
</html>
5.响应式原理
const obj= {
name : "孙悟空" ,
age : 19
}
const handler= {
get ( target, prop, receiver) {
console. log ( target, prop, receiver)
return '计算机科学与技术学院'
} ,
set ( target, prop, value, receiver) {
console. log ( target, prop, value, receiver)
}
} ;
const proxy= new Proxy ( obj, handler)
console. log ( proxy)
console. log ( proxy. name)
proxy. age= 10 ;
console. log ( proxy. age)
注意:设置代理时 不会对原对象产生影响
vm. $data是设计的代理对象 通过vm可以直接访问到$data中的属性
vm. $data. msg等价于vm. msg
可以通过vm. $data多态的向组件中添加响应式数据
created ( ) {
this . $data. name= '计算机'
}
6.data详细介绍
<script>
import MyButton from "./components/MyButton";
export default {
data(){
//data()返回的对象会被Vue所代理
return{
//Vue在构建响应式对象时 会同时将对象中的属性也做成响应式属性
//深层响应式对象
//有些情况下可以通过shallowReactive()来创建一个浅层的响应式属性
msg:'计算机科学与技术学院欢迎你!',
stu:{
name:'吴邪',
age:18,
gender:"男"
}
}
},
// 注册一下MyButton
components:{
MyButton
}
}
</script>
<template>
<h1>{{msg}}</h1>
<MyButton></MyButton>
</template>
7.methods介绍
< script >
export default {
data ( ) {
return {
msg : '计算机科学与技术学院'
}
} ,
methods : {
test ( ) {
alert ( "计算机科学与技术学院" )
} ,
hello ( ) {
console. log ( "我是计算机科学与技术学院的hello" )
} ,
sum ( a, b ) {
return a+ b
}
}
}
</ script>
< template>
< h1> {{msg}}</ h1>
< h2> {{sum(12,34)}}</ h2>
</ template>
8.计算属性
< script >
export default {
data ( ) {
return {
msg : '计算机科学与技术学院' ,
stu : {
name : '吴邪' ,
gender : '男' ,
age : '18'
}
}
} ,
methods : {
updateAge ( ) {
if ( this . stu. age=== 18 ) {
this . stu. age= 17
} else {
this . stu. age= 18
}
console. log ( "我执行了~~~" )
}
} ,
computed : {
info : function ( ) {
return '计算机科学与技术学院'
}
}
}
</ script>
< template>
< h1> {{msg}}</ h1>
< h2> {{stu.name}}--{{stu.age}}--{{stu.gender}}</ h2>
< h3>
评语:{{stu.age >=19? "你是一个成年人 !":"你是一个未成年人"}}
</ h3>
< button @click = " updateAge" > 减</ button>
< h1> {{msg}}</ h1>
< h4> {{info}}</ h4>
</ template>
9.安装Vue调试工具
在edg浏览器里面输入:https://microsoftedge.microsoft.com/addons/detail/vuejs-devtools/olofadcdnkkjdfgjcmjaadnlehnnihnl 安装扩展 Vue.js调试程序
10.组合式API简介
< script >
import { reactive} from 'vue'
export default {
setup ( ) {
let msg= "静态天气真不错!"
let count= 0
const stu= reactive ( {
name : "吴邪" ,
age : 18 ,
gender : '男'
} )
function f ( ) {
stu. age= stu. age++
}
return {
msg, count, stu, f
}
}
}
</ script>
< template>
< h1> 演示组合式api</ h1>
< h2> {{msg}}</ h2>
< h2> {{stu.age}}</ h2>
< button @click = " f" > 点我</ button>
< h1> {{stu.name+stu.age +stu.gender}}</ h1>
</ template>
11.setup
<!--加了setup后就告诉了浏览器 我们使用纯组合式api 就不需要之前的那种麻烦了-->
<script setup>
//条例 需要响应式数据也是
import {reactive} from 'vue'
// 在这里书写的 就不需要之前的那种return返回 才可以暴露出去 而是默认就暴露出去了
const msg="计算机科学与技术学院"
const count=0
const stu=reactive({
name:'孙悟空'
})
</script>
<template>
<h1>组合api</h1>
<h2>{{count}}</h2>
<h3>{{stu.name}}</h3>
</template>
12.响应式代理
< script setup >
import { reactive, ref} from 'vue'
import { $ref} from 'vue/macros'
const stu= reactive ( {
name : '吴邪'
} )
let x= $ref ( 0 )
let count= ref ( 0 )
count= 10
</ script>
< template>
< h1> 计算机科学与技术学院</ h1>
</ template>
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig ( {
plugins : [ vue ( {
reactivityTransform : true
} ) ] ,
resolve : {
alias : {
'@' : fileURLToPath ( new URL ( './src' , import . meta. url) )
}
}
} )
13.ref对象解包
<script setup>
import {ref, reactive, conputed, computed} from "vue"
//因为是组合式API 使用就追定义
const msg="Hello 计算机科学与技术学院"
//第二种方式:使用ref来定义
const msgTest=("Hello 计算机科学与技术学院 这个是一个响应式变量")
const changeMsgHander=()=>{
//修改ref对象时 必须通过value
msg.value="Hello 计算机科学与技术学院"
}
//{value:obj}
//obj.value.name
const obj=ref({
name:"吴邪",
age:18
})
//不加ref或者reactive就不是响应式的数据
const obj2=(
//obj.name.value
{
name:ref("解雨臣"),//{value:"解雨臣"}
age:ref(18)//{value:18}
}
)
//computed用来生成计算属性
const newMsg=computed(()=>{
return msg.value+"计算机科学与技术学院你好!"
})
</script>
<template>
<!-- ref对象在模板中可以自动解包 要求ref对象必须是顶层对象-->
<h1>{{msg}}</h1>
<h2>{{msgTest}}</h2>
<h3>{{obj.name}}</h3>
<!-- 这里的name表示顶层的响应式对象 使用不能自动解包 必须得加value-->
<h4>{{obj2.name.value}}</h4>
<hr>
<h2>{{obj.age}}</h2>
<h2>{{obj2.age}}</h2>
<hr>
<h1>{{newMsg}}</h1>
<button @click="msgTest='计算机科学与技术学院 响应式变量'">点我一下</button>
</template>
14.模板的语法
<script setup>
const msg="计算机科学与技术学院"
//例如:插入一段html代码
const html='<h1>计算机科学与技术学院</h1>'
</script>
<template>
<!-- 在模板中可以直接访问到 组件中声明的变量
--还可以访问js中的函数 除了组件中的变量外 vue也为我们提供了一些全局对象可以访问
--除此之外 也可以通过app对象来向vue中添加一些全局变量
--在使用插值语法时 {{}} 只能使用表达式
表达式 就是有返回值的语句
--插值实际上就是在修改元素的textContent 如果内容中含有标签 不会作为标签生效
{{}}
指令:--指令模板为标签设置的一些特殊属性 它可以用来设置标签如何显示内容
--指令使用v-开头
1.v-text 将表达式的值作为元素的textContent插入 作用同{{}}插值语法
使用指令时 就不需要通过插值语法来指定表达式
2.v-html 将表达式的值作为元素的innerHtml插入 有xss攻击的风险
-->
<h1>{{msg}}</h1>
<!-- 例如:访问随机数-->
<h2>{{Math.random()}}</h2>
<hr>
<h2>{{new Date()}}</h2>
<hr>
<!-- 插值语法只能使用表达式-->
<h1>{{1}}</h1>
<hr>
<h1>{{html}}</h1>
<!-- 使用指令-->
<div v-text="html"></div>
<hr>
<div v-html="html"></div>
</template>
15.v-bbind指令
<script setup>
import {ref} from "vue"
const imgPath=ref("/images/Default.jpg")
const changeImg=()=>{
imgPath.value="/images/favicon.ico"
}
/*
* 当我们需要为标签多态的数值属性时 需要使用v-bind指令
* v-bind指令可以简写为 :
*
* 当我们为一个布尔值设置属性时 如果我们设置为true 则元素上有该属性 如果值为FALSE则元素没有该属性
*
* 特殊情况:"" 空值 在这里会被当成空值
*
* */
const attrs={
id:"box1",
class:"hello"
}
</script>
<template>
<!-- public是静态资源 使用的时候 会原封不动的打包过来-->
<!-- <img src="/images/Default.jpg" alt="壁纸">-->
<button @click="changeImg">切换图片</button>
<img v-bind:src="imgPath" alt="壁纸">
<hr>
<img :src="imgPath" alt="壁纸">
<hr>
<!-- 设置标签属性-->
<div :="attrs"></div>
</template>
16.style-scoped
<script setup>
</script>
<template>
<h1>计算机科学与技术学院!</h1>
<div class="box1"> </div>
<div class="app"></div>
<!-- 直接书写组件-->
<MyBoxVue> </MyBoxVue>
</template>
<!--
样式设置:
--可以直接通过style标签来编写样式
如果追通过style标签来编写样式 此时编写的样式是全局样式 会影响到所有的组件
-->
<!--要想避免组件之间的影响 可以为style标签添加一个scoped属性 这样样式会作为局部样式 只对当前组件生效
当我们在组件中使用scoped样式时 vue会自动为组件中的所有元素生成一个随机的属性
形如:data-v-7a7a37b1 生成后所有的下载器都会在最后添加一个[data-v-7a7a37b1 ]
注意:随机生成的属性 除了会添加到当前组件内的所有元素上 也会添加到当前组件引入引入的其他组件的根元素上 这样设计是为了
可以通过父组件设置一些样式
-->
<style scoped>
h1{
background-color: aqua;
}
.box1{
width: 200px;
height: 200px;
background-color: aquamarine;
}
</style>
<!--注意一个组件可以由多个style-->
<style>
/*全局选择器*/
:global(div){
border: 1px red solid;
}
</style>
17.样式
<script setup>
</script>
<template>
<h1>计算机科学与技术学院欢迎你!</h1>
<hr>
<div class="app">
<h1>计算机科学与技术学院 欢迎你!</h1>
<div :class="$style.box1">App中的box1</div>
</div>
<hr>
<div :class="classes.h1">
<!-- 这里就可以调用自定义的样式-->
<h1>计算机科学与技术学院</h1>
</div>
</template>
<!--css模块
---自动的对模块中的类名进行哈希化处理 来确保类名的唯一性
---在模板中可以通过$style.类名 使用
--也可以通过module的属性值来指定变量名
-->
<style module>
.box1{
background-color: #bfa;
}
</style>
<style module="classes">
.h1{
background-color: orange;
}
</style>
<!--从习惯上 使用scoped为主-->
<style scoped>
</style>
18.类和内联样式
<script setup>
const arr=["box1","box2","box3"]
const arr2=[{box1:true},{box2:false},{box3:false},{box4:true}]
//设置一个动态态的内联样式
const style={
color:"red",
backgroundColor:"#bfa"
}
</script>
<template>
<h1>计算机科学与技术学院</h1>
<div :class="arr2" :style="style">计算机科学与技术学院</div>
</template>
<style scoped>
.header
{
background-color: orange;
}
</style>
练习
<script setup>
import {ref} from "vue"
//创建一个变量 来记录选项卡的状态
const current=ref(0)//0表示球员 1表示球队
</script>
<template>
<h1>计算机科学与技术学院</h1>
<hr>
<!-- 1.创建一个容器 tab-wrapper-->
<div class="tab-wrapper">
<!-- 2.选项卡的一个头部-->
<header class="tab-head">
<!-- 在这个区域里面有两个按钮-->
<!-- 绑定一个事件 效果就是点击的时候 要变色-->
<div @click="current=0" class="tab-button " :class="{active:current===0}">热门球员</div>
<!-- 给这个也绑定一个事件 点击也要变色-->
<div @click="current=1" class="tab-button" :class="{active:current===1}">热门球队</div>
</header>
<!-- 3.选项卡的主体-->
<div class="main" style="color: #f8f8f8;font-size: 20px">
<!--current===0显示球员
current===1显示球队
使用v-show指令 用来设置一个内容是否显示
v-show 设置一个内容是否显示时
v-show通过display来设置一个元素是否显示的
-->
<div v-show="current===0">
<!-- 球员-->
<div class="tab-list">
<div class="tab-item">
<!-- 用来放置图片-->
<div class="photo">
<img src=" /images/meix.png" alt="法国">
<span>1</span>
</div>
<!-- 用来放置描述-->
<div class="desc">
<span class="name">梅西</span>
<div class="hot-bar">
<div class="inner">33760热度</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="current===1">
<!-- 球队-->
<div class="tab-list">
<div class="tab-item">
<!-- 用来放置图片-->
<div class="photo">
<img src="/images/fanlai.png" alt="梅西">
<span>1</span>
</div>
<!-- 用来放置描述-->
<div class="desc">
<span class="name">法国</span>
<div class="hot-bar">
<div class="inner">433760热度</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.tab-wrapper{
box-sizing: border-box;
width: 800px;
padding: 20px;
background-color: rgb(45,83,211);
}
.tab-head{
/* 设置一个弹性盒*/
display: flex;
border-radius: 20px;
overflow: hidden;
}
/*给按钮也设置一个*/
.tab-button{
background-color: #fff;
font-size: 30px;
flex: auto;
padding: 10px 0;
text-align: center;
cursor: pointer;
/*加一点过度效果*/
transition: 1s;
}
.tab-button:not(.active):hover{
color: rgb(187,3,52);
}
.active{
background-color: rgb(187,3,5);
color: #ffffff;
}
.tab-list{
margin: 20px;
}
.tab-item{
/* 开启一个弹性盒子*/
display: flex;
margin-bottom: 20px;
}
/*容器*/
.photo{
width: 150px;
background-color: #f8f8f8;
border-radius: 20px;
overflow: hidden;
position: relative;
}
/*图片*/
.photo img{
width: 100%;
/*设置图片的对其*/
vertical-align: baseline;
}
/*排名*/
.photo span{
position: absolute;
width: 50px;
height: 50px;
background-color: rgb(245,102,1);
top: 0;
left: 0;
font-size: 20px;
font-weight: bold;
color: #f8f8f8;
display: flex;
justify-content: center;
align-items: center;
border-bottom-right-radius:10px ;
border-top-left-radius: 10px;
}
.desc{
/*设置一下文字描述*/
font-size: 30px;
color: #f8f8f8;
display: flex;
flex-flow: column;
justify-content: space-evenly;
/*background-color: #bfa;*/
/* 设置一下弹性盒*/
flex: auto;
margin-left: 30px;
}
.hot-bar{
background-color: rgb(3,37,103);
border-radius: 20px;
text-indent: 0.5em
;
overflow:hidden;
}
.inner{
background-color: red;
border-radius: 20px;
width: 50%;
/* 设置一下渐变*/
background-image: linear-gradient(90deg,rgb(187,3,52) 50%,rgb(66,2,12));
}
</style>
19.props介绍
<template>
<div class="tab-item">
<!-- 用来放置图片-->
<div class="photo">
<img :src="item.img" :alt="item.name">
<span>{{item.rate}}</span>
</div>
<!-- 用来放置描述-->
<div class="desc">
<span class="name">法国</span>
<div class="hot-bar">
<div class="inner">433760热度</div>
</div>
</div>
</div>
</template>
<script setup>
/*
*
* 子组件中的数据通常不会在子组件中直接定义 这样湖导致数据和视图发送耦合 子组件中的数据通常会在创建组件实例时确定
* 子组件中的数据通常会在创建组件实例时确定 父组件可以通过props来将数据传递给子组件
*
*
*
* ---使用props
* --先在子组件中定义props
*
*
* */
import {reactive} from 'vue'
const props= defineProps(["item"])
const item=reactive({
name:"梅西",
img:"/images/fanlai.png",
rate:1,
hot:433760
})
</script>
<style scoped>
.tab-item{
/* 开启一个弹性盒子*/
display: flex;
margin-bottom: 20px;
}
.photo{
width: 150px;
background-color: #f8f8f8;
border-radius: 20px;
overflow: hidden;
position: relative;
}
.photo img{
width: 100%;
/*设置图片的对其*/
vertical-align: baseline;
}
.photo span{
position: absolute;
width: 50px;
height: 50px;
background-color: rgb(245,102,1);
top: 0;
left: 0;
font-size: 20px;
font-weight: bold;
color: #f8f8f8;
display: flex;
justify-content: center;
align-items: center;
border-bottom-right-radius:10px ;
border-top-left-radius: 10px;
}
.desc{
/*设置一下文字描述*/
font-size: 30px;
color: #f8f8f8;
display: flex;
flex-flow: column;
justify-content: space-evenly;
/*background-color: #bfa;*/
/* 设置一下弹性盒*/
flex: auto;
margin-left: 30px;
}
.hot-bar{
background-color: rgb(3,37,103);
border-radius: 20px;
text-indent: 0.5em
;
overflow:hidden;
}
.inner{
background-color: red;
border-radius: 20px;
width: 50%;
/* 设置一下渐变*/
background-image: linear-gradient(90deg,rgb(187,3,52) 50%,rgb(66,2,12));
}
</style>
20.props-1
<template>
<h2>我是子组件</h2>
<div>我是子组件</div>
<h2></h2>
</template>
<script>
/*
* 父组件 可以通过props来向子组件传递数据
* ---注意 父组件 传递给子组件的props是只读的 不可以修改
* 即使可以修改 我们也不要在子组件中去修改父组件的数据
* 如果非得要改 具体方法在讲(通过自定义事件去改)
*
* 属性名:定义属性名时 要遵循驼峰命名法
*
* */
//定义props 里面写入属性
const props= defineProps(["1","2","obj","maxLength"])
</script>
<style scoped>
div{
color: red;
}
</style>
21.props的配置
子组件:
<template>
<div>
<hr>
<h1>{{props.MaxLength}}</h1>
<h2>我是子组件 MyBox {{props.obj.count}}</h2>
<button @click="props.obj.count++">子组件的按钮</button>
</div>
</template>
<script>
//1.定义props的方式二
const props=defineProps({
//定义参数类型
count:Number,
obj:Object,
MaxLengt:{
type:String,//type也是指定数据类型的
required:true,//帮助去检查这个属性
default:"哈哈哈",
validator(value) {
return value="计算机科学与技术学院"}
}
})
console.log(props)
</script>
<style scoped>
</style>
父组件:
<script setup>
import MyBox from './components/MyBox.vue'
import {ref} from 'vue'
const count=ref(0)
const obj=ref({
count:0
})
</script>
<template>
<h1>计算机科学与技术学院</h1>
<MyBox :count="count" :obj="obj" max-length="20">
</MyBox>
<button @click="obj.count++">点我一下</button>
</template>
22.v-if指令
<script setup>
import {ref} from 'vue'
const count=ref(0)
const obj=ref({
count:0
})
const isShow=ref(true)
</script>
<template>
<h1>计算机科学与技术学院</h1>
<button @click="isShow=!isShow">切换</button>
<hr>
<!-- v-show 可以根据值来决定值是否显示
通过display来切换元素的显示状态
v-if: 可以根据表达式的值来确定是否有元素 会直接将元素删除
区别:v-show通过css来切换组件的显示与否 切换不会涉及到组件的重新渲染 切换的性能比较高 但是初始化时
会对所有的组件进行初始化 所有这个对初始化的性能比较差
v-if 通过删除元素的方式来切换元素的显示 切换时反复的渲染组件 切换性能比较差
v-if只会初始化会用到的组件 所以他的初始化性能比较好
v-if可以和v-else-if 和v-else结合使用
v-if可以配合template使用
-->
<div v-show="isShow">
<h2>我不会显示</h2>
我不会显示呀!</div>
<hr>
<div v-if="isShow">
<h2>你猜猜我回显示吗!</h2>
</div>
<div v-else>
<h1>我是v-else中的内容</h1>
</div>
</template>
<style scoped>
</style>
23.动态组件(第33节)
<script setup>
import A from "./components/A.vue"
import B from "./components/B.vue"
import {ref} from "vue"
const isShow=ref(true)
</script>
<template>
<component is="div">
<!-- component--动态组件
---component最终以声明标签呈现是由is属性决定
is="X" X可以是 div h1 ...等等
-->
计算机科学与技术学院 div
</component>
<component :is="A"></component>
<h1>计算机科学与技术学院欢迎你!</h1>
<hr>
<button @click="isShow=!isShow">切换</button>
<component :is="isShow? A:B"></component>
<B>
</B>
</template>
24.网页渲染
浏览器在渲染页面的时候:
---1.加载页面的html和css(源码)
---2.html转换为dom css会转换为cssOM
---3.将DOM和CSSOM构建成一颗渲染树
---4.对渲染树进行reflow (回流 重载) 就是计算元素的位置
---5.对网页进行一个绘制 repaint(重绘)
渲染树:Render Tree
--从根元素楷书检查那些元素可见 以及他们的样式
--忽略那些不可见的元素(display:none)
重排 回流
计算渲染树中元素的大小和位置
当页面中的元素大小或位置发生变化时 便会触发元素的重排
注意:每次修改这类样式都会触发一次重排 所以n次修改多个样式就会重排n次 而重排是非常消耗系统资源的操作
所以重排次数过多后 会导致网页的显示性能变差
所以在开发时 我们应该尽量减少重排的次数
可以通过class来简介的影响样式 来减少重排的次数
重绘:
绘制页面
当页面发生变化时 浏览器就会对页面进行重新的绘制
在现代的前端框架中 这些东西都已经被框架优化过了 所以在使用react和Vue这些开开发时 就不需要考虑这些问题 唯独需要注意的是 尽量减少在框架中追操作dom
38节课