赞
踩
栈内存:存放基本数据类型的变量名和变量值;复杂(引用)数据类型的变量名和引用地址
堆内存:复杂数据类型的变量值
1.let命令
var 和 let的区别(var的三大bug):
2.const命令
是一个只读的常量,声明时,必须赋初值,一旦声明,栈值就不能改变,
3.变量的结构赋值
包括数组和对象的结构赋值
数组: let [a, b, c] = [10, 20, 30];
对象:let { name1, age1 } = { name1: ‘李四’, age1: 29 };
4.对象的扩展
包括属性的简写,方法的简写,扩展运算符,模版字符串
属性的简写::当属性名和值的变量名相同时,触发对象的属性简写let name = ‘张三’; const person ={name}
方法的简写:去掉冒号和function,
eat() {
return ‘三顿’
}
扩展运算符:三个点(…).可遍历属性。.三个点放在对象前,用于对象的合并等
let z = { a: 10, b: 20 }
let n = { …z, c: 30 };
console.log(n) // {a: 10, b: 20, c: 30}
模版字符串:模板字符串用反引号()表示,嵌入变量用${}表示 let idCard = '360424198612121539'; let str =
身份证号码${idCard} `
5.箭头函数
主要针对的是函数变量,即带有函数名的函数;使用箭头( => )连接参数列表和函数体
箭头函数的简化:
参数只有一个时,括号可以省略
const say = msg => {
函数体
}
无参数时,括号不能省略
const say = () => {
函数体
}
参数多个时,括号不能省略
const say = (x,y) => {
函数体
}
可变参数,括号不能省略
const say = (…args) => {
函数体
}
函数体只有一条return时,可以省略大括号和return关键字
const say2 = x =>x+1
函数体包含多条语句时,不可以省略大括号和return关键字
函数体中有一个对象时,省略大括号和return关键字后需要用小括号
-const student2 = () => ({ name: ‘张三’, age: 25 })
6.模块语法
export:规定模块的对外接口,如果希望外部能够获取模块内的某个变量/函数/类,就必须在模块中使用export输出该变量/函数/类
const PI = 3.1415
const add = (a, b) => a + b
export { PI as pi, add } //可以合在一起导出,也可以分别导出
import:引入模块
//import { pi as PI, add } from ‘./demo1.js’
import * as abc from ‘./demo1.js’ // 导入全部
console.log(‘pi的值为:’, abc.pi)
console.log(‘调用add函数:’, abc.add(40, 50))
export default:每个模块【只能够使用一次】,可以导出变量,常量,函数,类,匿名函数
export default (a, b) => a + b //默认导出的是匿名函数
对于export default导出的,导入时,不需要{},并且变量名可以随意
import 你家的孩子 from ‘./demo2.js’
console.log(‘变量值为:’, 你家的孩子(3, 6))
7.Promise异步编程
Promise对象要点:
原理:异步执行,当接口请求后,可以去做其他事情,等接口返回成功再渲染页面,接口返回失败也会有相应的提示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>8-1 promise对象.html</title> </head> <body> <script> /* Promise对象要点: 1.Promise对象是用于执行异步操作的 2.可以使用Promise构造函数来创建实例对象 3.Promise对象的.then方法调用后,返回的还是一个Promise对象 4.Promise对象的.catch方法调用后,返回的还是一个Promise对象 */ /* 步骤1:创建Promise对象 1.调用构造函数,来创建Promise对象 2.构造函数的参数,是一个函数【参数是函数】,它负责执行业务 3.该函数接受2个参数作为参数 4.第一个参数:是resolve(成功的)函数,可以是其他 5.第二个参数:是reject(拒绝的)函数 */ const p1 = new Promise((resolve, reject) => { console.log('1.异步请求开始,异步讨债开始') // 去讨债开始...... // ......漫长的过程,....可以去干其它事情.... // 讨债结束..... const flag = false if (flag) { //resolve方法执行后,则执行then的第一个参数 return resolve('还钱成功!')//异步调用,只支持一个参数(可以是一个对象) } else { return reject('还钱失败!')//它们前面加上return语句,这样就不会有意外。 } }) /* 要点: 1.then方法,也接收2个函数作为参数,但第二个参数是可选的 2.当resolve方法调用时,会触发then的第一个参数 3.当rreject方法调用时,会触发then的第二个参数 */ //步骤2:调用异步执行.then方法 const p2 = p1.then((a) => { // throw new Error('4.人为模拟异常,还的钱是假钱...') console.log('3.进来了then的第一个方法,还钱成功了,用钱干什么,买手机。。。', a) } // , () => {//第二个参数是可选的 // console.log('3.进来了then的第二个方法,,还钱失败了,怎么办。。。') // } )//还可以继续.then /* 要点: 1.catch方法,也接收1个函数作为参数 2.当【前面】的方法中有异常时,才会触发catch的参数 */ // 步骤3.调用catch方法,then方法有效 const p3 = p2.catch((e) => { console.log(`catch方法被调用了${e}`) }).finally(() => { //无论如何都会执行 console.log('finally') }) console.log('2.底部的代码调用了,将在当前脚本所有同步任务执行完才会执行点then异步代码') //Promise 新建后立即执行,所以首先输出的是Promise。 //然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。 </script> </body> </html>
1.在本地电脑创建一个文件夹
2.终端进入文件夹,创建项目:npm create vue@3,命名项目名称,出现如下界面
3.VSCode编辑器中,在终端执行一下命令,初始化并启动项目
4.页面执行顺序
创建一个vue组件,main.js中导入该vue组件,挂载文件index.html 就可以找到该组件并运行在浏览器中
//main.js文件 import { createApp } from 'vue' //不是路径的话,必须package.json中定义,dependencies import { createPinia } from 'pinia'//{}是采用export形式导出的 //import App from './App.vue'//export default导出的,App这个名字可以任意取。 import App from './components/CaoQing.vue' import router from './router' //会找router文件下的index.js import './assets/main.css' //创建vue实例化对象 const app = createApp(App) //app名字上随便的 //使用第三方插件/库 app.use(createPinia()) app.use(router) //把创建的vue实例,挂载到 index.html app.mount('#app') //括号里的app要和index.html里的<div id="app"></div>的id一致 //总结:把开发的vue组件放到index.html里运行 //main.js:入门文件/主文件 //App.vue :根组件 //index.html ://挂载文件 //.vue结尾的都叫一个组件,打包工具会把组件打包成一个js,js会加上export default //三个地方可以放组件:components:公共组件 views:业务组件 App.vue:src根目录下
//index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
创建组件,组件名首字母要大写,以.vue后缀表示组件,装的插件有自动补全功能,所以只需要输入vbase,选择弹出的含有reactive的模版。Vue3的基本指令都是在template模版中使用,以下是模版简介
<template> <!-- 第一部分:template模版,相当于html的body部分,是必须的 --> <!-- 在模版中可以【直接使用】返回对象中的属性/方法 --> <div>响应式对象计数:{{ count }}</div> <div>普通对象计数:{{ count1 }}</div> <div>响应式变量计数:{{ age }}</div> </template> <script> //第二部分:js部分 import { onMounted, reactive, ref, toRefs } from 'vue' export default { //1.setup函数,是一个生命周期函数,是组合式API的起点 //它比较特殊,无需从vue中导入,其他的周期函数都需要导入才能使用,而且其他生命周期函数都需要在setup函数使用 setup() { //2.定义一个【响应式】对象 =》页面会变化 const state = reactive({ count: 0 }) //定义一个【普通】对象 =》页面不会变化 const state1 = { count1: 0 } //2.【响应式】变量 =》页面会变化 const age = ref(0) //3.定义一个函数,方法不存在收否响应 const addOne = () => { state.count += 1 state1.count1 += 1 age.value += 1 } //4.生命周期函数:当页面加载完成后,才会执行 onMounted(() => { //5.每隔多久执行某个代码/函数 setInterval(addOne, 1000) }) //以上定义的属性和方法必须返回,模板中才能使用 //注意:如果是响应式对象里的变量,就不需返回模版里也可以使用 return { age, //toRefs:把一个【响应式】对象,转换成普通对象,该普通对象的每一个属性值都是ref类型 //三个点是扩展运算符,取出对象的所有可遍历属性 ...toRefs(state), ...state1 } } } </script> <style lang="scss" scoped> </style>
(1)文本插值
数据绑定最常见的形式就是使用双大括号的文本插值,基本语法:{{ 变量/数组/对象等 }}
(2)v-text指令 和 v-html指令
键盘常用事件:
v-on用于:基本语法 <标签 v-on:事件名=“事件的处理方法或脚本”><标签/>
缩写是@:<标签 @事件名=“事件的处理方法或脚本”><标签/>
(8)v-model(表单输入绑定)
所谓表单,指的是html的input ,select,textarea等表单的元素,v-model实现和这些标签数据的双向绑定,监听用户的输入事件来更新数据。它本质上是一个语法糖,实际上就是v-bind:value + v-on:input的组合。
双向绑定:用javascript命令改变数据的值时,会在页面中自动重新渲染内容,改变文本框的内容也会自动修改绑定的数据(可在控制台看,以便于存放修改后的数据到数据库)。
可用于文本框,单选框,复选框,下拉列表,多行文本框的绑定
基本语法:<标签 v-model=“响应式数据”><标签/>输入框可以.number 限制只输入数字,.trim 去除左右空格。例如v-model.number和v-model.trim
1.计算属性:
使用computed方法实现,方法参数是一个函数,它必须有return返回值,在该函数中,任意一个响应式数据发生变化,computed方法都将自动重新运算,视图也会同步更新,默认第一次就会调用。
2.侦听属性:
使用watch方法实现,该方法有三个参数:
3.watchEffect:
和watch功能类似,不同的是 它会自动监听其内部回调函数使用到的数据,其中任意一个数据发生了变化,它都会执行回调函数,首次加载就会执行一次。
只有一个参数,该参数是一个函数
4.总结
计算属性:
watchEffect
和watch功能类似,不同的是:
1.组件的常用的生命周期
创建-》挂载-》更新-》销毁
以下代码说明:
<template> <div class="about"> <h1>This is an about page(生命周期)</h1> <div> <input type="radio" name="xb" value="1" v-model="sex" />男 <input type="radio" name="xb" value="2" v-model="sex" />女 </div> </div> </template> <style> @media (min-width: 1024px) { .about { min-height: 100vh; display: flex; align-items: center; } } </style> <script> import { onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated, reactive, toRefs } from 'vue' export default { setup() { //第一阶段:创建 console.log('1~2.setup()函数开始了!!!!相当于vue2的(BeforeCreate、Created)') const state = reactive({ count: 0, sex: 1 }) //阻塞的睡眠函数(delay参数:N毫秒) //普通函数 function sleep2(delay) { //当前时间 const start = new Date().getTime() //执行的时间4 小于 设定的等待时间5 就继续等待,如果6大于等待的时间5,则跳出循环不再等待执行下一步骤 while (new Date().getTime() - start < delay) { //继续,调用while continue } } //箭头函数 const sleep = (delay) => { //当前时间 const start = new Date().getTime() //执行的时间4 小于 设定的等待时间5 就继续等待,如果6大于等待的时间5,则跳出循环不再等待执行下一步骤 while (new Date().getTime() - start < delay) { //继续,调用while continue } } //第二阶段:挂载,组件被挂载到index.html上 //2。挂载前 onBeforeMount(() => { console.log('3.onBeforeMount被调用了!(挂载前。。。。)') // 在组件挂载到index.html之前,睡大觉。睡5秒 sleep(3000) }) onMounted(() => { console.log('4.onMounted被调用了!(挂载后。。。。)') }) //第三阶段:数据更新 onBeforeUpdate(() => { console.log('5.onBeforeUpdate被调用了!(更新前。。。。)') }) onUpdated(() => { console.log('6.onUpdated被调用了!(更新后。。。。)') }) //第四阶段:销毁阶段,vue组件被销毁,即点击其他组件时,当前组件被销毁 onBeforeUnmount(() => { console.log('7.onBeforeUnmount被调用了(组件失效了。。。)!') }) onUnmounted(() => { console.log('8.onUnmounted被调用了!(组件失效且销毁了。。。)') }) return { ...toRefs(state) } } } </script>
2.组件的使用步骤
<template> <div> <h2>组件的使用步骤</h2> <h3>这里是父组件-FatherComp.vue</h3> <!-- 步骤3:使用子组件 --> <!-- 单标签 --> <!-- <ChildComp /> --> <!-- 标签对 --> <child-comp></child-comp> <!-- <ChildComp></ChildComp> --> </div> </template> <script> import { reactive, toRefs } from 'vue' //步骤2-1:导入子组件 import ChildComp from './ChildComp.vue' export default { //步骤2-2:注册子组件 components: { ChildComp }, setup() { const state = reactive({ count: 0 }) return { ...toRefs(state) } } } </script> <style lang="scss" scoped> </style>
3.父组件传递数据给子组件(80%以上用这个)
前提是:父子组件已经关联,参考2进行关联
<child-comp v-bind:ccount="count" v-bind:cname="name" :clistObj="listObj"></child-comp>
<template> <div> <h4 style="color: red">这里是子组件-ChildComp.vue</h4> <!-- 子组件渲染 --> <h5>这里是从父组件传递过来的ccount的值:{{ ccount }}</h5> <p>这里是从父组件传递过来的cname的值: {{ cname }}</p> <p>这里是从父组件传递过来的clistObj的值: {{ clistObj }}</p> <ul> <li v-for="(obj, index) in clistObj" :key="index">{{ obj.id }}-{{ obj.realName }}</li> </ul> </div> </template> <script> import { reactive, toRefs, ref, watch, watchEffect } from 'vue' export default { // props: ['ccount', 'cname', 'clistObj'], //Number、String、Array、Object等等 //导入父组件模版中定义的值 props: { ccount: Number, cname: String, clistObj: Array }, setup(props) { const state = reactive({ count: 0, ccount: 0 //定义一个响应式变量,接收父组件传过来的变更的值 }) //因为只执行一次,所以值一直不变 // console.log('拿到的props的值为:', props.ccount) // 如果ccount 在setup中,也需要有响应式,怎么办? // 可以采用:侦听器 watch( () => props.ccount, () => { console.log('调用了watch方法。') state.ccount = props.ccount console.log('拿到的props的值为:', state.ccount) }, { immediate: true } ) //父组件值改变,子组件值跟着改变,方便存储到数据库 // watchEffect(() => { // console.log('进来了watchEffect') // state.ccount = props.ccount // console.log('拿到的props的值为:', state.ccount) // }) return { // result, ...toRefs(state) } } } </script> <style lang="scss" scoped> </style>
4.子组件传递数据给父组件(用的比较少)
前提是:父子组件已经关联,参考2进行关联
/* setup接收2个参数,第一个是props,它为响应式对象。第二个参数context,它是非响应式对象 context对象包括三个属性:emit(方法)、slots(插槽对象)、attrs(attribute对象) context:{ emit:()=>{}, slots:{}, attrs:{} } 我们也可以对它进行解构 */ setup(props, { emit }) { const state = reactive({ count: 10000, name: '小马云', obj: { name: '张三', age: 29 }, objList: [ { id: 1, name: '张三', age: 22 }, { id: 2, name: '李四', age: 23 }, { id: 3, name: '王五', age: 25 }, { id: 4, name: '李世民', age: 27 }, { id: 5, name: '朱元璋', age: 30 } ] }) const sendMsg = () => { console.log('调用了子组件的传值方法。。。') //传给父组件 //两个参数:1.事件名,由父组件的模版调用;2.要传递的数据 emit('caoqq', state.count, state.name, state.obj, state.objList) }
<template> <div> <h2 style="color: pink">【子组件传递数据给父组件】</h2> <h3 style="color: green">这里是父组件-FatherComp.vue</h3> <!-- 步骤3:使用子组件 --> <!-- 标签对 --> <!-- caoqq是子组件中emit函数的事件名 --> <child-comp @caoqq="getData"></child-comp> </div> </template> <script> import { reactive, toRefs } from 'vue' //步骤2-1:导入子组件 import ChildComp from './ChildComp.vue' export default { //步骤2-2:注册子组件 components: { ChildComp }, setup() { const state = reactive({ count: 0 }) //方法里的参数要和子组件中emit的一致,也可以用可变参数接收 const getData = (data, name, obj, objList) => { console.log( '父组件接受了子组件传过来的值:count的值为:', data, 'name的值:', name, 'obj的值:', obj, 'objList的值:', objList ) // state.count = data }
1.动态组件
场景:在一个父组件中同时引用三个子组件,我们想一次只显示一个组件,当点击某个按钮时,切换显示不同的组件,要实现这种组件动态显示效果,vue提供了 compoent标签,语法如下:
<compoent :is="要显示的组件名" ></compoent> //采用v-bind指令绑定is属性
<template> <div> <h3>这里是父组件</h3> <!-- 使用动态使用子组件 --> <!-- component:is ,is的值是哪个组件的名称就显示哪个组件 --> <component :is="selectTab"></component> <!-- 选择需要显示的组件 --> <select v-model="selectTab"> <option value="TabOne">选项卡一</option> <option value="TabTwo">选项卡二</option> <option value="TabThree">选项卡三</option> </select> <div>选项内容:{{ selectTab }}</div> </div> </template> <script> import { reactive, toRefs } from 'vue' //导入子组件 import TabOne from './TabOne.vue' import TabTwo from './TabTwo.vue' import TabThree from './TabThree.vue' export default { //注册子组件 components: { TabOne, TabTwo, TabThree }, setup() { const state = reactive({ count: 0, selectTab: 'TabOne' }) return { ...toRefs(state) } } } </script>
2.插槽的使用
分为默认插槽(不具名插槽)和具名插槽
插槽:在子组件中留插槽,想让内容显示在什么位置,就把插槽放在哪里,插槽显示的内容是在父组件中写的。如果子组件定义了默认插槽,其他内容将显示在默认插槽中,如果定义了具名插槽具名插槽的内容将显示在具名插槽中,如果没有定义默认插槽,其他内容将不会显示
:<slot></slot>
<div><slot name="zhangsan"></slot></div> 其中name,是父组件中定义的插槽名
,父组件模版中需要定义以下格式: <template v-slot:zhangsan>具名插槽内容-章三</template>, v-slot: 可以缩写成 #
<!-- 在父组件中添加内容,这些内容将展示在子组件的插槽中 -->
<child-comp>
<!-- 这是不具名(默认)插槽要显示的内容 -->
这里是父组件传给子组件展示的默认插槽内容11: {{ count }}
<!-- 这是具名插槽要显示的内容 -->
<!--需要用到template标签, -->
<template v-slot:zhangsan>具名插槽内容-章三</template>
<!--需要用到template标签, -->
<template #lisi>简写具名插槽内容-李四</template>
</child-comp>
3.响应式变量的定义
三种方式定义响应式变量
setup() { //定义响应式变量state,但是state里的属性是没有响应式的 const state = reactive({ count: 0, name: '张三' }) //toRef接收两个参数:源响应式对象 和 该对象的属性名(指定属性),返回一个ref数据 // 采用toRef函数,为响应式对象的某个属性,添加响应式 const conut2 = toRef(state, 'count') setInterval(() => { state.count += 1 }, 1000) //return中的变量在模版中可以直接用 return { age: 22, //也属性响应式变量,可直接使用 conut2, count3: toRef(state, 'count'), // 1.toRefs,用来把响应式对象中的属性,变成响应式 ...toRefs(state) // ...state //count就没有响应式了 } }
5.模版引用
可以获取元素的具体信息
//...1.从vue-router中导入createRouter, createWebHistory import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' //。。。2.导入HomeView组件 import Home from '../views/Home.vue' //。。。。。3,使用createRouter方法创建一个路由器对象 const router = createRouter({ //路由模式1:history模式(参数:导入环境变量中的基础URL),也可以不写括号里的内容 // history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(), //路由模式2:hash模式 // history: createWebHashHistory(), routes: [ //每一个路由,都是一个对象,它包括三个属性:path,【name】,[component/redirect二选一] { path: '/',//根路由,路由的路径 name: 'home', //路由的名称 可以省略 component: Home }, { path: '/login', // route level code-splitting 路由级代码拆分 //这将为此路由生成一个单独的模块(About.4543054354dfgdf.js) // this generates a separate chunk (About.[hash].js) for this route // 当访问路由时,是懒加载的 // which is lazy-loaded when the route is visited. // 总结:路由懒加载方式,项目打包时,一个组件打包为一个js文件。访问时才加载组件。 // component: () => import('../views/AboutView.vue') component: () => import('../views/Login.vue') } ] }) export default router //导出路由器
路由是用来实现页面导航的,导航分为两种:
声明式导航:在模板中声明路由链接,最终形成a标签导航
编程式导航:通过调用 JavaScript 形式的API实现导航,适合页面重定向,比 如登录成功后重定向到主页
(1)路由链接的代码如下(声明式导航的实现):
<!-- 作用:RouterLink会被渲染成一个a标签,它的to属性,会被渲染成a元素的href属性 -->
<!-- 好处:可以给to属性绑定变量(对象),to的值等于路由配置中的path -->
<RouterLink to="/about">About</RouterLink>
<RouterLink :to="{ path: '/', query: { a: '123', b: '456' } }">Home</RouterLink>
(2)路由填充位(路由占位符 )
通过路由规则匹配到的组件后,将组件的内容 渲染到路由占位符所在的位置(想在哪个组件里显示内容就在该组件留路由占位符,比如点击A组件中的【按钮】希望A组件内容在B组件展示,那么A组件和B组件就需要有关系,在同一Web网友中)。路由占位符的代码如下:
<RouterView />
或
<router-view />
或
<router-view></router-view>
总结:前端页面访问的路由在根组件App.vue里找,找到后去index.js,找到对应的组件,将组件的内容在路由占位符中显示
官网:https://element-plus.gitee.io/
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' //样式
import zhCn from 'element-plus/es/locale/lang/zh-cn'
const elementConfig = { size: 'default', local: zhCn, zIndex: 3000 }
app.use(ElementPlus, elementConfig)
main.js中全局导入自定义样式:import ‘./assets/css/common.scss’
import * as Icons from '@element-plus/icons-vue'
// 1.注册全局elementplus icon组件 Object.keys(Icons).forEach((key) => {
app.component(key, Icons[key])
})
<el-icon><CirclePlus /></el-icon >
import { ElMessage } from 'element-plus'
# 用法一
ElMessage.type('消息内容')
// 其中:type可替换为:success、warning、info、error
# 用法二 ElMessage({
message: '消息内容',
type: 'success',// 其中:type值可为:success、warning、info、 error
})
跟缓存类似,本地存储(新增、获取、删除、清空全部)
在浏览器的Applicationd的Local Storage下的地址中查看
// A.新增
// localStorage.setItem('userName', 'caoqq')
// localStorage.setItem('userId', '123')
// localStorage.setItem('token', 'wfffdsfd')
// B.获取
// console.log('userId====', localStorage.getItem('userId'))
// C.删除
// localStorage.removeItem('userName')
// // D.清空所有
// localStorage.clear()
Axios是一个基于Promise的HTTP库,可以用在浏览器和node.js中。用于向服 务器后端发起Ajax请求,并在请求的过程中可以进行很多控制,其主要特性如下:
Axios的安装:$ npm install axios
Axios的使用:两种方式,代码如下:
// 第一步:导入axios库 import axios from 'axios' // 第二步:编写请求配置 const config = { url: '/token/', method: 'post', baseURL: 'http://地址/api', data: { username: "账号", password: "密码", captcha: "9999", captchaKey: 1157 } } //第三步:发送网络请求 axios(config).then((res) => { console.log('res的值为:', res) console.log('res对象中的data为:', res.data) }).catch((e) => { console.log('异常响应对象为:', e.response) console.log('异常响应状态码为:', e.response.status) console.log('请求异常') })
// 第一步:导入axios库 import axios from 'axios' // 第二步:编写请求配置 const config = { baseURL: 'http://地址/api', } // 第三步:采用别名的方式发送请求 //语法格式:axios.post(url[, data[, config]]) axios.post('/token/', { username: "账号", password: "密码", captcha: "9999", captchaKey: 1157 }, config ).then((rep) => { console.log('res对象中的data为.data', rep.data) }).catch()
总结:在实际应用中会封装Axios
定义一个js文件,包括
通过调用 JavaScript 形式的API实现导航,适合页面重定向
//...1.参数为路径字符串
router.push('/about')
//...2.参数为对象-path属性
router.push({ path: '/about' }) //...3.参数为对象-name属性
router.push({ name: 'About' }) //...4.参数为对象-带查询参数
router.push({ name: 'About', query: { a: 'Hello' } })
1.主页布局
引用Element Plus布局,主页布局我们采用 左右结构 ,右边采用 上下结构
效果图如下:
3.左侧边栏组件注意内容
点击接口自动化下的各子组件时MutiTabs.vue组件会展示对应的内容
//父子路由 children: [ { path: '/cases', // 根路由,路由的路径 name: '测试用例', component: () => import('../views/sqtp/Cases.vue') }, { path: '/requests', name: 'web接口', component: () => import('../views/sqtp/Requests.vue') }, { path: '/plans', name: '测试计划', component: () => import('../views/sqtp/Plans.vue') }, { path: '/reports', name: '测试报告', component: () => import('../views/sqtp/Reports.vue') }
pinia 都是状态管理库,用于跨组件(页面)进行状态共享,应用中,存在某些变量需要跨组件共享时,应该使用状态管理库。一个 Store 是一个存储实体,它有 state 、 getters 和 actions ,相当于组件中的 响应式数据 、 计算属性 和 方法 。
import { createPinia } from 'pinia'
app.use(createPinia())
import { defineStore } from 'pinia' import { ref, computed } from 'vue' // Setup方式定义Store export const useUserStore = defineStore('user2', () => { // 1.定义响应式变量 const count = ref(40) const name = ref('张三') // 2.定义计算属性 const doubleCount = computed(() => count.value * 2) // 3.定义方法 const addOne = () => { count.value++ } // 4.返回 return { count, name, doubleCount, addOne } })
import { useUserStore } from '@/stores/user' // 1.导入一个store
export default {
setup() {
const store = useUserStore()
return {
} }
}
// 采用storeToRefs()、toRefs()函数解构,保留响应式 。记得要导出
const { count, name, doubleCount, addOne } = toRefs(store)
// $patch()方法修改(批量修改)
store.$patch({
count: store.count + 1,name: '李四' })
需求:根据当前登录的用户,从后端动态获取对应的菜单,进行格式转换后,存到本地存储中
(1)menuTree:左侧菜单数据
2)menuList: 按钮权限数据,类似:
“menuPermission”:
[“Retrieve”, “Update”, “Search”,“Create”, “Build”, “Delete”]
碰到的问题:用户在未登录的情况下,仍然可以访问Home主页。这在实际项 目中是不允许的。如何在请求每条路由链接前,判断用户是否登录呢? Vue-rout提供了全局路由守卫来监听路由的进入与离开。程序员可以通过 Vue-router 提 供的 beforeEach (前置守卫)、 afterEach (后置守卫)两个钩子函数,来搞事 情。它们分别在路由改变前和改变后触发
在项目的 router/index.js 中,添加前置路由守卫,代码如下:
/* 前置路由守卫 to表示要跳转到哪里 from 表示从哪里来 next表示动作 让进入 */ router.beforeEach((to, from, next) => { // 进度条开始 NProgress.start() const userId = localStorage.getItem('userId') if (to.path === '/login') {//1.跳转到登录界面,放行 next(true) //或者next() } else if (userId) { // 2.有登录的,放行 next() } else {//其他情况(无登录,且非登录界面)都跳转到登录界面 next('/login') //进入登陆界面 } }) // 后置路由守卫 router.afterEach(() => { // 进度条结束 NProgress.done() }) // 进度条的配置项:ease可以设置css3动画,如ease,linear;speed是进度条从开始到结束的耗时 NProgress.configure({ ease: 'linear', speed: 500 })
xe-utils 提供了一套实用的基础函数、任意格式的日期转换函数,浏览器相 关操作函数等。提供了100多个函数,应有尽有。总之,如果你有判断、处理、转 换的一些需求,尽管来这里找找看。
官网地址:https://toscode.gitee.com/x-extends/xe-utils api
文档:https://x-extends.github.io/xe-utils/
npm install xe-utils
import XEUtils from 'xe-utils'
XEUtils.cookie('name') // 根据name获取
XEUtils.cookie('name', 'value', {expires: '7d'}) //指定7天后期
XEUtils.cookie('name', null, {expires: -1}) // 删除 XEUtils.cookie.remove(name) // 删除
思路:
利用状态管理,定义两个变量,左边菜单栏点击菜单,重复点击的菜单不重复展示
// 1.当前激活的选项卡
const activeName = ref('')
// 2.当前打开的选项卡数组
const openTabs = ref([])
系统中,业务功能菜单展示的内容,大部分布局是:上、中、下三栏布局,即顶部搜索区、中间数据表格、底部数据分页。这三个组件是通用组件
因此,我们可以单独创建一个内容页组件( MainLayout )。在该组件中,再单 独引入 Search 、 Tables 、 Paginator 三个子组件
布局采用:vh+ calc() ( 我们采用 ),即后面会在 Tables 组件中,添加了 height=“calc(100vh - 250px)”
使用 Provide (提供)和 Inject (注入)进行数据传递,父组件可以作为所有子组件的依赖项提供数据,而不管组件层次结构有多深。 这种特性有两个部分:父组件有一个 Provide 选项用于提供数据;子组件有一个 I nject 选项用于接收这个数据。例如:
在测试用例组件中利用Provide
provide('searchForm', searchForm)
provide('queryParam', queryParam)
provide('columns', columns)
provide('tableData', tableData)
provide('total', total)
provide('pageSize', pageSize)
provide('pageIndex', pageIndex)
provide('multiple', multiple)
provide('getData', getData)
const tableData = inject('tableData')
const columns = inject('columns')
const multiple = inject('multiple', false)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。