需要自己配置request.js
axios({
url:'http://localhost:5000/person',
method:'GET',
params:{id:personId.value}
# 此处写的是params,但是携带的是query参数
}).then(
response=>{ console.log('请求成功了!',response.data);},
error=>{console.log('请求失败了!',error);}
)
axios({
url:'http://localhost:5000/person',
method:'POST',
# 1. 携带请求体参数,json编码
data:{name:personName.value}
}).then(
response=>{ console.log('请求成功了!',response.data);},
error=>{console.log('请求失败了!',error);}
)
//main.js
//需要全局挂载axios并配置u根路径
import axios from 'axios'
Vue.prototype.$http = axios
axios.defaults.baseURL = 'http://121.41.91.38:8002'
async getAllMajor() {
const { data: res } = await this.$http.get('/admin/get_majors')
if (res.code !== 200) {
this.$message.error('获取失败')
} else {
this.options1 = res.data
}
}
async getAllMajor() {
//get发起请求时如果需要携带参数则用params
const { data: res } = await this.$http.get('/admin/get_majors',{params:{stu_id:this.stu_id,class:class}})
if (res.code !== 200) {
this.$message.error('获取失败')
} else {
this.options1 = res.data
}
}
传递参数
//单个参数
async change1(value) {
//这里传递参数需要获取data里面自定义value1中的major
const { data: res } = await this.$http.post('/admin/get_class', {
major: this.value1.major
})
// console.log(res);
this.options2 = res.data
},
//多个参数
async change1(value) {
//这里的addForm包含了多个参数,都定义在data中
const { data: res } = await this.$http.post('/admin/get_class',this.addForm )
// console.log(res);
this.options2 = res.data
},
1.首先,如果只是使用定位的话,当页面缩小的时候是肯定不会保持二者之间的相对距离的,缩放的话样式肯定会崩的。
2.可以尝试给这两个元素(也可能是很多个,具体的看你自己的界面而定)的父元素设定flex布局,然后设置flex常见的几行代码:
display:flex;
//主轴排列方式
justify-content:center;
//单行侧轴排列
aligin-items:center;
//多行侧轴排列
align-content:center
3.你需要显示的内容和父元素大致是这样的关系:
4.最后,你的元素有可能是挤在中间的,这个时候,再去对左边和右边的div进行定位,最好是用相对定位,因为相对定位自己本身的空间还站着,不会脱离文档流,不对其他元素的布局造成影响。
5.等你调好之后,再去缩放浏览器,你就会惊奇的发现,样式不崩了,不管是缩小还是放大,二者之间的距离都是不变的
登录设置token
window.sessionStorage.setItem('token',res.data.token)
退出登录清除token
window.sessionStorage.removeItem('token')
//挂载路由导航守卫
router.beforeEach((to, from, next) => {
//to 表示要访问的路径
//from 代表从哪一个路径跳转而来
//next 是一个函数,表示放行
// next() 放行 next('/login') 强制跳转
if (to.path === '/login') return next();
//获取token
const tokenStr = window.sessionStorage.getItem('token')
//如果没有获取到token那么返回登录
if (!tokenStr) return next('/login')
//得到token就跳转页面,放行
next()
})
el-pagination分页组件前端分页使用方法
...
data() {
currentPage: 1, // 当前页码
pageSize: 10, // 每页显示的行数
tableData: [...], // 表格数据
}
methods: {
// 页面切换方法
handleCurrentChange(val) {
this.currentPage = val;
}
}
1、图片填充DIV容器大小
将DIV的大小设置成为固定的大小,设定img 的宽度为:100%,高度为:100%;即可让图片自动适应DIV容器的大小。
2.指定背景图像的大小:
div
{
background:url(img_flwr.gif);
background-size:80px 60px;
background-repeat:no-repeat;
}
display: flex;
align-items:center;
链接:box-shadow详解_火兰的博客-CSDN博客
box-shadow 属性接受值最多由五个不同的部分组成。
box-shadow: (offset-x offset-yblurspreadcolorposition) ;
等同于:对象选择器 {box-shadow:X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色 投影方式 }
1.offset-x:指明了阴影水平方向的偏移,即阴影在 x 轴的位置。值为正数时,阴影在元素的右侧;值为负数时,阴影在元素的左侧。
2.offset-y:指明了阴影竖直方向的偏移,即阴影在y 轴的位置。值为正数时,阴影在元素的下方;值为负数时,阴影在元素的上方。
3.blur:第三个长度值代表了阴影的模糊半径,值为 0 意味着该阴影是固态而锋利的,完全完全没有模糊效果。blur 值越大,阴影越模糊。负值是不合法的,会被修正成 0。
4.spread第四个长度代表了阴影扩展半径,其值可以是正负值,如果值为正,则整个阴影都延展扩大,若值为负值缩小。前提是存在阴影模糊半径。
5.color:color 部分指阴影的颜色。它可以是任意的颜色单元 (见 在 CSS 中与颜色打交道)
6.position此参数是一个可选值,如果不设值,其默认的投影方式是外阴影;如果取其唯一值“inset”,就是将外阴影变成内阴影,也就是说设置阴影类型为“inset”时,其投影就是内阴影。
1.数据动态绑定
2.表单校验与表单预检验
vue2
// vue2
登录
vue3
// vue3
后台管理系统
登录
重置
3.重置表单
重置
用户进入网站首次登录,前端会携带用户信息(用户名、密码什么的)到服务端做请求
1、服务端验证用户名密码
未通过校验:响应给前端,用户名/密码错误等信息
通过校验:对该用户创建token,并将token作为响应数据返回给前端
2、前端拿到响应数据:
错误信息:页面给予提示:用户名/密码错误
正常信息:页面进行跳转到首页,保存token(可以保存在cookie或sessionStorage)
3、用户点击触发请求:
【路由守卫】(全局——Vue中的 beforeEach())
判断即将进入的页面需不需要token(例如:路由配置中 meta{authRequired:true})
不需要:next()放行,展示页面
需要:从本地获取token(获取到则发起请求,没获取到则返回登录页引导登录)
router.beforeEach((to, from, next) => {
//这里是获取token,点击登录时需要将token保存,然后再路由守卫中进行验证
const token = sessionStorage.getItem('token')
// 目标路由不是登录页,并且还需要token验证,还没有token,那就直接给返回到登录页
if (to.name !== 'Login'&& to.meta.authRequired && !token){
next({ name: 'Login' })
}else{
// 目标路由是登录页-自然不需要token验证
// 或目标路由不需要身份验证
// 又或目标路由非登录页,需要token验证,但是有token
// next放行
next()
}
})
补充
// 1.将登录成功之后的token,保存到客户端的sessionStorage中
// 1.1 项目中除了登录或注册之外的其他API接口,必须在登录之后才能访问
// 1.2 token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
// localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。
// sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。
window.sessionStorage.setItem('token', res.data.token)
//将res.data.token赋值给sessionStorage中的token
// 2.通过编程式导航跳转到后台主页,路由地址是 /home
this.$router.push('/home')
(1)首先输入账号密码
(2)账号密码验证无误后,服务器会随机生成一个token值(令牌)
(3) 将服务器返回的token值 在我们本地进行存储
(4) 下次登陆时就携带这个token(我们把token值放在http请求头)
(5)最后在退出登陆时,将token在本地化存储中删除
window.sessionStorage.clear();
当状态码时401就说明token校验失败,给予用户提示/跳转到登录页面
大物项目代码展示
async login() {
const { data: res } = await this.$http.post(
"/api/users/login",
this.loginForm
);
if (res.code == 200) {
this.$message.success("登录成功!");
//将获取到的token存储在sessionStorage
window.sessionStorage.setItem("token", "Bearer " + res.data.token);
this.$router.push("/home");
}
if (res.code == 100) {
this.$message.error("登录失败!");
}
},
X-Requested-With(作用:异步请求)
现在很多的功能都会用到这个异步请求,比如说登录。
//X-Requested-With:它的作用是:异步请求
axios.defaults.headers = {
'X-Requested-With': 'XMLHttpRequest',
}
异步请求的特点:无刷新。就是说登录的时候是需要进行页面跳转的,而异步请求它不需要跳转也可以做到这样的请求。
//请求拦截器:1.展示loading动画
2.认证登录,关于token/cookie
3.某些请求参数的转化
//响应拦截器:1.关闭loading动画
2.对相应的数据机型转化,转化之后再返回
// axios请求拦截器 => interceptors 在页面发送请求前进行一次预处理
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
//axios响应拦截器
// use(两个参数)
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
大物代码展示:
axios.interceptors.request.use((config) => {
config.headers.Authorization = window.sessionStorage.getItem("token")
return config
},
error => {
error.data = {
message: '服务器异常!'
}
return Promise.reject(error)
}
)
属性失效的原因:因为justify-contnt属性是控制在主轴上的对齐方式,align-items属性是控制侧轴上的对齐方式.所以在首对齐,中对齐,尾对齐等各种对齐效果生效时需要计算组件的宽度。当组件的 主轴长度属性(主轴为横轴时就是width,为纵轴时就是height)没有进行设置时,属于灵活延展的,所以无法进行计算,故属性没有生效。
解决方案:为主轴设置好确切的长度
真实开发的时候,我们往往会从服务器拿到一组数据,并对其进行渲染
把v-for写在谁身上,谁就会出现多个!!!
v-for的基本格式:“item in 数组” ,如果需要拿到索引值,则写成: (item,index)in 数组
,
人员列表(遍历数组)
//最好使用每条数据的唯一标识作为key
-
{{item.name}}-{{item.age}}
汽车信息(遍历对象)
-
{{key}}-{{value}}
推荐:全局事件总线:实现任意组件间的通信
//引入Vue
import Vue from 'vue';
//引入App
import App from './App';
//关闭vue的生产提示
Vue.config.productionTip = false
//创建vm
new Vue({
el: "#app",
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this//安装全局事件总线
}
})
mounted(){
this.$bus.$on('hello',this.demo)
}
3.提供数据(this.$bus.$emit()):student组件去触发事件。比如在Student组件中准备一个按钮,绑定send方法,点击按钮去触发这个事件
methods:{
send(){
this.$bus.$emit('hello',this.name)
}
}
4.解绑数据:最好在beforeDestory(){}钩子中,用$off去解绑当前组件所用到的事件,所以在School组件中去解绑hello事件
beforeDestroy() {
console.log('hello事件被解绑')
this.$bus.off('hello')
},
完整代码:
main.js
import Vue from 'vue'
import App from './App.vue'
//关闭vue生产模式
Vue.config.productionTip = false
new Vue({
el:'#app',
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this//安装全局事件总线
}
})
school.vue
学校名称:{{name}}
学校地址:{{address}}
student.vue
{{msg}}
学生名字:{{name}}
学生年龄:{{myAge}}
这种通信方式适用与父向子传递数据
//父组件
我是父组件
这样我们的子组件就能拿到父组件传递过来的数据,并把它渲染上页面:
// 子组件
我是子组件
我是父组件传递过来的数据:{{msg}}
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
v-on ===>@click
给一个事件绑定多个方法
vuex详解
具体代码怎么做看我vue2项目中的vuex
几句重要的核心:
commit触发mutations的函数,dispatch触发actions的函数
Vuex是实现组件全局状态
的一种机制,可以实现组件之间的数据共享
组件之间共享的数据
才有必要存到vuex中
唯一公共的数据源
,所有共享数据都需要统一放到Store的State中进行存储//创建store数据源,提供唯一公共数据
const store =new Vuex.Store({
state:{count:0}
})
第一种方式
:【这种简单的用的多】this.$store.state.全局数据名称 //想访问谁,就把谁的名称.出来,this可以省略
commit的作用就是调用某个mutation函数
】变更Store中的数据
,不可以直接操作Store中的数据//在store.js中定义Mutation
const store =new Vuex.Store({
state:{
count:0
},
mutations:{
add(state){
//变更状态
state.count++
}
}
})
//在components组件中触发mutations
methods:{
handle1(){
//触发mutations的第一种方式
this.$store.commit('add')
}
}
//在store.js中定义Mutation
const store =new Vuex.Store({
state:{
count:0
},
mutations:{
addN(state,step){
//变更状态
state.count+=step
}
}
})
//在components组件中触发mutations
methods:{
handle2(){
//在调用commit函数,
//触发mutations时携带参数
this.$store.commit('addN',3)
}
}
处理异步任务
//在store.js中定义Action
const store =new Vuex.Store({
state:{
count:0
},
mutations:{
add(state){
//变更状态
state.count++
}
},
actions:{
addAsync(context){
setTimeout(()=>{
//通过commit触发mutations中的函数,实线异步操作
//在actions中,不能直接修改state中的数据,必须通过context.commit()触发某个mutation才行
context.commit('add')
},1000)
}
}
})
//在components组件中触发Actions
methods:{
handle(){
//触发actions的第一种方式
//dispatch的作用就是触发某个对应的actions中的函数
this.$store.dispatch('addAsync')
}
}
总结:commit触发mutations的函数,dispatch触发actions的函数
//在store.js中定义Action
const store =new Vuex.Store({
state:{
count:0
},
mutations:{
add(state){
//变更状态
state.count++
}
},
actions:{
addAsync(context,step){
setTimeout(()=>{
//通过commit触发mutations中的函数,实线异步操作
//在actions中,不能直接修改state中的数据,必须通过context.commit()触发某个mutation才行
context.commit('add',step)
},1000)
}
}
})
//在components组件中触发Actions
methods:{
handle(){
//触发actions的第一种方式
//dispatch的作用就是触发某个对应的actions中的函数
this.$store.dispatch('addAsync',5)
}
}
Getter用于对store中的数据进行加工形成新的数据
,相当于计算属性的作用
//定义Getter
const store =new Vuex.Store({
state:{
count:0
},
getters:{
showNum:state=>{
return '当前最新的数值是【‘+ state.count+’】'
}
}
})
使用getters的第一种方式
:
this.$store.getters.名称
给el-input外部包裹一层el-col,来控制el-input的宽度
localStorage:本地存储,提供的是一种永久性的本地存储,在关闭掉网页重新打开时,存储的内容依然保留;
localStorage.setItem('name',yjm)
sessionStorage:会话存储,提供的是本次会话的存储,在关闭掉会话时,存储的内容会被清除;
sessionStorage.setItem('name',yjm)
路由首页重定向
const routes =[
//当路由路径后面没有跟后缀组件时,重定向到home组件进行展示,当有后缀home也会重定向到home
{path:'/',redirect:'/home'},
//配置路由懒加载,按需去加载路由对应的资源,提高首屏加载速度
{path:'/home',component:()=>import('../views/Home.vue')},
{path:'/about',component:()=>import('../views/About.vue')}
]
注意:最好使用normalize.css,别使用reset.scss(太暴力)
在每个项目的开发都需要进行项目css初始化
npm install --save normalize.css
import "normalize.css"
当某个人需要使用这个组件的时候,但同时不希望组建的内容写死,则使用插槽自定义组件内容
父组件中:
html结构1
子组件中:
插槽默认内容...
父组件中:
html结构1
html结构2
子组件中:
插槽默认内容...
插槽默认内容...
需要template和v-slot
具名插槽顾名思义就是给插槽起一个名字, 元素有一个特殊的属性:name
keep-alive的详解【按住ctrl再点击就可以打开网址】
作用: 在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
1.使用:
// router.js
{
path: '/home',
name: 'home',
component: () => import('../views/home.vue')
},
{
path: '/test',
name: 'test',
component: () => import('../views/test.vue')
},
// App.vue
此外,我们还可以通过路由中的 meta 属性来控制,是否需要缓存。
将 test 路由中的 meta 添加 keepAlive 属性为 true,表示当前路由组件要进行缓存。
// router.js
{
path: '/home',
name: 'home',
component: () => import('../views/home.vue')
},
{
path: '/test',
name: 'test',
meta:{
keepAlive:true
},
component: () => import('../views/test.vue')
},
keep-alive 代码可以结合 v-if 进行包裹,如果 meta 中的 keepAlive 为 true 进行缓存,否侧不进行缓存。
2.生命周期函数
activated:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。
deactivated:在组件被停用时调用。
在后台管理系统中,点击侧边栏切换main区域的组件内容,给main组件的template区域添加
上图就实现了组件的缓存
el-input
input
代码示例
巨重要:!!!【歌唱管理员端的根据名字搜索学校的代码】
Vue中this.$router.push(参数) 实现页面跳转的详解
这是params的,query类似
传递:this.$router.push({
name:'跳转页面的name',
params:{
//你需要通过页面跳转传递的参数
}
})
接收:this.$route.params
解决方法:在router中的index.js重写该方法即可
//1、先把VueRouter原型对象的push,保存一份
let originPush = VueRouter.prototype.push;
//2、重写push|replace
//第一个参数:告诉原来的push,跳转的目标位置和传递了哪些参数
VueRouter.prototype.push = function (location,resolve,reject){
if(resolve && reject){
originPush.call(this,location,resolve,reject)
}else{
originPush.call(this,location,() => {},() => {})
}
}
vue2和3都使用lodash节流防抖:
vue3使用防抖和节流
防抖:用户操作很频繁,但是只执行一次,减少业务负担。
节流:用户操作很频繁,但是把频繁的操作变为少量的操作,使浏览器有充分时间解析代码
// 安装lodash
npm i --save lodash
// 节流
// 防抖
图片懒加载
npm安装
npm i vue-lazyload -S
使用
import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'
//注册插件
Vue.use(VueLazyload)
Vue.use(VueLazyload, {
loading: 这里写的是懒加载的预览图【还没有加载出正真的图片的预览图】,
})
变为了:
修改第三方UI组件库样式的四种方法
例如:
我想要修改tabbar的字体图标的大小
总结:找到想要修改的类,对其css样式进行重写,在引用第三方库的时候,需要使用:deep进行样式穿透
coderwhy前端day64-第1128集
hhhhhhh{{item}}
//路由配置
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
//映射关系
routes: [
{
path:"/",
redirect:"/home"
},
{
path:"/home",
component:()=>import("@/views/home/home.vue")
},
{
path:"/city",
component:()=>import("@/views/city/city.vue"),
meta: {
showTab: false
}
},
]
})
export default router
上面代码的意思就是如果底部需要tabbar就设置meta:{showTab:true}不需要的就设置meta:{showTab:false}
然后在app.vue中的tabbar组件(就是底部配置的router-link)中判断就行了这里的tabbar组件就是下面的底部导航
这里呢是给出v-if就是判断showTab是否为true了,为true显示tabBar为false不显示
//动态将服务器的内容渲染到页面上
{{ item.school_name }}
//顶部部分
//内容部分
数据列表:{{item}}
const isShow=ref(false)
// 页面滚动
window.addEventListener("scroll",()=>{
const scrollTop=document.documentElement.scrollTop//已经滚动的高度
const scrollHeight =document.documentElement.scrollHeight//可滚动的总高度
const clientHeight =document.documentElement.clientHeight//可视区域的高度
console.log(scrollTop,scrollHeight,clientHeight);
if(scrollTop>0.85*clientHeight){
isShow.value=true
}else{
isShow.value=false
}
})
视频教学:百度网盘 - 视频播放 (baidu.com)
操作文档:jspopularGL | 百度地图API SDK
百度网盘 - 视频播放 (baidu.com)
GitHub - evrone/postcss-px-to-viewport: A plugin for PostCSS that generates viewport units (vw, vh, vmin, vmax) from pixel units. The best choice to create a scalable interface on different displays by one design size.
将全局的px转换为vw
module.exports = {
plugins: {
'postcss-px-to-viewport': {
//移动端适配,视口宽度375
viewportWidth:375
}
}
}
在App.vue中配置以下代码
vue3.0 router路由跳转传参(router.push)_vue3 router.push 传参数_吃鱼吐泡泡的博客-CSDN博客
1.首先在需要跳转的页面引入API---useRouter
import { useRouter } from 'vue-router'
2.在跳转页面定义router变量
//首先在setup中定义
const router = useRouter()
3.用router.push跳转页面
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?userId=123
router.push({ path: 'register', query: { userId: '123' }})
VUE使用sessionStorage存取对象时会显示[object object]的解决方法_vue [object object]_Leon_BUAA的博客-CSDN博客
coderwhy day105 233
elementplus按需自动导入
npm install -D unplugin-vue-components unplugin-auto-import
Vite
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
Webpack
// vue.config.js
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = {
// ...
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
注意:elementplus的反馈组件Feedback需要自己在页面js中手动导入
:deep(.el-input__inner){
height: 100px;
}
icon图标的全局使用
// main.ts
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
day106的262
Collapse 折叠面板
核心:
组件间存在父子关系,所以需要使用emit将子组件的事件传递到父组件中去
调整aside的宽度:
三元运算符
调整menu的宽度:
coderwhy day107--270
动态路由:根据用户的权限,动态添加路由信息(而不是一次性注册所有的路由)
基于菜单(menus)的动态路由管理
在store中定义动态路由数组
const localRoutes:any[]=[
{
path: '/main/analysis/dashboard',
component: () => import('@/views/main/analysis/dashboard/dashboard.vue')
},
......
]
const route = localRoutes.find((item) => {
return item.path === submenu.url
})
// if(route)代表上面通过find已经查询出了相等的数据返回给了route
// 需要在全局router中给main组件命名为main才能添加进来
if (route) router.addRoute('main', route)
main.ts
做了以上操作后,需要在main.ts中再次调用这个方法,否则当进入这个页面后会导致路径出错(需要在app.use(router之前))
示例:
var obj = { name: '小明', age: 22 };
console.log( Object.values(obj) ); // ['小明', 22]
const arr = ['小明', 22];
const obj = {...arr};
console.log(obj); //{0: '小明', 1: 22}
npm install dayjs --save
import dayjs from 'dayjs'
export default function time (day){
const finalTime = dayjs(day).format('YYYY-MM-DD');
return finalTime
}
import time from './utils/time'
console.log(time(1690033589685));//2023-07-22
console.log(time('2023-07-23T00:49:11.000Z'));//2023-07-23
官网:Animate.css | A cross-browser library of CSS animations.
npm install animate.css --save
import animated from 'animate.css'
const app = createApp(App)
app.use(animated)
情况一:进入页面自动展示动画
直接添加transition标签再使用class添加动画样式就能展示对应的动画
切记:再使用动画效果之前,一定要使用animate__animated
后台管理系统
情况二:触发事件造成dom元素切换时的动画
hello world
const show=ref(true)
function handleClick(){
show.value=!show.value
}
npm i --save lodash
import _ from 'lodash'
//生成随机数
console.log(_.random(5))//生成0-5随机数
console.log(_.random(5,10))//生成5-10的随机数
// 数组去重
const arr=['red','yellow','blue','red']
console.log(_.uniq(arr))// ['red', 'yellow', 'blue']
//防抖函数
直接看28
selectBlur(e){
this.$set(this.value, 'account', e.target.value)
},
npm i countup.js
day 110 328
个人建议去听尚硅谷硅谷甄选项目P28
import axios from 'axios'
// 第一步:利用axios对象的create方法,去创建axios实例(其他的配置:基础路径,超时时间)
let request=axios.create({
// 基础路径
baseURL:http://xxxxxxx,
timeout:5000
})
// 第二步:request实例添加请求响应拦截器
request.interceptors.request.use((config)=>{
// config配置对象,headers属性请求头,经常给服务器携带公共参数
// 返回配置对象
return config
})
// 第三步:响应拦截器
request.interceptors.response.use((response)=>{
// 成功的回调
// 可以简化数据
},(error)=>{
// 失败的回调:处理http网络错误
})
// 对外暴露
export default request
我们可能会在很多组件里用到数据/实用工具,但是不想污染全局作用域。这种情况下,可以通过在原型上定义它们使其在每个 Vue 的实例中可用。
每个组件都是一个vue实例,Vue.prototype加一个变量,只是给每个组件加了一个属性,这个属性的值并不具有全局性。
npm install vue-danmaku --save
<-- 使用 -->
//当传入的是:age="18",age这个属性传递的就是双引号里面的内容
//如果不写v-bind,传入的就是字符串的18
传递一个age属性,但是值是引号里面的js表达式运行的结果
在Vue 2中,this 可以访问以下内容:
data() {
return {
message: 'Hello, Vue!'
};
},
methods: {
showMessage() {
console.log(this.message);
}
}
computed: {
reversedMessage() {
return this.message.split('').reverse().join('');
}
},
methods: {
showReversedMessage() {
console.log(this.reversedMessage);
}
}
methods: {
sayHello() {
console.log('Hello!');
}
},
mounted() {
this.sayHello();
}
created() {
console.log('组件创建完成');
},
mounted() {
console.log('组件挂载到 DOM');
}
methods: {
goToPage() {
this.$router.push('/some-page');
}
}
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.commit('increment');
}
}
请注意,以上是在合适的上下文环境中使用 this 的示例。
scope-row:获取整行的数据
scope-$index:获取这一行的序列号
Vue2:
查看
编辑
// 多种情况使用v-if判断,只有两种情况就是用三元表达式
下载中
已完成
下载失败
原因:由于是请求接口返回的数据,可能还没有返回到,所以data就是undefined,就会出现上面的这种错误
解决办法:多增加一层div嵌套,判断data对象是否有数据,有则渲染,没有则不渲染。则解决该问题。
解决办法
硅谷甄选P24
npm i vite-plugin-svg-icons -D
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
return {
plugins: [
createSvgIconsPlugin({
// Specify the icon folder to be cached
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
// Specify symbolId format
symbolId: 'icon-[dir]-[name]',
}),
],
}
}
import 'virtual:svg-icons-register'
前端解决跨域的方法
coderwhy day105 242
在父组件中给子组件定义ref,去获取他的实例,就能调用子组件的方法了
获取子组件的实例
注意:有一个例外的情况,使用了
然后通过this.$refs获取子组件实例
Vue3官网对于props的解读
如果我们正在构建一个博客,我们可能需要一个表示博客文章的组件。我们希望所有的博客文章分享相同的视觉布局,但有不同的内容。要实现这样的效果自然必须向组件中传递数据,例如每篇文章标题和内容,这就会使用到 props。
Props 是一种特别的 attributes,你可以在组件上声明注册。要传递给博客文章组件一个标题,我们必须在组件的 props 列表上声明它。这里要用到 defineProps 宏:
{{ title }}
一个组件可以有任意多的 props,默认情况下,所有 prop 都接受任意类型的值。
当一个 prop 被注册后,可以像这样以自定义 attribute 的形式传递数据给它:
在实际应用中,我们可能在父组件中会有如下的一个博客文章数组:
const posts = ref([
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
])
这种情况下,我们可以使用 v-for 来渲染它们:
npm install echarts --save
当多个组件用到了同一个样式(非全局,如果是全局就直接在main.js中引入),我们可以用这种方式来解决: