当前位置: 首页 > news >正文

Vue2+Vue3 45-90集学习笔记

Vue2+Vue3 45-90集学习笔记

小兔鲜首页

页面开发思路:

  1. 分析页面,按模块拆分组件,搭架子(局部注册或全局注册)
    • 局部注册:App.js中 导入(import),注册(components),使用(<组件名></组件名>)
  2. 根据设计图编写htmlcss样式
  3. 拆分封装通用小组件(局部或全局注册)
    • 全局注册:main.js中 导入(import),注册(Vue.component('组件名',组件对象)),使用(<组件名></组件名>)

所有都折叠ctrl+k,ctrl+0
所有都展开ctrl+k,ctrl+j

一、组件的三大组成部分

1、注意点说明

  • template:有且只能由一个根元素
  • style:默认为全局样式影响所有组件,如果想限制为局部样式,给组件加上scoped属性,让样式只作用于当前组件
<style scoped>
</style>

scoped原理:
1.给当前组件模板的所有元素都添加上一个自定义属性:data-v-hash值
2.css选择器后面,被自动处理,添加上了属性选择器div[data-v-hash值]

  • script:el根实例独有,data必须是一个函数,其他配置项一致
data() {return {count:100}
}

每次创建新的组件实例,都会新执行一次data函数,得到一个新对象=>保证每个组件实例,维护独立的一个数据对象

二、组件通信

组件通信就是指组件与组件之间的数据传递

为什么要数据传递?
组件的数据是独立的,无法直接访问其他组件的数据,组件只能访问自己的数据
想用其他组件的数据,必须要进行组件通信

组件关系分类:

  • 父子关系:props和$emit
  • 非父子关系:1.provide&inject 2.eventbus

1、父子通信

父组件通过props将数据传递给子组件
子组件利用$emit通知父组件修改更新

//父组件
<template><div><MySon :title="myTitle" @changeTitle="changeFn"></MySon></div>
</template><script>
import MySon from './components/MySon.vue'export default {data(){return {myTitle:'黑马程序员'}},components: {MySon},methods:{changeFn(newTitle){this.myTitle = newTitle}}
}
</script><style>
</style>
//子组件
<template><div>我是子组件{{ title }}<button @click="handleClick">修改title</button></div>
</template><script>
export default {props:['title'],methods:{handleClick(){this.$emit('changeTitle','传智教育')}}
}
</script><style scoped>
</style>

父传子步骤
1.给子组件以添加属性的方式传值
2.在子组件内通过props接收数据
在子组件模板中直接使用

子传父步骤
1.在子组件内使用$emit触发事件,给父组件发送消息通知
this.$emit('事件名','传递过去的参数')
2.父组件监听事件
3.提供处理函数,形参会获取传递过来的参数

2、props详解

(1)什么是prop

prop定义:组件上注册的一些自定义属性
prop作用:向子组件传递数据

(2)prop校验

作用:为组件的prop指定验证要求,不符合要求,控制台就会有错误提示=>帮助开发者,快速发现错误

props:{校验的属性名:类型 //Number/String/Boolean
}

更细致的校验要求

props:{校验的属性名:{type:类型,//Number/String/Booleanrequired:true,//是否必填default:默认值,//默认值validator(value){//自定义校验逻辑return 是否通过校验(true/false}}
}
(3)prop&data、单向数据流

共同点:都可以给组件提供数据
不同点:

  • data数据是自己的=>随便改(谁的数据谁负责)
  • prop数据是外部的=>不能直接改,单向数据流

子组件想要修改props数据,需要通过子传父通知到父组件,在父组件内修改

//父组件
<template><div><MySon :count="count" @changeCount="changeFn"></MySon></div>
</template><script>
import MySon from './components/MySon.vue'export default {data(){return {count:999}},components: {MySon},methods:{changeFn(newCount){this.count = newCount}}
}
</script><style>
</style>
//子组件
<template><div><button @click="handleSub">-</button>{{ count }}<button @click="handleAdd">+</button></div>
</template><script>
export default {props:{count:{type:Number}},methods:{handleAdd(){//不可以使用this.count++,这样就修改了子组件内的count了this.$emit('changeCount',this.count+1)},handleSub(){//不可以使用this.count--,这样就修改了子组件内的count了this.$emit('changeCount',this.count-1)}}
}
</script><style scoped></style>

单向数据流:父组件的prop更新,会单向的向下流动,进而影响子组件,这个数据是单向流动的

三、综合案例:小黑记事本(组件版)

  1. 拆分基础组件
    新建组件 -> 拆分存放结构 -> 导入注册使用
  2. 渲染功能
    • 提供数据 => 提供在公共的父组件内 App.vue
    • 通过父传子,将数据传递给子组件
    • 利用v-for渲染
  3. 添加功能
    • 收集表单数据 => v-model
    • 监听事件(回车+点击 都要监听)
    • 子传父,将任务名称传递给父组件
    • 将任务名称添加到任务数组中unshift添加到数组最前面
  4. 删除功能
    • 监听点击事件 携带需删除的任务id
    • 子传父 ,将任务id传递给父组件
    • 在父组件内,任务数组中将 id===任务id 的任务删除filter方法
  5. 底部合计
    • 父传子任务数组
    • 在子组件内渲染任务数组的长度
  6. 清空功能
    • 监听点击事件
    • 子传父 通知父组件在父组件内清空任务数组
  7. 持久化存储
    • watch深度监视list变化 => 往本地存储,一进页面优先读取

四、非父子通信(拓展)-event bus 事件总线

作用:非父子组件之间,进行简易消息传递

  1. 创建一个都能访问到的事件总线(空Vue实例)
import Vue from 'vue'
const Bus = new Vue()
export default Bus
  1. A组件(接收方),监听Bus实例的事件
created () {Bus.$on('sendMsg', (msg) => {this.msg = msg})
}
  1. B组件(发送方),触发Bus实例的事件
Bus.$emit('sendMsg', '这是一个消息')

在这里插入图片描述

五、非父子通信(拓展)-provide-inject

作用:跨层级共享数据

  1. 父组件 provide提供数据
export default {provide () {return {// 普通类型【非响应式】color: this.color, // 复杂类型【响应式】userInfo: this.userInfo, }}
}

2.子/孙组件 inject获取数据

export default {inject: ['color','userInfo'],created () {console.log(this.color, this.userInfo)}
}

注意
provide提供的简单类型的数据不是响应式的,复杂类型数据是响应式。(推荐提供复杂类型数据)
子/孙组件通过inject获取的数据,不能在自身组件内修改

六、v-model详解

1、v-model原理

原理:v-model本质上是个语法糖
作用:实现数据的双向绑定

  1. 数据变,视图跟着变 :value
  2. 视图变,数据跟着变 @input$event用于在模板中,获取事件的形参
<input v-model='msg' type='text'>
等于
<input :value='msg' @input='msg=$event.target.value' type='text'>

模板中获取事件的形参需要用$event获取\

2、表单类组件封装、v-model简化代码

  1. 表单类组件的封装
    • 父传子:数据由父组件props传递过来的,v-model拆解绑定数据(因为子组件不能直接修改父组件的数据)
    • 子传父:监听输入,子传父传值给父组件修改

App.vue

<template><div class="app"><BaseSelect :cityId='selectId' @changeId='selectId = $event'></BaseSelect></div>
</template><script>
import BaseSelect from './components/BaseSelect.vue'
export default {data() {return {selectId: '102',}},components: {BaseSelect,}
}
</script><style>
</style>

BaseSelect.vue

<template><div><select :value='cityId' @change='handleChange'><option value="101">北京</option><option value="102">上海</option><option value="103">武汉</option><option value="104">广州</option><option value="105">深圳</option></select></div>
</template><script>
export default {props:{cityId:String},methods:{handleChange(e){this.$emit('changeId',e.target.value)}}
}
</script><style>
</style>
  1. 父组件v-model简化代码,实现子组件和父组件数据双向绑定
    • 子组件中,props通过values接收,事件触发input
    • 父组件中,v-model给组件直接绑定数据

子组件

//父传子3.子组件使用   子传父1.添加监听
<select :value="value" @change="handleChange">...</select>
//父传子2.子组件props接收
props: {value: String
},
methods: {//子传父2.设置监听函数handleChange (e) {this.$emit('input', e.target.value)}
}

父组件

<BaseSelect v-model="selectId"></BaseSelect>
等于
<BaseSelect :value="selectId" @input="selectId = 传入的参数"></BaseSelect>
//父传子1.子组件引入属性   子传父3.监听input,函数的形参接收

七、.sync修饰符

作用:可以实现子组件父组件数据双向绑定,简化代码
特点:prop属性名,可以自定义,非固定为value
本质::属性名@update:属性名合写

<BaseSelect :visible.sync="selectId"></BaseSelect>
等于
<BaseSelect :visible="isShow" @update:visible="isShow = 传入的参数($event)"></BaseSelect>

App.vue

<template><div class="app"><button @click="isShow=true">退出按钮</butto//父传子1:注册属性 :visible='isShow'//子传父3:监听通知事件 @update.visible='isShow=$event'<BaseDialog :visible.sync='isShow'></BaseDialog></div>
</template><script>
import BaseDialog from './components/BaseDialog.vue'
export default {data() {return {isShow: false,}},components: {BaseDialog,},
}
</script><style>
</style>

BaseDialog.vue

<template><div class="base-dialog-wrap" v-show="visible">//父传子3:子组件内渲染<div class="base-dialog"><div class="title"><h3>温馨提示:</h3><button class="close" @click='handleClick'>x</button>//子传父1:监听点击事件</div><div class="content"><p>你确认要退出本系统么?</p></div><div class="footer"><button @click='handleClick'>确认</button>//子传父1:监听点击事件<button @click='handleClick'>取消</button>//子传父1:监听点击事件</div></div></div>
</template><script>
export default {props: {//父传子2:props接收visible: Boolean,},methods:{handleClick(){//子传父2:给父组件传递通知this.$emit('update:visible',false)}}
}
</script><style scoped>
</style>

八、ref和$ref

作用:利用ref和$ref可以用于获取dom元素,或组件实例
特点:查找范围->当前组件内,更精确稳定

获取dom

  • 目标标签-添加ref属性
<div ref="chartRef">我是渲染图表的容器</div>
  • 恰当时机,通过this.$ref.xxx,获取目标标签
mounted () {console.log(this.$refs.chartRef)
}

获取组件

  • 目标组件-添加ref属性
<BaseForm ref='baseForm'></BaseForm>
  • 恰当时机,通过this.$ref.xxx,获取目标组件,就可以调用组件对象里面的方法
this.$refs.baseForm.组件方法()

九、Vue异步更新、$nextTick

Vue 是异步更新DOM (提升性能):代码执行完时,当前dom并没有立即更新
$nextTick:等dom更新后,才会触发执行此方法里的函数
语法:this.$nextTick(函数体)

this.$nextTick(()=>{this.$refs.inp.focus()
})

十、自定义指令

1、自定义指令

自己定义的指令,可以封装一些DOM操作,扩展额外的功能
语法:

  • 全局注册
//在main.js中
Vue.directive('指令名', {"inserted" (el) {// 可以对 el 标签,扩展额外功能el.focus()}
})
  • 局部注册
//在Vue组件的配置项中
directives: {"指令名": {inserted () {// 可以对 el 标签,扩展额外功能el.focus()}}
}
  • 使用自定义指令
    一定要先注册,再使用,否则会报错
    使用语法:v-指令名
  • 指令中配置项介绍
    • inserted:被绑定元素插入父节点时调用的钩子函数
    • el:使用指令的那个DOM元素,DOM元素添加了自定义指令后,el会与其绑定
//局部注册自定义属性
directives:{focus:{inserted(){el.foucus}}
}//全局注册自定义属性
Vue.directive(focus,{"inserted"(el){el.focus}
})
//使用
<div><h1>自定义指令</h1><input v-focus ref="inp" type="text">
</div>

2、自定义指令的值

//使用
<div v-color="color">我是内容</div>
//定义
directives: {color: {inserted (el, binding) {el.style.color = binding.value},update (el, binding) {el.style.color = binding.value}}
}
  1. 在绑定指令时,可以通过等号为自定义指令绑定具体的值
  2. 通过binding.value可以拿到指令的值,当其修改时会触发update函数,否则当修改binding.value的值时不会重新渲染

3、v-loading

1、场景
实际开发过程中,发送请求需要时间,在请求的数据未回来时,页面会处于空白状态 => 用户体验不好
2、需求
封装一个 v-loading 指令,实现加载中的效果
3、实现

  1. 准备一个 loading类,通过伪元素定位,设置宽高,实现蒙层
  2. 开启关闭 loading状态(添加移除蒙层),本质只需要添加移除类即可
  3. 结合自定义指令的语法进行封装复用
<template><div class="main"><div class="box" v-loading='isLoading'><ul><li v-for="item in list" :key="item.id" class="news"><div class="left"><div class="title">{{ item.title }}</div><div class="info"><span>{{ item.source }}</span><span>{{ item.time }}</span></div></div><div class="right"><img :src="item.img" alt=""></div></li></ul></div> </div>
</template><script>
// 安装axios =>  yarn add axios || npm i axios
import axios from 'axios'// 接口地址:http://hmajax.itheima.net/api/news
// 请求方式:get
export default {data () {return {list: [],isLoading: true}},async created () {// 1. 发送请求获取数据const res = await axios.get('http://hmajax.itheima.net/api/news')setTimeout(() => {// 2. 更新到 list 中,用于页面渲染 v-forthis.list = res.data.datathis.isLoading = false}, 2000)},directives:{loading:{inserted(el,binding){binding.value ? el.classList.add('loading') : el.classList.remove('loading') },updata(el,binding){binding.value ? el.classList.add('loading') : el.classList.remove('loading') }}}
}
</script><style>
.loading:before {content: '';position: absolute;left: 0;top: 0;width: 100%;height: 100%;background: #fff url('./loading.gif') no-repeat center;
}
.box {width: 800px;min-height: 500px;border: 3px solid orange;border-radius: 5px;position: relative;
}
.news {display: flex;height: 120px;width: 600px;margin: 0 auto;padding: 20px 0;cursor: pointer;
}
.news .left {flex: 1;display: flex;flex-direction: column;justify-content: space-between;padding-right: 10px;
}
.news .left .title {font-size: 20px;
}
.news .left .info {color: #999999;
}
.news .left .info span {margin-right: 20px;
}
.news .right {width: 160px;height: 120px;
}
.news .right img {width: 100%;height: 100%;object-fit: cover;
}
</style>

十一、插槽

1、默认插槽

1、作用:让组件内部的一些结构支持自定义
2、需求:将需要多次显示的对话框封装成一个组件,组件的内容部分不希望写死,希望使用的时候可以自定义
3、基本语法:

  • 组件内需要定制的结构部分,改用<slot></slot> 占位
  • 使用组件时,组件标签的内部填入slot的内容
  • 给插槽传入内容时,可以传入纯文本、html标签、组件

MyDialog.vue

<template><div class="dialog"><div class="dialog-header"><h3>友情提示</h3><span class="close">✖️</span></div><div class="dialog-content"><slot></slot>//在需要定制的位置,使用slot占位</div><div class="dialog-footer"><button>取消</button><button>确认</button></div></div>
</template><script>
export default {data () {return {}}
}
</script><style scoped>
* {margin: 0;padding: 0;
}
.dialog {width: 470px;height: 230px;padding: 0 25px;background-color: #ffffff;margin: 40px auto;border-radius: 5px;
}
.dialog-header {height: 70px;line-height: 70px;font-size: 20px;border-bottom: 1px solid #ccc;position: relative;
}
.dialog-header .close {position: absolute;right: 0px;top: 0px;cursor: pointer;
}
.dialog-content {height: 80px;font-size: 18px;padding: 15px 0;
}
.dialog-footer {display: flex;justify-content: flex-end;
}
.dialog-footer button {width: 65px;height: 35px;background-color: #ffffff;border: 1px solid #e1e3e9;cursor: pointer;outline: none;margin-left: 10px;border-radius: 3px;
}
.dialog-footer button:last-child {background-color: #007acc;color: #fff;
}
</style>

App.vue

<template><div><MyDialog>你确认要删除么?//在使用组件时,组件标签内填入内容</MyDialog></div>
</template><script>
import MyDialog from './components/MyDialog.vue'
export default {data () {return {}},components: {MyDialog}
}
</script><style>
body {background-color: #b3b3b3;
}
</style>

2、后备内容

封装组件时,可以为预留的 插槽提供后备内容(默认内容)。
<slot></slot>标签内,放置内容, 作为默认显示内容(即如果在使用组件时为插槽传入内容则显示传入的内容,否则将显示在<slot></slot>内放置的默认内容)

3、具名插槽

默认插槽:一个定制的位置
具名插槽:给多个slot起名字从而定制多个位置

  1. 给slot使用name属性区分名字
    在这里插入图片描述
  2. template配合v-slot来对应定制的位置,v-slot可以简写为#
    在这里插入图片描述

4、作用域插槽

(1)插槽分为默认插槽具名插槽
(2)作用域插槽的作用:给插槽上绑定数据,将来使用组件时就可以用
(3)使用步骤

  1. 给slot标签以添加属性的方式传值
<slot :id='item.id' msg='测试文本'></slot>
  1. 所有添加的属性都会被收集到一个对象之中
{id:3,msg:'测试文本'}
  1. 在template中,通过#插槽名=‘obj’接收,默认插槽名为default
<组件名 :list='list'><template #default = 'obj'><button @click='del(obj.id)'>删除</button></template>
</组件名>

MyTable.vue

<template><table class="my-table"><thead><tr><th>序号</th><th>姓名</th><th>年纪</th><th>操作</th></tr></thead><tbody><tr v-for='(item,index) in data'><td>{{index + 1}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td>//1.给slot以添加属性的方式传值<slot :row='item'></slot>//2.将所有的属性添加到一个对象中,例如//{//	row:{id:1,name:xxx,age:18}//}</td></tr></tbody></table>
</template><script>
export default {props: {data: Array}
}
</script><style scoped>
.my-table {width: 450px;text-align: center;border: 1px solid #ccc;font-size: 24px;margin: 30px auto;
}
.my-table thead {background-color: #1f74ff;color: #fff;
}
.my-table thead th {font-weight: normal;
}
.my-table thead tr {line-height: 40px;
}
.my-table th,
.my-table td {border-bottom: 1px solid #ccc;border-right: 1px solid #ccc;
}
.my-table td:last-child {border-right: none;
}
.my-table tr:last-child td {border-bottom: none;
}
.my-table button {width: 65px;height: 35px;font-size: 18px;border: 1px solid #ccc;outline: none;border-radius: 3px;cursor: pointer;background-color: #ffffff;margin-left: 5px;
}
</style>

App.vue

<template><div><MyTable :data="list">//通过template #插槽名='变量名'来接受上述对象<template #default='obj'><button @click='del(obj.item.id)'>删除</button></template></MyTable><MyTable :data="list2"><template #default='obj'><button @click='show(obj.item)'>查看</button></template></MyTable></div>
</template><script>import MyTable from './components/MyTable.vue'export default {data () {return {list: [{ id: 1, name: '张小花', age: 18 },{ id: 2, name: '孙大明', age: 19 },{ id: 3, name: '刘德忠', age: 17 },],list2: [{ id: 1, name: '赵小云', age: 18 },{ id: 2, name: '刘蓓蓓', age: 19 },{ id: 3, name: '姜肖泰', age: 17 },]}},methods:{del(id){this.list = this.list.filter(item=>item.id!==id)},show(row){console.log(row)}}components: {MyTable}}
</script>

十二、路由入门

1、单页应用程序&路由介绍

单页应用程序:SPA-Single Page Application是指所有的功能都在一个html页面上实现
在这里插入图片描述
单页面应用程序,之所以开发效率高,性能好,用户体验好
最大的原因就是:页面按需更新
要按需更新,首先就需要明确:访问路径组件的对应关系!
访问路径 和 组件的对应关系如何确定呢? 路由
Vue中的路由:路径和组件映射关系

2、路由的基本使用

(1)VueRouter介绍

作用:修改地址栏路径时,切换显示匹配的组件
官网:https://v3.router.vuejs.org/zh/
使用步骤(5+2)
固定5个步骤:

  1. 下载 VueRouter 模块到当前工程,版本3.6.5
npm add vue-router@3.6.5
  1. main.js中引入VueRouter
import VueRouter from 'vue-router'
  1. 安装注册(main.js)
Vue.use(VueRouter)
  1. 创建路由对象(main.js)
const router = new VueRouter()
  1. 注入,将路由对象注入到new Vue实例中,建立关联(main.js)
new Vue({render: h => h(App),router:router
}).$mount('#app')

2个核心步骤

  • 创建需要的组件 (views目录),配置路由规则
//在main.js中
import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'const router = new VueRouter({routers:[{path:"/find",component:Find},{path:"/my",component:My},{path:"/friend",component:Friend}]
})
  • 配置导航,配置路由出口(路径匹配的组件显示的位置)
<div class="top">
//配置导航<a href="#/find">发现</a><a href="#/find">我的</a><a href="#/find">朋友</a>
</div>
<div class="content">
//配置路由出口<router-view></router-view>
</div>

3、views目录和components目录

.vue文件分为2类,都是 .vue文件(本质无区别)

  • 页面组件 (配置路由规则时使用的组件)
  • 复用组件(多个组件中都使用到的组件)
  1. src/views文件夹

    页面组件 - 页面展示 - 配合路由用

  2. src/components文件夹

    复用组件 - 展示数据 - 常用于复用

4、路由的模块封装

目标:将路由模块抽离出来,更利于维护
方法:将main.js中的路由配置抽离到router/index.js中,并在main.js中导入impor router from './router/index.js'
注意:更改原来组件的路径
路径简写:
脚手架环境下 @指代src目录,可以用于快速引入组件

import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'
等于
import Find from '@/views/Find'
import My from '@/views/My'
import Friend from '@/views/Friend'

5、使用router-link替代a标签实现高亮

(1)使用router-link替代a标签实现高亮

<div><div class="footer_wrap"><router-link to="/find">发现音乐</router-link><router-link to="/my">我的音乐</router-link><router-link to="/friend">朋友</router-link></div><div class="top"><router-view></router-view></div>
</div>

对比a标签

<div class="top">
//配置导航<a href="#/find">发现</a><a href="#/find">我的</a><a href="#/find">朋友</a>
</div>
<div class="content">
//配置路由出口<router-view></router-view>
</div>

(2)功能:

  1. 能跳转:配置to属性指定路径(必须),无需#,本质还是a标签
  2. 能高亮,默认会提供高亮类名,可以设置高亮样式
    • 使用router-link跳转后,当前点击的链接默认加了两个class的值 router-link-exact-activerouter-link-active
    • 给任意一个class属性添加高亮样式即可实现功能

router-link-exact-activerouter-link-active的区别:

  1. router-link-active模糊匹配:to=“/my” 可以匹配 /my、/my/a、/my/b …
  2. router-link-exact-active精确匹配:to=“/my” 仅可以匹配 /my

(3) 声明式导航:
router-link两个高亮类名太长了

const router = new VueRouter({routes: [...],linkActiveClass: "类名1",//配置模糊匹配的类名linkExactActiveClass: "类名2"//配置精确匹配的类名
})

十三、声明式导航-跳转传参

目标:在跳转路由时进行传值

1、跳转传参

  1. 查询参数传参
  • 语法格式:<router-link to="/path?参数名1=值1&参数名2=值2"></router-link>
  • 对应页面接受传递过来的值:$route.query.参数名
//Home
<div class="hot-link">热门搜索:<router-link to="/search?key=黑马程序员">黑马程序员</router-link><router-link to="/search?key=前端培训">前端培训</router-link><router-link to="/search?key=如何成为前端大牛">如何成为前端大牛</router-link>
</div>//Search
<p>搜索关键字: {{ $router.query.key }}</p>
  1. 动态路由传参
  • 配置动态路由
const router = new VueRouter({routes: [...,{ path: '/search/:words', //配置动态路由component: Search }]
})
  • 配置导航链接
规则:to="/path/参数值"
<router-link to="/search/黑马程序员">黑马程序员</router-link>
<router-link to="/search/前端培训">前端培训</router-link>
<router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
  • 对应页面组件接收传递过来的值
规则:$route.params.参数名
<p>搜索关键字: {{ $router.params.words }}</p>
  1. 差异
    查询参数传参:比较适合传多个参数
    动态路由传参:比较适合传单个参数
  2. 动态路由参数的可选符
const router = new VueRouter({routes: [...,{ path: '/search/:words?', //加上问号,可以不传参数component: Search }]
})

十四、Vue路由的重定向

重定向 => 匹配 / 后, 强制跳转 /home 路径\

{ path: 匹配路径, redirect: 重定向到的路径 },
比如:
const router = new VueRouter({routes:[{path:'/',redirect:'/home'},...]
})

十四、Vue路由的404

当路径找不到匹配时,给个提示页面

import NotFind from '@/views/NotFind'const router = new VueRouter({routes: [...{ path: '*', component: NotFind } ]
})

path:'*'前面的路径都匹配不上就命中最后这个路径,所以一定要放在最后一个

十五、Vue路由-模式设置

路由的路径看起来不自然, 有#,使用history路由看起来更加自然
hash路由和history路由对比:
hash路由(默认): http://localhost:8080/#/home
history路由:http://localhost:8080/home

const router = new VueRouter({mode:'histroy', //默认是hashroutes:[]
})

十六、编程式导航-两种路由跳转方式

点击按钮可以实现跳转

  1. path路径跳转(简单方便)
    $router指大的路由实例对象
//简单写法
this.$router.push('路由路径')//路由路径:/home或/search....//完整写法
this.$router.push({path: '路由路径'
})

路由路径:/home或/search…
2. name命名路由跳转(适合path路径长的场景)
配置路由时起个名字

const router = new VueRouter({routes: [...{ name:'路由名',path: '/path/xxx', component: xxx } ]
})

通过name进行跳转

this.$router.push({name: '路由名'
})

十七、路由跳转+传参

1、query传参+path跳转

//简单写法
this.$router.push('/路径?参数名1=值1&参数名2=值2')//完整写法
this.$router.push({path:'/路径',query:{参数名1:'参数值1',参数名2:'参数值2'}
})

2、query传参+name跳转

const router = new VueRouter({routes:[{name:'路由名',path:'/path/xxx',component:xxx}]
})
this.$router.push({name:'路由名',query:{参数名1:'参数值1',参数名2:'参数值2'}
})

3、动态路由传参+path跳转

//简单写法
this.$router.push('/路径/参数值')//完整写法
this.$router.push({path:'/路径/参数值',
})

4、动态路由传参+name跳转

const router = new VueRouter({routes:[{name:'路由名',path:'/path/:参数名',component:xxx}]
})this.$router.push({name:'路由名',params:{	参数名:'参数值'}
})

十八、VueCli自定义创建项目

目标:基于VueCli自定义创建项目架子

vue create demo

在这里插入图片描述

在这里插入图片描述

十九、ESlint代码规范

下载ESlint插件自动修改规范错误的代码

相关文章:

Vue2+Vue3 45-90集学习笔记

Vue2Vue3 45-90集学习笔记 小兔鲜首页 页面开发思路&#xff1a; 分析页面&#xff0c;按模块拆分组件&#xff0c;搭架子&#xff08;局部注册或全局注册&#xff09; 局部注册&#xff1a;App.js中 导入&#xff08;import&#xff09;&#xff0c;注册&#xff08;compon…...

【Web 服务器】的工作原理

&#x1f310; Web 服务器的工作原理 Web 服务器的主要作用是 接收客户端请求&#xff08;通常是浏览器发出的 HTTP/HTTPS 请求&#xff09;&#xff0c;处理请求&#xff0c;并返回相应的数据&#xff08;如网页、图片、API 响应等&#xff09;。 &#x1f4cc; 工作流程 1️…...

LeetCode 5 -- 区间DP | 中心拓展算法

题目描述 最长回文子串 数据规模为 5e5&#xff0c;必须 manacher 算法 1. DP 由于 r e v e r s e ( ) reverse() reverse() 的时间复杂度是 O ( N ) O(N) O(N)&#xff0c;因此暴力肯定是不行的。 d p dp dp 的思路&#xff1a;如果 s [ l . . r ] s[l..r] s[l..r] 是一个…...

IntelliJ IDEA中Spring Boot 3.4.x+集成Redis 7.x:最新配置与实战指南

‌前言 Spring Boot 3.4.x作为当前‌最新稳定版本‌&#xff0c;全面支持Java 17与Jakarta EE 10规范。本文以‌Spring Boot 3.4.1‌和‌Redis 7.x‌为例&#xff0c;详解如何在IDEA中快速接入Redis&#xff0c;涵盖‌最新依赖配置‌、‌数据序列化优化‌、‌缓存注解‌及‌高…...

数仓建模中计算累计销量

在数仓建模中计算累计销量&#xff0c;通常需要结合时间维度和业务逻辑设计合理的模型与计算逻辑。以下是分步骤的实现思路和示例&#xff1a; 1. 模型设计 累计销量的计算通常基于星型模型或雪花模型&#xff0c;核心结构包括&#xff1a; 事实表&#xff1a;记录每一笔销售…...

(多看) CExercise_05_1函数_1.2计算base的exponent次幂

题目&#xff1a; 键盘录入两个整数&#xff1a;底(base)和幂指数(exponent)&#xff0c;计算base的exponent次幂&#xff0c;并打印输出对应的结果。&#xff08;注意底和幂指数都可能是负数&#xff09; 提示&#xff1a;求幂运算时&#xff0c;基础的思路就是先无脑把指数转…...

Pollard‘s Rho 算法

Pollard’s Rho 算法&#xff1a;一场数学与计算机科学的巧妙结合 在现代计算机科学中&#xff0c;素数分解、整数因子化问题有着广泛的应用&#xff0c;尤其是在密码学领域。然而&#xff0c;当面对一个大合数时&#xff0c;寻找其因子仍然是一个非常复杂的问题。我们常常依赖…...

8款分形长虹玻璃科幻渐变海报设计JPG背景素材 The Gradient Backgrounds Pack

天空从未如此美好 — 直到有人将日落洒在您的屏幕上。这些渐变是带有心跳的液体颜色&#xff0c;从熔化的金色转变为深紫色&#xff0c;就像地平线一样。 8 个背景中的每一个都以 45003000 像素和 300dpi 的速度脉冲&#xff0c;清晰到足以让您感觉自己可以直接踏入光芒中。但这…...

AIGC9——​AIGC时代的用户体验革命:智能交互与隐私保护的平衡术

引言&#xff1a;当AI成为交互主角 2024年&#xff0c;淘宝AI客服"阿里小蜜"日均处理20亿次咨询&#xff0c;日本虚拟偶像"初音未来"演唱会门票3秒售罄——这些现象标志着AIGC已深度融入人机交互场景。但与此同时&#xff0c;过度个性化的推荐引发"信…...

vm虚拟机虚拟出网卡并ping通外网

在 Linux 和 Windows 系统中&#xff0c;即使不使用网络命名空间&#xff08;namespace&#xff09;&#xff0c;也能实现虚拟网卡上网。以下是不同场景下的实现方法&#xff1a; 一、Linux 系统&#xff08;不使用网络命名空间&#xff09; 1. 直接创建虚拟网卡对&#xff08…...

基于时间卷积网络TCN实现电力负荷多变量时序预测(PyTorch版)

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…...

ESXi8的部署过程

目录 一、系统安装 二、ESXI8的序列号 三、挂载硬盘和新建VMFS数据分区 四、通过数据存储浏览器上传下载文件 五、Windows远程桌面端口隐射 六、导出虚机 一、系统安装 1、使用UtrIOS系统制作ESXI8的启动盘; 2、服务器启动F8按键进入Popup启动选项,选择U盘启动; 3、安…...

IntelliJ IDEA 2020~2024 创建SpringBoot项目编辑报错: 程序包org.springframework.boot不存在

目录 前奏解决结尾 前奏 哈&#xff01;今天在处理我的SpringBoot项目时&#xff0c;突然遇到了一些让人摸不着头脑的错误提示&#xff1a; java: 程序包org.junit不存在 java: 程序包org.junit.runner不存在 java: 程序包org.springframework.boot.test.context不存在 java:…...

Windows 权限配置文件解析与安全分析(GPP,GPO,LSA)

在 Windows 网络环境中&#xff0c;权限配置文件用于管理用户权限、密码策略和访问控制&#xff0c;涵盖组策略首选项&#xff08;GPP&#xff09;、本地安全策略&#xff08;LSA&#xff09;、注册表以及 Active Directory 组策略&#xff08;GPO&#xff09; 等。这些配置文件…...

【微服务】基础概念

1.什么是微服务 微服务其实就是一种架构风格&#xff0c;他提倡我们在开发的时候&#xff0c;一个应用应该是一组小型服务而组成的&#xff0c;每一个服务都运行在自己的进程中&#xff0c;每一个小服务都通过HTTP的方式进行互通。他更加强调服务的彻底拆分。他并不是仅局限于…...

MYOJ_4342:(洛谷P1087)[NOIP 2004 普及组] FBI 树(二叉树实操,递归提高)

题目描述 我们可以把由 “0” 和 “1” 组成的字符串分为三类&#xff1a;全 “0” 串称为 B 串&#xff0c;全 “1” 串称为 I 串&#xff0c;既含 “0” 又含 “1” 的串则称为 F 串。 FBI 树是一种二叉树&#xff0c;它的结点类型也包括 F 结点&#xff0c;B 结点和 I 结点三…...

LLM(13):词编码后的位置

原则上&#xff0c;token 嵌入是大型语言模型&#xff08;LLM&#xff09;的合适输入。然而&#xff0c;LLM 的一个小缺点是它们的自注意力机制无法指导序列中 token 的位置或顺序。在前面介绍的嵌入层的工作方式中&#xff0c;无论 token ID 在输入序列中的位置如何&#xff0…...

MINIQMT学习课程Day4

聚宽的模拟/实盘跟单系统&#xff0c;已经全部介绍完毕&#xff0c;上传完毕了&#xff0c;相信大家已经可以进行聚宽的miniqmt的交易了。如果还有疑问&#xff0c;私信我进行沟通。 现在开始进入新的课题&#xff0c;如何学习python&#xff0c;我不教那些乱七八糟的&#xff…...

AWS云服务:大数据公司实现技术突破与商业价值的核心引擎

在数据驱动决策的时代&#xff0c;大数据公司面临着海量数据存储、实时计算、复杂分析及安全合规等核心挑战。如何高效构建弹性、可扩展且低成本的技术架构&#xff0c;成为企业能否在竞争中胜出的关键。亚马逊云科技&#xff08;AWS&#xff09;作为全球云计算领域的领导者&am…...

Openpyxl使用教程(包含处理大数据量案例)

文章目录 一、简介功能特性应用场景使用优势 二、常用方法1、工作簿wb2、工作表ws 三、案例1、创建新工作簿2、将Excel数据存入list中3、按行读取文件(适合大文件)4、按指定行读取文件(适合大文件) 一、简介 在 Python 数据处理领域&#xff0c;openpyxl 凭借其卓越的功能与易…...

蓝桥杯15届 宝石组合

问题描述 在一个神秘的森林里&#xff0c;住着一个小精灵名叫小蓝。有一天&#xff0c;他偶然发现了一个隐藏在树洞里的宝藏&#xff0c;里面装满了闪烁着美丽光芒的宝石。这些宝石都有着不同的颜色和形状&#xff0c;但最引人注目的是它们各自独特的 “闪亮度” 属性。每颗宝…...

THE UNIVERSITY OF MANCHESTER-NUMERICAL ANALYSIS 1-3.4数值积分-复合积分公式

3.4.1 复合梯形法则 梯形法则仅使用两个点来近似积分,显然对于大多数应用来说,这不足够。为了提高精度,有多种方法可以利用更多的点和函数值。正如我们刚才在Newton-Cotes方法和辛普森法则中所看到的,一种方法是使用更高阶的插值函数。另一种方法是将区间划分为更小的区间…...

嵌入式系统应用-拓展-相关开发软件说明

这里以STM32的系列产品为例子&#xff0c;利用MDK的集成开发平台进行开发过程中&#xff0c;所有相关软件安装说明。 1 集成开发环境安装 1.1 MDK 下载 1.1.1 官网下载 官方下载地址&#xff1a; https://www.keil.com/download/product/ 选择MDK-ARM &#xff0c;填写一些…...

react实现上传图片到阿里云OSS以及问题解决(保姆级)

一、优势 提高上传速度&#xff1a;前端直传利用了浏览器与 OSS 之间的直接连接&#xff0c;能够充分利用用户的网络带宽。相比之下&#xff0c;后端传递文件时&#xff0c;文件需要经过后端服务器的中转&#xff0c;可能会受到后端服务器网络环境和处理能力的限制&#xff0c;…...

嵌入式学习笔记——ARM-中断与异常

文章目录 中断与异常的区别中断与 DMA 的区别中断能否睡眠&#xff1f;下半部能否睡眠&#xff1f;1. 中断处理程序不能睡眠2. 下半部&#xff08;SoftIRQ、Tasklet、Workqueue&#xff09; 中断处理注意点1. 快进快出2. 避免阻塞3. 正确返回值4. 如何处理大量任务5. 避免竞态问…...

OpenHarmony子系统开发 - 安全(十二)

OpenHarmony SELinux开发指导&#xff08;五&#xff09; 一、OpenHarmony SELinux常见问题 neverallow编译报错处理 现象描述 编译SELinux时会进行neverallow检查&#xff0c;当配置的策略不合理时&#xff0c;可能出现违反neverallow编译报错。 neverallow check failed…...

深入解析ARM与RISC-V架构的Bring-up核心流程

深入解析ARM与RISC-V架构的Bring-up核心流程 作者&#xff1a;嵌入式架构探索者 | 2023年10月 引言 在嵌入式开发中&#xff0c;处理器的Bring-up&#xff08;启动初始化&#xff09;是系统运行的第一道门槛。ARM和RISC-V作为两大主流架构&#xff0c;其Bring-up流程既有共性…...

【力扣hot100题】(054)全排列

挺经典的回溯题的。 class Solution { public:vector<vector<int>> result;void recursion(vector<int>& nums,vector<int>& now){if(nums.size()0){result.push_back(now);return ;}for(int i0;i<nums.size();i){now.push_back(nums[i]);…...

vue中如何动态的绑定图片

在项目中遇到需要动态的改变图片路径&#xff0c;图片路径并非是从后台获取过来的数据。 因此在data中必须用require加载&#xff0c;否则会当成字符串来处理。...

湖北师范大学计信学院研究生课程《工程伦理》12.6章节练习

1【单选题】下列哪个不是数字身份的特点? A. 多样性 B. 唯一性 C. 可变性 D. 允许匿名和假名 2【单选题】下列哪项不是现代国家的基本职能。 A. 保护政权统一 B. 保护本国面对其他国家侵犯 C. 保护国内每个人免受他人侵犯 D. 承担发展国民经济 3【单选题】哪个国家在全球率先发…...

prism WPF 登录对话框登录成功后显示主界面

prism WPF 登录对话框登录成功后显示主界面 项目结构 LoginUC.xaml <UserControl x:Class"PrismWpfApp.Views.LoginUC"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml…...

MySQL统计信息

1. 什么是统计信息&#xff1f; 统计信息就像是数据库的"地图"&#xff0c;它告诉优化器&#xff1a; 每个表有多大&#xff08;有多少行数据&#xff09; 每个索引的"区分度"&#xff08;有多少不同的值&#xff09; 数据分布情况&#xff08;哪些值出…...

Spark,配置hadoop集群2

编写Hadoop集群启停脚本 1.建立新文件&#xff0c;编写脚本程序 在hadoop101中操作&#xff0c;在/root/bin下新建文件&#xff1a;myhadoop&#xff0c;输入如下内容&#xff1a; 2.分发执行权限 保存后退出&#xff0c;然后赋予脚本执行权限 [roothadoop101 ~]$ chmod x /r…...

⭐算法OJ⭐重建行程【哈密尔顿路径】(C++ 实现)Reconstruct Itinerary

You are given a list of airline tickets where tickets[i] [from_i, to_i] represent the departure and the arrival airports of one flight. Reconstruct the itinerary in order and return it. All of the tickets belong to a man who departs from “JFK”, thus, t…...

大模型如何优化数字人的实时交互与情感表达

标题:大模型如何优化数字人的实时交互与情感表达 内容:1.摘要 随着人工智能技术的飞速发展&#xff0c;数字人在多个领域的应用愈发广泛&#xff0c;其实时交互与情感表达能力成为提升用户体验的关键因素。本文旨在探讨大模型如何优化数字人的实时交互与情感表达。通过分析大模…...

【含文档+PPT+源码】基于SpringBoot+Vue旅游管理网站

项目介绍 本课程演示的是一款 基于SpringBootVue旅游管理网站&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该项目附…...

理解OSPF Stub区域和各类LSA特点

之前学习到OSPF特殊区域和各类类型LSA的分析后&#xff0c;一直很混乱&#xff0c;在网上也难找到详细的解释&#xff0c;在看了 HCNP书本内容后&#xff0c;对这块类容理解更加清晰&#xff0c;本次内容&#xff0c;我们使用实验示例&#xff0c;来对OSPF特殊区域和各 类型LSA…...

AI智算-K8s如何利用GPFS分布式并行文件存储加速训练or推理

文章目录 GPFS简介核心特性存储环境介绍存储软件版本客户端存储RoCEGPFS 管理(GUI)1. 创建 CSI 用户2. 检查GUI与k8s通信文件系统配置1. 开启配额2. 启用filesetdf文件系统3. 验证文件系统配置4. 启用自动inode扩展存储集群配置1. 启用对根文件集(root fileset)配额2. igno…...

Linux如何设置bash为默认shell

大部分情况下&#xff0c;Linux的默认shell是bash&#xff0c;但某些Linux发行版&#xff0c;例如Kali&#xff0c;默认的终端是zsh&#xff0c;本文以Kali为例&#xff0c;将Kali的默认shell从zsh改为bash。 其实Kali早期的shell也是bash&#xff0c;2020 版本之后&#xff1a…...

leetcode-代码随想录-链表-翻转链表

题目 链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]class Solution { public:ListNode* rev…...

CSS快速上手

第一章 CSS基础 首先来回答2个问题。 1.CSS是什么&#xff1f; CSS是用来控制网页外观的一门技术。 2.前端最核心的技术是什么&#xff1f;他们分别是用来干吗的&#xff1f; 前端最核心的技术有&#xff1a;HTML、CSS、JavaScript。 HTML用于控制网页的结构&#xff0c;CSS…...

虚拟现实 UI 设计:打造沉浸式用户体验

VR UI 设计基础与特点 虚拟现实技术近年来发展迅猛&#xff0c;其独特的沉浸式体验吸引了众多领域的关注与应用。在 VR 环境中&#xff0c;UI 设计扮演着至关重要的角色&#xff0c;它是用户与虚拟世界交互的桥梁。与传统 UI 设计相比&#xff0c;VR UI 设计具有显著的特点。传…...

搜索与图论 树的广度优先遍历 图中点的层次

适用性 当边的权值相等时&#xff0c;使用广度优先遍历&#xff0c;往往是求图&#xff08;树&#xff09;的最短路径最优方法 抽象理解 伪代码 建立队列 添加第一个起始点到队列&#xff0c;标记其不可访问 while(队列不为空)//开始循环{获取队列中的队首元素&#xff0c;获…...

DHCP之报文格式

字段说明&#xff1a; op (op code): 表示报文的类型&#xff0c;取值为 1 或 2&#xff0c;含义如下 1:客户端请求报 2:服务器响应报文 Secs (seconds):由客户端填充&#xff0c;表示从客户端开始获得 IP 地址或 IP 地址续借后所使用了的秒数&#xff0c;缺省值为 3600s。 F…...

Docker安装、配置Redis

1.如果没有docker-compose.yml文件的话&#xff0c;先创建docker-compose.yml 配置文件一般长这个样子 version: 3services:redis:image: redis:latestcontainer_name: redisports:- "6379:6379"command: redis-server --requirepass "123456"restart: a…...

空中无人机等动态目标识别2025.4.4

* 一.无人机动态数据概述* 1.1 空中动态数据定义 在无人机动态数据的范畴中&#xff0c; 空中动态数据 是一个核心概念。它主要包括无人机在飞行过程中产生的各种实时信息&#xff0c;如 位置、速度、高度、姿态 等[1]。这些数据通过传感器系统采集&#xff0c;并以特定格式存…...

【AI论文】通过R1-Zero类似训练改进视觉空间推理

摘要&#xff1a;人们越来越关注提升多模态大型语言模型&#xff08;MLLMs&#xff09;的推理能力。作为在物理领域中运作的人工智能代理的基石&#xff0c;基于视频的视觉空间智能&#xff08;VSI&#xff09;成为MLLMs最为关键的推理能力之一。本研究首次深入探讨了通过R1-Ze…...

游戏引擎学习第203天

回顾当前情况 在这里我将直播完成整个游戏的制作。我们现在面临一些技术上的困难&#xff0c;确实如此。我的笔记本电脑的电源接口坏了&#xff0c;所以我不得不准备了这台备用笔记本&#xff0c;希望它能够正常工作。我所以希望一切都还好&#xff0c;尽管我不完全确定是否一…...

从菜鸟到高手的提示词优化指南‌

如何用“说话的艺术”榨干AI潜力&#xff1f; ——从菜鸟到高手的提示词优化指南‌ 一、什么是好的提示词&#xff1f; 核心公式‌&#xff1a;精准提问 明确需求 限定条件 示范案例 好比让AI帮你买咖啡—— ❌ 差提示&#xff1a;“帮我买杯咖啡”&#xff08;AI可能随便…...

应对高并发的根本挑战:思维转变【大模型总结】

以下是对这篇技术总结的详细解析&#xff0c;以分步说明的形式呈现&#xff0c;帮助理解亿万并发场景下的核心策略与创新思维&#xff1a; 一、应对高并发的根本挑战&#xff1a;思维转变 1. 传统架构的局限 问题&#xff1a;传统系统追求零故障和强一致性&#xff0c;但在海…...