java Web学习笔记(三)
乐正龙牙lox 2024-08-05 12:03:02 阅读 93
文章目录
1. 前置知识2. Vue使用vite构建项目SFC入门使用ref和.value体会响应式数据(使用ES6和setup)
3. Vue视图渲染技术及其语法模板语法:命令插值表达式渲染双标`><`中的文本(还挺可爱)属性渲染命令事件渲染命令
响应式基础响应式数据
两个渲染条件渲染列表渲染
数据的双向绑定属性计算(不常用)重新回顾SFC(组件传参)文件目录结构(涉及多个vue文件)
4. 路由机制(router)路由的使用路由接收参数路由守卫
5. vue3数据交互 axios(处理异步请求)前置学习:promise特点promise在html中的用法(后面有更简洁的)asyc声明回调函数
axios简介axios的使用
1. 前置知识
前置知识
2. Vue
vue的核心功能:<code>声明式渲染和响应性
渐进式框架vue 理解:功能逐步完善的过程
声明式渲染
:Vue扩充了html语法使其能够声明式响应js
响应性
:在改变js代码的同时html组件的内容自动改变,不需要使用按钮等组件手动触发文本改变
使用vite构建项目
以管理员身份打开vscode
如果不以管理员身份打开vscode,将会导致不能再vscode使用终端访问npm命令
输入命令(第一次进入会下载vite库)
npm create vite
根据提示修改项目名、选择框架和语言
这里是vue框架和JavaScript语言
然后会在命令行的目录下创建相对应的工程
进入项目目录,然后下载依赖
cd ***# 你自己的项目名
npm install # npm i
运行项目
npm run dev # 以测试环境启动项目(在package.json中自定义)
停止项目
ctrl + c
工程文件讲解:不可能给你讲的,先多练,练多了才一讲就通
SFC入门
SFC是Vue的一种规范(Single-File Component):
vue里面含有前端三件套的语法,然后html
通过ES6
语法导入.vue文件
实现前端页面的显示。(导入方式见前置知识)
.vue文件
template标签 代表组件的html部分代码 代替传统的.html文件script标签 代表组件的js代码 代替传统的.js文件style标签 代表组件的css样式代码 代替传统的.css文件
标准的.vue文件格式
<script setup>
</script>
<template>
</template>
<style scoped>
</style>
按照.vue文件
可以看出style是管理css(样式)的;script是管理js的
当然也可以在对应的标签中导入样式:
<script setup>
import './style/test.css'
</script>
...
<style scoped>
@import './style/test.css'
</style>
注意:导入全局的样式文件,在工程的main.js文件中导入即可
使用ref和.value体会响应式数据(使用ES6和setup)
<!-- 使用ES6语法实现 -->
<script type="module">code>
import {ref,reactive} from 'vue'
export default {
setup(){
let counter = ref(1)
function counterUp(){
counter.value ++
}
function counterDown(){
counter.value --
}
return {
counter,
counterUp,
counterDown
}
}
}
</script>
<template>
<div>
<button @click="counterUp()">+</button>code>
<span v-text="counter"></span>code>
<button @click="counterDown()">-</button>code>
</div>
</template>
<style scoped>
</style>
<!-- 在script中声明setup实现 -->
<script setup>
import {ref,reactive} from 'vue'
let counter = ref(1)
function counterUp(){
counter.value ++
}
function counterDown(){
counter.value --
}
</script>
<template>
<div>
<button @click="counterUp()">+</button>code>
<span v-text="counter"></span>code>
<button @click="counterDown()">-</button>code>
</div>
</template>
<style scoped>
</style>
总结:在script中使用setup声明的优点,声明即存在,因为存在和代码冗余,不需要返回数据类型或方法
3. Vue视图渲染技术及其语法
模板语法:命令
删除原本的vue3默认样式设置:
删除components文件夹中的.vue文件删除main.js中的全局样式文件删除App.vue中的三个主标签中的所有内容
插值表达式
语法
插值表达式语法:
{ {数据名字、函数名、对象调用API}}
如果调用的数据的名字,则将名字渲染到对应的位置
如果调用的事函数名,则将函数返回值渲染到对应的位置
可以在双大括号中传入对象,同时调用相对应的API
<script setup>
// 准备
let msg = "hello world"
let getMsg=()=>{
return "hello world222"
}
let age = 16
let bee = "蜜蜂 嗡嗡"
let carts = [{name:"可乐",price:3,number:6},{name:"薯片",price:1.5,number:8}]
function priceAll(){
let count = 0
// 在前端的增强for循环第一个定义的不是数组对象,而是数组的第几个
for(let index in carts){
count += carts[index].price*carts[index].number
}
return count
}
</script>
<template>
<!--示例-->
<div>
<h1>{ {msg}}</h1>
</div>
msg 标签的额值为:{ {getMsg()}}<br>
年龄:{ { age }} 是否成年?{ { age > 18 ? "是": "否" }}<br>
{ {bee.split(' ').reverse().join('')}}<br>
{ { priceAll() }}
</template>
渲染双标><
中的文本(还挺可爱)
v-text和v-html语法:
v-text不支持html的标签识别,直接展示html标签的文本
v-html支持识别html的标签
<!--测试准备-->
<script setup>
let msg = "hello world"
// 命令支持模板字符串
let ddd = "die"
let msg2 = `nobody will ${ddd}`
let age = 19
let bee = '蜜 蜂'
</script>
<!--测试-->
<template>
<h1 v-text="msg"></h1>code>
<h1 v-text="msg2"></h1>code>
<h1 v-text="`you will ${ddd}`"></h1>code>
<h1 v-text="age>=18?'成年':'未成年'"></h1>code>
<h1 v-text="bee.split(' ').reverse().join('')"></h1>code>
</template>
属性渲染命令
v-bind语法:
v-bind支持识别""中的变量
v-bind:属性名 可以简写为 :属性名
<!--测试准备-->
<script setup>
const data={
logo:"https://s21.ax1x.com/2024/07/11/pkhhICn.md.jpg",
name:"linus",
url:"https://www.bilibili.com/"
}
let urlTest = "https://s21.ax1x.com/2024/07/11/pkhhICn.md.jpg"
</script>
<!--测试-->
<template>
<div>
<a v-bind:href="data.url">code>
<img v-bind:src="data.logo" :title="data.name">code>
</a>
</div>
</template>
事件渲染命令
v-on 语法
v-on:事件名可以简写为 @事件名
写法区别:
js vue onclick click ondbclick dbclick onblur blur onfocus focus
<!--测试准备-->
<script setup>
import {ref} from 'vue';
function fun1(){
alert("hi")
}
let counter = ref(1)
function fun2(){
counter.value ++
}
</script>
<!--测试-->
<template>
<button v-on:click="fun1()">hello</button>code>
<button @click="fun1()">hello</button> <br>code>
<!--内联事件-->
<button v-on:click="fun2()">+</button>code>
{ { counter }} <br>
<button v-on:click="counter ++">+</button>code>
{ { counter }} <br>
<!--事件的修饰符-->
<button v-on:click.once="fun2()">+</button>code>
{ { counter }} (这个加号只能使用一次)<br>
<!-- 组件原始的默认行为是否执行prevent修饰符 -->
</template>
响应式基础
响应式数据
将数据转换为响应式数据
两种方式:ref 、 reactive
ref方式:一般用于将数据转换为响应式数据
reactive方式:一般用于将对象转换为响应式数据
使用前都需要导包:
import{ref,reactive} from "vue"
<!--测试准备-->
<script setup>
import{ref,reactive} from "vue"
let counter = ref(10)
let person = reactive({
name:"",
age:12
})
function fun1(){
counter.value ++
}
function fun2(){
person.age ++
}
</script>
<!--测试-->
<template>
<button v-on:click="fun1()">+</button>code>
{ { counter }}
<button v-on:click="fun2()">+</button>code>
{ { person.age }}
</template>
两个渲染
条件渲染
当符合某一特定条件之后再对数据进行渲染
v-if命令:如果当前表达式为true,渲染当前元素,否则不渲染
v-else命令:自动和前一个v-if做取反操作
v-show命令:也可以使组件不展示,但是方式是通过css隐藏;而不是像v-if一样直接让页面不对其进行渲染
<!--测试准备-->
<script setup>
import {ref} from "vue"
let flag = ref(true)
</script>
<!--测试-->
<template>
<div>
<h1 id="h1" v-if="flag">vue is easy</h1>code>
<h1 id="h2" v-else>vue is not easy</h1>code>
<button @click="flag = !flag">toggle</button>code>
</div>
</template>
列表渲染
列表渲染
v-for:与li标签绑定,
<!--测试准备-->
<script setup>
import {reactive} from "vue"
let items = reactive([
{
id:"item1",
message:"可乐"
},
{
id:"item2",
message:"薯片"
},
{
id:"item3",
message:"炸鸡"
},
])
</script>
<!--测试-->
<template>
<div>
<ul>
<li v-for="item in items">{ { item.message }}</li>code>
</ul>
</div>
</template>
数据的双向绑定
单向绑定:改变js中的数据的值会响应式地影响dom树中的数据。但是如果用户修改界面(html)中的数据,js中的数据不会改变
双向绑定:
使用: v-model=“数据”
顺便回顾html中的组件属性
<!--测试准备-->
<script setup>
import {reactive} from "vue"
let user = reactive({
username:"",
userPwd:"",
habbits:[],
love:[],
introduct:"",
province:[],
local:""
})
function clearF(){
user.username='',code>
user.habbits.splice(0,user.habbits.length),
user.userPwd='',code>
user.love='',code>
user.introduct='',code>
user.province='',code>
user.local=''code>
}
</script>
<!--测试-->
<template>
<div>
<input type="text" v-model="user.username"><br>code>
<input type="password" v-model="user.userPwd"><br>code>
{ { user }} <br>
<br>
爱好<br>
唱 <input type="checkbox" v-model="user.habbits" value="sing"><br>code>
跳 <input type="checkbox" v-model="user.habbits" value="dance"><br>code>
rap <input type="checkbox" v-model="user.habbits" value="rap"><br>code>
篮球 <input type="checkbox" v-model="user.habbits" value="ball"><br>code>
<br>
性趣<br>
女 <input type="radio" v-model="user.love" value="woman"><br>code>
男 <input type="radio" v-model="user.love" value="man"><br>code>
<br>
简介<br>
<textarea v-model="user.introduct"></textarea>code>
<br>
籍贯<br>
<select v-model="user.local">code>
<option value="1">11</option>code>
<option value="2">22</option>code>
<option value="3">33</option>code>
</select><br>
<button @click="clearF()">清空</button>code>
</div>
</template>
属性计算(不常用)
<!--测试准备-->
<script setup>
import {reactive,computed} from "vue"
const author = reactive({
name:"张三",
books:["前端","后端","数据库"]
})
// 每次调用都会重新计算
function fun1(){
return author.books.length>0?"是":"否"
}
// 每次调用都会检查是否和上次调用的数据相同
let bookNum = computed(()=>{return author.books.length>0?"是":"否"})
</script>
<!--测试-->
<template>
<div>
<p>作者:{ { author.name }}</p>
是否出版过图书:{ { fun1() }} <br>
是否出版过图书:{ { bookNum }}
</div>
</template>
重新回顾SFC(组件传参)
测试组件拼接页面小练习以及组件之间参数的传递
文件目录结构(涉及多个vue文件)
<code><!--Content.vue-->
<script setup>
import {defineProps} from 'vue'
defineProps({
message:String
})
</script>
<template>
<div>
这里是展示主要内容
<h1>{ { message }}</h1>
</div>
</template>
<style scoped>
</style>
<!--Header.vue-->
<script setup>
</script>
<template>
<div>
欢迎:光临 <a href="#">退出登陆</a>code>
</div>
</template>
<style scoped>
</style>
<!--Navigater.vue-->
<script setup>
// 定义向父组件提交数据的事件和提交数据
import { defineEmits } from 'vue';
// 定义广播对象
const emits = defineEmits(["sendMenu"])
function send(data){
// 键值对方式提交数据
emits("sendMenu",data)
}
</script>
<template>
<div>
<ul>
<li @click="send('学员管理')">学员管理</li>code>
<li @click="send('图书管理')">图书管理</li>code>
<li @click="send('请假管理')">请假管理</li>code>
<li @click="send('考试管理')">考试管理</li>code>
<li @click="send('班级管理')">班级管理</li>code>
<li @click="send('教师管理')">教师管理</li>code>
</ul>
</div>
</template>
<style scoped>
</style>
<!--App.vue-->
<script setup>
import {ref} from 'vue'
import Header from './components/Header.vue'
import Navigater from './components/Navigater.vue'
import Content from './components/Content.vue'
let menu = ref("")
// 接受数据的方法
function recevier(data){
menu.value = data
}
</script>
<template>
<div>
<Header class="head"></Header>code>
<Navigater @sendMenu="recevier" class="navigater"></Navigater>code>
<Content class="content" v-bind:message="menu"></Content>code>
<h1>{ { menu }}</h1>
</div>
</template>
<style scoped>
.head{
height: 80px;
border: 1px solid red;
}
.navigater{
width: 15%;
height: 500px;
border: 1px solid green;
float: left;
}
.content{
width: 83%;
height:500px;
border: 1px solid yellow;
float: right;
}
</style>
4. 路由机制(router)
引入路由的目的:实现页面的切换
路由切换页面的实现方式:通过改变申请的url实现页面的切换
路由的使用
使用vite创建前端工程
下载路由相关依赖
npm install vue-router
修改main.js配置router
import { createApp } from 'vue'
import App from './App.vue'
import router from './routers/router'
const app = createApp(App)
app.use(router)
app.mount('#app')
在主vue页面添加<router-view>
标签
<template>
<div>
<!--router-link标签可以在子页面中使用-->
<router-link to="/home">home页</router-link> <br>code>
<router-link to="/list">list页</router-link> <br>code>
<router-link to="/add">add页</router-link> <br>code>
<router-link to="/update">update页</router-link> <br>code>
<!--一定要在需要轮播的主页面上添加router-view标签-->
<router-view></router-view>
</div>
</template>
配置路由的映射路径
/*导入创建路由对象需要使用的函数*/
import { createRouter,createWebHashHistory} from 'vue-router'
// 导入.vue组件
import Home from "../components/Home.vue"
import List from "../components/List.vue"
import Add from "../components/Add.vue"
import Update from "../components/Update.vue"
//创建一个路由对象
const router =createRouter({
//history属性用于记录路由的历史
history : createWebHashHistory(),
// 定义路径和组件之间的对应关系
routes:[
{
path:"/home",
component:Home
},
{
path:"/list",
component:List
},
{
path:"/add",
component:Add
},
{
path:"/update",
component:Update
},
{
path:"/",
component:Home
},
// 重定向
{
path:"/showAll",
redirect:"list"
}
]
})
//向外暴露router
export default router
定义各个页面的信息
……
注意:
在5.
的映射路径中如果要指定映射到哪一个名字的router-view
组件,可以采用如下写法
routes:[{
path:"/home",
component{
homeView:Home
// router-view名:子页面别名
}
}]
注意:
也可以不是单纯使用router-vue包中的接口,也可以设置方法来控制路由
<!--准备-->
<script setup>
import {useRouter} from 'vue-router'
const router = useRouter()
function showList(){
router.push("/list")
}
</script>
<!--测试-->
<template>
<div>
<!--router-link标签可以在子页面中使用-->
<router-link to="/home">home页</router-link> <br>code>
<router-link to="/list">list页</router-link> <br>code>
<router-link to="/add">add页</router-link> <br>code>
<router-link to="/update">update页</router-link> <br>code>
<button @click="showList()">list</button>code>
<!--一定要在需要轮播的主页面上添加router-view标签-->
<router-view></router-view>
</div>
路由接收参数
略
路由守卫
页面跳转前后的代码逻辑
操作:略
5. vue3数据交互 axios(处理异步请求)
axios是原生代替Ajax的解决方案
前置学习:promise
特点
只有三种状态:进行中、成功、失败一旦改变,不会再次改变
promise在html中的用法(后面有更简洁的)
<script>
let promise =new Promise(function(resolve,reject){
console.log("promise do some code ... ...")
//resolve("promise success")
reject("promise fail")
})
console.log('other code1111 invoked')
//2.获取回调函数结果 then在这里会等待promise中的运行结果,但是不会阻塞代码继续运行
promise.then(
// 成功时
function(value){ console.log(`promise中执行了resolve:${ value}`)},
// 失败时
function(error){ console.log(`promise中执行了reject:${ error}`)}
)
// 3 其他代码执行
console.log('other code2222 invoked')
</script>
asyc声明回调函数
<script>
async function fun1(){ }
</script>
axios简介
axios是vue封装好的专门用于发送Ajax请求的API包
axios的使用
<script setup>
import axios from "axios"
import {ref,reactive} from "vue"
// 这个变量作用域一定要大!
let message = reactive({
"code":1,
"content":"hahaha"
})
function getLoveWords(){
// return axios({
// method:"post",
// url:"https://api.uomg.com/api/rand.qinghua?format=json",
// data:{
// },
// params:{
// format:'json',
// username:"张三"
// }
// })
return axios.get("https://api.uomg.com/api/rand.qinghua?format=json?format=json")
}
async function getNews(){
// let response = await getLoveWords()
let {data} = await getLoveWords()
// Object.assign(message,response.data)
Object.assign(message,data)
}
</script>
还有一个拦截器,大概和后端的拦截器差不多吧,就这样了,今天学习的劲头真糟糕。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。