赞
踩
vue的核心功能:声明式渲染
和响应性
渐进式框架vue 理解:功能逐步完善的过程
声明式渲染
:Vue扩充了html语法使其能够声明式响应js
响应性
:在改变js代码的同时html组件的内容自动改变,不需要使用按钮等组件手动触发文本改变
如果不以管理员身份打开vscode,将会导致不能再vscode使用终端访问npm命令
npm create vite
这里是vue框架和JavaScript语言
cd ***# 你自己的项目名
npm install # npm i
npm run dev # 以测试环境启动项目(在package.json中自定义)
ctrl + c
工程文件讲解:不可能给你讲的,先多练,练多了才一讲就通
SFC是Vue的一种规范(Single-File Component):
vue里面含有前端三件套的语法,然后html
通过ES6
语法导入.vue文件
实现前端页面的显示。(导入方式见前置知识)
.vue文件
标准的.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文件中导入即可
<!-- 使用ES6语法实现 --> <script type="module"> 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> <span v-text="counter"></span> <button @click="counterDown()">-</button> </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> <span v-text="counter"></span> <button @click="counterDown()">-</button> </div> </template> <style scoped> </style>
总结:在script中使用setup声明的优点,声明即存在,因为存在和代码冗余,不需要返回数据类型或方法
删除原本的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> <h1 v-text="msg2"></h1> <h1 v-text="`you will ${ddd}`"></h1> <h1 v-text="age>=18?'成年':'未成年'"></h1> <h1 v-text="bee.split(' ').reverse().join('')"></h1> </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"> <img v-bind:src="data.logo" :title="data.name"> </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> <button @click="fun1()">hello</button> <br> <!--内联事件--> <button v-on:click="fun2()">+</button> {{ counter }} <br> <button v-on:click="counter ++">+</button> {{ counter }} <br> <!--事件的修饰符--> <button v-on:click.once="fun2()">+</button> {{ 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> {{ counter }} <button v-on:click="fun2()">+</button> {{ 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>
<h1 id="h2" v-else>vue is not easy</h1>
<button @click="flag = !flag">toggle</button>
</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> </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='', user.habbits.splice(0,user.habbits.length), user.userPwd='', user.love='', user.introduct='', user.province='', user.local='' } </script> <!--测试--> <template> <div> <input type="text" v-model="user.username"><br> <input type="password" v-model="user.userPwd"><br> {{ user }} <br> <br> 爱好<br> 唱 <input type="checkbox" v-model="user.habbits" value="sing"><br> 跳 <input type="checkbox" v-model="user.habbits" value="dance"><br> rap <input type="checkbox" v-model="user.habbits" value="rap"><br> 篮球 <input type="checkbox" v-model="user.habbits" value="ball"><br> <br> 性趣<br> 女 <input type="radio" v-model="user.love" value="woman"><br> 男 <input type="radio" v-model="user.love" value="man"><br> <br> 简介<br> <textarea v-model="user.introduct"></textarea> <br> 籍贯<br> <select v-model="user.local"> <option value="1">11</option> <option value="2">22</option> <option value="3">33</option> </select><br> <button @click="clearF()">清空</button> </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>
测试组件拼接页面小练习以及组件之间参数的传递
<!--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>
</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> <li @click="send('图书管理')">图书管理</li> <li @click="send('请假管理')">请假管理</li> <li @click="send('考试管理')">考试管理</li> <li @click="send('班级管理')">班级管理</li> <li @click="send('教师管理')">教师管理</li> </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> <Navigater @sendMenu="recevier" class="navigater"></Navigater> <Content class="content" v-bind:message="menu"></Content> <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>
引入路由的目的:实现页面的切换
路由切换页面的实现方式:通过改变申请的url实现页面的切换
使用vite创建前端工程
下载路由相关依赖
npm install vue-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')
<router-view>
标签<template>
<div>
<!--router-link标签可以在子页面中使用-->
<router-link to="/home">home页</router-link> <br>
<router-link to="/list">list页</router-link> <br>
<router-link to="/add">add页</router-link> <br>
<router-link to="/update">update页</router-link> <br>
<!--一定要在需要轮播的主页面上添加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> <router-link to="/list">list页</router-link> <br> <router-link to="/add">add页</router-link> <br> <router-link to="/update">update页</router-link> <br> <button @click="showList()">list</button> <!--一定要在需要轮播的主页面上添加router-view标签--> <router-view></router-view> </div>
略
页面跳转前后的代码逻辑
操作:略
axios是原生代替Ajax的解决方案
<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>
<script>
async function fun1(){}
</script>
axios是vue封装好的专门用于发送Ajax请求的API包
<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>
还有一个拦截器,大概和后端的拦截器差不多吧,就这样了,今天学习的劲头真糟糕。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。