点击跳转到Vue.js学习参考文档

文章目录

  • vue3.0介绍
    • 什么是Vue.js
    • 安装
  • vite构建工具工具创建vue3项目
    • 使用npm创建
    • 使用yarn
    • vue3项目结构
  • Vue声明式语法与数据双向绑定
    • 命令式
    • 声明式
    • 数据双向绑定
  • 模板语法
    • 双括号语法
    • v-once
    • v-html
    • v-bind
    • 模板语法中使用JavaScript表达式
  • 动态指令
  • 计算属性
  • watch监听数据的变化
  • 类的多种绑定方式
    • 放置字符串
    • 放置对象
    • 放置数组
    • 数组和对象的结合
  • Style样式的多种绑定方式
    • 放置字符串
    • 放置对象
    • 放置数组
  • v-if 和 v-show
  • v-for循环
  • 事件与参数、时间修饰符
    • 事件修饰符
    • 按键修饰符
    • 系统修饰符
    • 鼠标修饰符
  • 表单输入双向绑定、修饰符
    • 文本框 text
    • 多行文本框textarea
    • 复选框checkbox
    • 单选框radio
    • 选项框 select
    • 数据绑定v-model的修饰符
      • .lazy
      • .number
      • .trim
  • 组件
    • 父组件向子组件传递数据props
    • 通过provide和inject 将数据提供给子组件
    • 子组件向父组件传递数据:自定义事件
  • Vue3生命周期
    • beforeCreate()和created()
    • beforeMount()和mounted()
    • beforeUpdate()和updated()
    • beforeUnmount()和unmounted()
  • 合成API:Composition API
    • Composition API :单个值ref
    • Composition API :函数
    • Composition API :对象 reactive({})
    • Composition API :监听数据变化
      • watchEffect
      • watch
  • setup详解
    • 使用setup接收父组件数据
    • 生命周期
  • Vue3路由:vue-router
    • 路由的基本使用
    • 动态路由
    • 路由正则与重复参数
    • 嵌套路由
    • 程序化导航:使用js跳转页面
      • 导航到其他位置
      • 替换当前位置
      • 替换当前位置
    • 命名路由与重定向和别名
      • 命名路由
      • 重定向:redirect
      • 别名:alias
    • 路由模式
      • 哈希模式
      • HTML5模式
    • 导航守卫
      • router.beforeEach
      • router.beforeResolve
      • beforeEnter
      • 组件内防护
  • 状态管理
    • 通过reactive响应式对象管理
    • Vuex状态管理
      • map辅助函数
  • vue3 实现前后端交互
    • 通过fetch()
    • 通过axios()
  • vite 配置跨域请求
  • Mock.js 模拟获取数据
  • vue脚手架cli的使用
  • 模块化管理 vuex
    • 命名空间
    • 模块中辅助函数的写法

vue3.0介绍

什么是Vue.js

1、前端开发框架
2、用于构建用户界面的渐进式框架
3、简化复杂的开发过程
4、Vue 也完全有能力为复杂的单页应用程序提供支持

安装

将 Vue.js 添加到项目中有四种主要方法:

1、在页面上将其导入为CDN包

<script src="https://unpkg.com/vue@next"></script>

2、下载 JavaScript 文件并自行托管
如果您想避免使用构建工具但不能在生产中使用 CDN,那么您可以下载相关.js文件并使用您自己的 Web 服务器托管它。然后您可以使用

3、使用npm安装
npm 是使用 Vue 构建大型应用程序时推荐的安装方法

4、使用官方CLI构建项目,该项目为现代前端工作流程(例如,热重载、lint-on-save 等)提供包含电池的构建设置
Vue 提供官方 CLI (打开新窗口)用于快速搭建雄心勃勃的单页应用程序

vite构建工具工具创建vue3项目

使用npm创建

前提:安装Node.js
步骤如下:

$  npm init vite@latest <project-name>  或者   $  npm init vite-app <project-name>$ cd <project-name>
$ npm install
$ npm run dev

使用yarn

$ yarn create vite <project-name> --template vue
$ cd <project-name>
$ yarn
$ yarn dev

vue3项目结构

Vue声明式语法与数据双向绑定

命令式

document.querySelector('h1').innerHTML="小范宝贝"

声明式

export default {name: "App",data(){return{msg:'小范同学'}},methods:{changeMsg(){this.msg = '小范美女'}}
};

数据双向绑定

数据变了,页面内容也会变,页面内容变了,数据也随之改变

    <h1 @click="changeMsg">{{msg}}</h1><input type="text" v-model="msg"  />

模板语法

双括号语法

<h1>{{msg}}</h1>

v-once

一次性插值,只渲染一次

 <!-- v-once指令,使得内容只渲染一次 --><h1 @click="changeMsg" v-once>{{msg}}</h1>

v-html

在内容中插入HTML代码

 <!--v-html指令 使得内容插入html的代码  --><div>{{content}}</div><div v-html="content"></div>

v-bind

绑定属性的内容

<!-- v-bind指令 绑定属性的内容 --><div v-bind:id="id"></div>

模板语法中使用JavaScript表达式

<template><div><!-- JavaScript可以在模板语法中使用 --><!-- 双括号语法 --><h1>{{ msg }}</h1><!-- split()分割msg字符串,得到一个数字 --><h1>{{msg.split('')}}</h1><!-- reverse() 使得数组内容颠倒 --><h1>{{msg.split('').reverse()}}</h1><!-- join()使得数组内容合并成字符串 --><h1>{{msg.split('').reverse().join('')}}</h1><!-- 可以使用三元运算符 --><div>{{color=="green"?"开心":"难过"}}</div></div>
</template><script>
// 声明式
export default {name: "App",data() {return {msg: "Hello,Word!",color:"green"};},methods: {},
};
</script>

动态指令

指令对应的属性名称是可以修改的

<template><div><!-- 动态指令 --><div v-bind:[attrbuteName]="d1"></div><button @click="toggleColor">点击切换颜色</button></div>
</template><script>
// 声明式
export default {name: "App",data() {return {attrbuteName:"class",d1:'d1'};},methods: {toggleColor() {this.attrbuteName = "id";},},
};
</script><style>#d1{margin-left: 47%;width: 100px;height: 100px;background-color: yellow;}.d1{margin-left: 47%;width: 100px;height: 100px;background-color: blue;}
</style>

计算属性

  • 简化代码
<template><div><!-- 原来的msg --><h1>{{msg}}</h1><!-- 运用JS语句颠倒msg --><h1>{{msg.split('').reverse().join('')}}</h1><!-- 使用计算属性颠倒msg --><h1>{{reverseMsg}}</h1></div>
</template><script>
// 声明式
export default {name: "App",data() {return {msg: 'Hello World'};},computed:{reverseMsg(){return this.msg.split('').reverse().join('')}},methods: {toggleColor() {this.attrbuteName = "id";},},
};
</script>

watch监听数据的变化

想要监听数据的变化,可以使用watch监听,里面写监听目标变量的函数,里面有两个参数,第一个参数是新值,第二个参数是旧值。

<template><div><!-- 原来的msg --><h1>{{msg}}</h1><input type="text" v-model="msg"></div>
</template><script>
// 声明式
export default {name: "App",data() {return {msg: 'Hello World'};},watch:{msg(newValue,oldValue){if(newValue.length<10){alert("输入的值太少了!!!")}}}};
</script>

类的多种绑定方式

放置字符串

<template><div><!-- 类class --><!-- 第一种写法,放置字符串 --><h1 v-bind:class = "msg">hello</h1></div>
</template><script>
// 声明式
export default {name: "App",data() {return {msg: 'Hello World'};},
};
</script>

放置对象

<template><div><!-- 类class --><!-- 放置对象 --><h1 v-bind:class="{active:isActive}">Hello</h1><button @click="toggleActive">切换样式</button></div>
</template><script>
// 声明式
export default {name: "App",data() {return {isActive: true};},methods:{toggleActive(){this.isActive=!this.isActive}}};
</script>
<style scoped>.active{background-color: yellow;}
</style>

放置数组

<template><div><!-- 类class --><!-- 放置数组 --><h1 :class="arr">Hello</h1><button  @click="toggleActive">切换类</button></div>
</template><script>
// 声明式
export default {name: "App",data() {return {arr: ['swiper','active']};},methods:{toggleActive(){this.arr.pop()}}
};
</script>

数组和对象的结合

<template><div><!-- 类class --><!-- 数组和对象的结合 --><h1 :class="[className, {active:isActive}]">Hello</h1><button @click="toggleActive">切换类</button></div>
</template><script>
// 声明式
export default {name: "App",data() {return {className : "abc",isActive : true};},methods:{toggleActive(){this.className= "cba",this.isActive = !this.isActive}}};
</script>
<style scoped>
.active {background-color: yellow;
}
</style>


Style样式的多种绑定方式

放置字符串

<template><div><!-- 类class --><!-- 第一种写法:放置字符串 --><h1 :style="msg">Hello</h1></div>
</template><script>
// 声明式
export default {name: "App",data() {return {msg: "background:red;"};},
};
</script>

放置对象

<template><div><!-- 类class --><!-- 第一种写法:放置字符串 --><h1 :style="{background: 'purple'}">Hello</h1></div>
</template><script>
// 声明式
export default {name: "App",data() {return {};},
};
</script>

放置数组

<template><div><!-- 类class --><!-- 第一种写法:放置字符串 --><h1 :style="[styleObj,{boxSizing: 'border-box'}]">Hello</h1></div>
</template><script>
// 声明式
export default {name: "App",data() {return {styleObj:{background: "pink",border: '1px solid blue'}};},
};
</script>

v-if 和 v-show

  • v-if…v-else-if…v-else… 可以根据不同的条件显示多个内容,频繁切换的话,较为消耗性能

  • v-show 根据条件确定是否显示单个内容,不显示时,其实是将样式改为display: none 所以性能消耗较小

<template><div><!-- 设置多个内容切换显示 --><h1 v-if = "user == '超级VIP'"> 欢迎金主爸爸</h1><h1 v-else>充值使你更强大</h1><button @click="toggleUser">切换用户</button><!-- 设置一个内容切换显示 --><h1 v-show="isShow">只显示我一个</h1><button @click="toggleShow">切换</button></div>
</template><script>
// 声明式
export default {name: "App",data() {return {user:'超级VIP',isShow: true};},methods:{toggleUser(){this.user = "普通用户"},toggleShow:function(){this.isShow = !this.isShow}}
};
</script>

v-for循环

  • 循环数组
  • 循环数组里的对象
  • 循环对象
<template><div><!-- 循环数组 --><ol><li v-for="(item, i) in news" :key="i">{{ item }}====>{{ i }}</li></ol><!-- 循环数组里的对象 --><ol><li v-for="(item, i) in news1" :key="i">{{ item.title }}==>{{ item.content }}===>{{ item.athor }}====>{{ i }}</li></ol><!-- 循环对象 --><ol><li v-for="(item, i) in athor" :key="i">{{ item }}====>{{ i }}</li></ol></div>
</template><script>
// 声明式
export default {name: "App",data() {return {news: ["11111", "222222", "333333"],news1: [{title: "我是标题1",content: "我是内容1",athor: "作者1",},{title: "我是标题2",content: "我是内容2",athor: "作者2",},],athor:{name:'lingLing',age: '18'}}},
};
</script>

事件与参数、时间修饰符

绑定事件使用 v-on(简写@)

  • 绑定事件不需要参数
<h1 @click="addEvent">{{num}}</h1>
  • 绑定事件,直接处理表达式
 <h1 @click="num += 2">{{num}}</h1>
  • 绑定事件,传递参数
 <h1 @click=" addEvent1(20)">{{num}}</h1>
  • 绑定事件。传递 $event事件对象和参数
<h1 @click=" addEvent1(20,$event)">{{num}}</h1>
  • 一个事件绑定多个处理函数
 <h1 :style="{background:color}" @click="addEvent1(20,$event),changeColor($event)">{{num}}</h1>

事件修饰符

  • 阻止事件冒泡 .stop
  • 阻止默认事件 .prevent
  • 事件只触发一次 .once
<h1 @click.once=" addEvent1(20,$event)">{{num}}</h1>

按键修饰符

enter/tap.delete/esc/space/up/down/left/right

 <input type="text" @keydown.enter="searchEvent">

系统修饰符

.ctrl/.alt/.shift/.meta

鼠标修饰符

.left/.right/.middle
<template><div><!-- 绑定事件,不需要参数 --><h1 @click="addEvent">{{num}}</h1><!-- 绑定事件,直接处理表达式 --><h1 @click="num += 2">{{num}}</h1><!-- 绑定事件,传递参数 --><h1 @click=" addEvent1(20)">{{num}}</h1><!--绑定事件。传递 $event事件对象和参数 --><h1 @click=" addEvent1(20,$event)">{{num}}</h1>  <!-- 一个事件绑定多个处理函数 --><h1 :style="{background:color}" @click="addEvent1(20,$event),changeColor($event)">{{num}}</h1><!-- 事件修饰符 --><!-- 阻止事件冒泡 .stop阻止默认事件 .prevent事件只触发一次 .once--><h1 @click.once=" addEvent1(20,$event)">{{num}}</h1>  <!-- 按键修饰符enter/tap.delete/esc/space/up/down/left/right系统修饰符.ctrl/.alt/.shift/.meta鼠标修饰符.left/.right/.middle--><input type="text" @keydown.enter="searchEvent"></div>
</template><script>
// 声明式
export default {name: "App",data() {return {num:0,color: 'red'}},methods:{addEvent:function(e){console.log(e)this.num += 2},addEvent1:function(number){this.num += number},addEvent2:function(number,event){this.num += number},changeColor:function(){this.color = 'pink'},searchEvent:function(){console.log("执行了搜索事件!!!")}}
};
</script>

表单输入双向绑定、修饰符

文本框 text

*单行本文框数据的双向绑定

<input v-model="searchKey" type="text" @keydown="searchEvent" />

多行文本框textarea

  • 多行文本框的数据绑定
<textarea v-model="lineText" name="textarea"  id="" cols="30" rows="10"></textarea>

复选框checkbox

  • 复选框的数据绑定,获取的是是否选中的内容
<input type="checkbox" name="likes" v-model="fruits" value="柿子"><input type="checkbox" name="likes" v-model="fruits" value="香蕉"><input type="checkbox" name="likes" v-model="fruits" value="葡萄"><input type="checkbox" name="likes" v-model="fruits" value="苹果">

单选框radio

只能选一个值

<input type="radio" name="sex" value="man" v-model="picked">
<input type="radio" name="sex" value="woman" v-model="picked">

选项框 select

添加multiple属性可以选择多个选项

<select name="citys"  v-model="citys" multiple ><option value="广州"></option><option value="上海"></option><option value="北京"></option><option value="成都"></option></select>

数据绑定v-model的修饰符

.lazy

input变为change事件改变值,焦点失焦后才改变

<input v-model.lazy="searchKey1" type="text" @keydown="searchEvent" />

.number

把输入值转换为数字类型

<input v-model.lazy.number="searchKey2" type="text" @keydown="searchEvent" />

.trim

去掉空格

 <input v-model.lazy.trim="searchKey3" type="text" @keydown="searchEvent" />

案例代码

<template><div><!-- 单行本文框数据的双向绑定 --><input v-model="searchKey" type="text" @keydown="searchEvent" /><h1>{{ searchKey }}</h1><!-- 多行文本框的数据绑定 --><textarea v-model="lineText" name="textarea"  id="" cols="30" rows="10"></textarea><h1>{{ lineText }}</h1><!-- 复选框的数据绑定,获取的是是否选中的内容--><input type="checkbox" name="like" v-model="checked" value="123"><h1>{{checked}}</h1><!-- 复选框多个值的情况 --><input type="checkbox" name="likes" v-model="fruits" value="柿子"><input type="checkbox" name="likes" v-model="fruits" value="香蕉"><input type="checkbox" name="likes" v-model="fruits" value="葡萄"><input type="checkbox" name="likes" v-model="fruits" value="苹果"><h1>{{fruits}}</h1><!-- 单选框的数据绑定 --><input type="radio" name="sex" value="man" v-model="picked"><input type="radio" name="sex" value="woman" v-model="picked"><h1>{{picked}}</h1><!-- 单选选项框的数据绑定 --><select name="city"  v-model="city"><option value="广州"></option><option value="上海"></option><option value="北京"></option><option value="成都"></option></select><h1>{{city}}</h1><!-- 多选选项框的数据绑定 --><select name="citys"  v-model="citys" multiple ><option value="广州"></option><option value="上海"></option><option value="北京"></option><option value="成都"></option></select><h1>{{citys}}</h1><!-- 表单获取的是是否选中的内容 --><input type="checkbox" name="like" v-model="checked1" true-value="喜欢" false-value="不喜欢"><h1>{{checked1}}</h1><!-- 修饰符 --><!-- .lazy/input变为change事件改变值,焦点失焦后才改变 --><input v-model.lazy="searchKey1" type="text" @keydown="searchEvent" /><h1>{{searchKey1}}</h1><!-- .number 把输入值转换为数字类型 --><input v-model.lazy.number="searchKey2" type="text" @keydown="searchEvent" /><h1>{{searchKey2}}</h1>、<input v-model.lazy.trim="searchKey3" type="text" @keydown="searchEvent" /><h1>{{searchKey3}}</h1></div>
</template><script>
// 声明式
export default {name: "App",data() {return {searchKey: "百度一下",lineText: "",checked: false,fruits:[],picked:'',city:'',citys:[],checked1:'',searchKey1: "百度一下",searchKey2:'转换为数字类型',searchKey3:'去掉空格'};},methods: {searchEvent: function () {console.log("执行了搜索事件!!!");},},
};
</script>

组件

父组件向子组件传递数据props

父组件数据newContent绑定在content ,子组件通过props接收父组件的数据
父组件 App.vue代码如下:

<template><div><!-- 父组件数据newContent绑定在content  --><News :content = "newsContent"></News></div>
</template><script>
// 声明式
import News from './components/News.vue'
export default {name: "App",data() {return {newsContent:"23岁女星与男子开房被原配抓包!!!"};},methods: {},components:{News}
};
</script>

子组件 App.vue代码如下:

<template><div><h1>新闻内容是{{content}}</h1></div>
</template>
<script>
export default {// 子组件通过props接收父组件的数据props:["content"]
}
</script>

通过provide和inject 将数据提供给子组件

父组件通过provide()将数据提供出去,子组件通过inject()将数据注入进来
父组件代码:App.vue

<template><div><Student></Student></div>
</template><script>
import { reactive,provide} from "vue";
import Student from './components/Student.vue'
export default {name: "App",data() {return {};},setup() {const student = reactive({name: "小红",age: 18,grade: "初一",});// 将数据提供出去provide("stu", student);return { };},components:{Student},
};
</script>

子组件代码:Student.vue

<template><div><h1>userName:{{ name }}</h1><h1>age: {{ age }}</h1><h1>年级:{{grade}}</h1></div>
</template><script>
import { inject } from "vue";
export default {setup() {// 将父组件提供的数据注入进来const student = inject('stu')return {...student}},
};
</script>

运行截图如下

子组件向父组件传递数据:自定义事件

子组件触发自定义事件1,父组件监听自定义事件1,并将监听到的值给自定义事件2
App.vue代码如下:

<template><div><!-- 子组件将数据传递给父组件,监听到sendParentMsg被触发就会运行自定义事件sendChildMsg --><Login @sendParentMsg ="getChildMsg" ></Login><h1>从子元素获得的值:{{msg}}</h1></div>
</template>  <script>
// 声明式
import Login from './components/Login.vue'
export default {name: "App",data() {return {msg:''};},methods: {getChildMsg:function(value){this.msg = value}},components:{Login}
};
</script>

Login.vue代码如下:

<template><div><input type="text" v-model="userName"><button @click="sendMsg">将数据提交给父组件</button></div>
</template><script>
export default {data(){return{userName:''}},methods:{sendMsg:function(){// 使用$emit(事件名称,发送的事件值)触发自定义事件 sendParentMsg()this.$emit("sendParentMsg",this.userName)}},
}
</script>

Vue3生命周期

beforeCreate()和created()

初始化数据之前和初始化数据之后,初始化页面时调用

beforeMount()和mounted()

挂载渲染之前和挂载渲染之后,初始化完成后开始渲染页面

beforeUpdate()和updated()

页面数据发生更改时调用

beforeUnmount()和unmounted()

页面数据不显示时不渲染,vue2调用的是 beforeDestroy()和destroyed()

合成API:Composition API

  • 可以在setup函数中使用Composition AP

  • 普通写法和合成API的写法执行顺序,合成API更加快速便捷,且有利于代码的维护

Composition API :单个值ref

导入ref
ref()是一个变量变成响应式的

import {ref} from 'vue'
<template><div><h1 @click="changeEvent">普通方式计数:{{count}}</h1><h1 @click="num+=10">使用合成API计数:{{num}}</h1></div>
</template><script>
import {ref} from 'vue'export default {name: "App",data() {return {count: 0};},setup(){const num = ref(0)return{num}},methods: {changeEvent() {this.count++},},};
</script>

Composition API :函数

<template><div><h1 @click="changeNum">使用合成API定义的函数计数:{{num}}</h1></div>
</template><script>
import {ref} from 'vue'export default {name: "App",data() {return {};},//合成APIsetup(){//实例化变量 numconst num = ref(0)function changeNum(){num.value += 10}//返回相关的变量和函数return{num,changeNum}},
};
</script>

Composition API :对象 reactive({})

  • reactive({})使得一个对象变成响应式的
  • …toRefs(对象名)是用于解构对象,调用对象属性时不需要带上对象名作为前缀
<template><div><!-- 合成API中对象的使用 --><h1>姓名:{{user.userName}}</h1><!-- 合成API中返回的是解构对象,调用时不用加对象名前缀 --><h1>年龄:{{age}}</h1><h1 @click="changeType">类型:{{type}}</h1></div>
</template><script>
import { reactive,toRefs} from "vue";
export default {name: "App",data() {return {};},setup() {// 定义对象const user = reactive({userName: "小米",age: 18,type: "小奶狗",});// 更改对象数据function changeType(){user.type = "超级帅!!!"}//...toRefs(user)是解构对象return { num, changeNum, user, ...toRefs(user),changeType};},
};
</script>

Composition API :监听数据变化

watchEffect

跟踪所使用到的数据的变化

导入

import { watchEffect} from "vue";
//只跟踪匿名函数里使用到的值typewatchEffect(()=>{console.log(user.type)console.log("user.type的值发生改变时触发")})

watch

跟踪指定属性
导入

import { watch} from "vue";
  • 监听单个属性
// 单个监听watch(num,(newNum,oldNum)=>{console.log(newNum)console.log(oldNum)console.log("num的值发生改变时触发")})
  • 监听多个属性
// 多个监听watch([num,user],(newNum,oldNum)=>{console.log(newNum)console.log(oldNum)console.log("值发生改变时触发")})

setup详解

使用setup接收父组件数据

需要依赖props接收数据,父组件先绑定数据,子组件通过props接收,在setup中可以通过props计算响应式内容

  • content属性包含了父组件中传过来的内容

子组件的代码:

<template><div><h1>userName:{{userName}}</h1><h1>age: {{age}}</h1><!-- 通过props生成一句话 --><h1>description: {{description}}</h1></div>
</template><script>
import {ref} from 'vue'
export default {setup(props,content){// 使用setup接收props的数据,通过props计算响应式的内容const description = ref(props.userName+"年龄是"+props.age)console.log(content)return{description}},// 接收来自父组件绑定的数据props:['userName','age']
}
</script>

父组件代码:

<template><div><User :userName = "userName" :age= "age" class="abc"></User></div>
</template><script>
import { reactive,toRefs} from "vue";
import User from './components/User.vue'
export default {name: "App",data() {return {};},setup() {// 定义对象const user = reactive({userName: "小米",age: 18,type: "小奶狗"})//...toRefs(user)是解构对象return {  user, ...toRefs(user)};},components:{User},
};
</script>

生命周期

  • onBeforeMount 挂载渲染之前
  • onMounted 挂载渲染之后
  • onBeforeUpdate 更新之前
  • onBeforeUnmount 更新之后
    先导入
import {onBeforeMount,onMounted,onBeforeUpdate,onBeforeUnmount} from 'vue'

再运用

  setup(){// 声明周期函数的应用onBeforeMount(()=>{console.log("onBeforeMount")})},

Vue3路由:vue-router

路由的基本使用

  • 路由:单页面应用根据路径的变化显示不同的内容
  • 在项目路径下安装路由
E:\vuejs\vue3Router01> npm install vue-router@next

HTML
App.vue代码:

<template><div><p><router-link to="/">Go to Home</router-link><router-link to="/about">Go to About</router-link></p><router-view></router-view></div>
</template>
<script>
export default {name: "App",
};
</script>

JS
index.js

import {createRouter,createWebHashHistory} from 'vue-router'const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }const routes = [{ path: '/', component: Home },{ path: '/about', component: About },
]const router = createRouter({history:createWebHashHistory(),routes,
})export default router

main.js

import { createApp } from 'vue'
import App from './App.vue'
import './index.css'import router from './router'const app = createApp(App)// 使用路由
app.use(router)app.mount('#app')

动态路由

单页面应用中,根据路径的id显示不一样的内容

index.js

import {createRouter,createWebHashHistory} from 'vue-router'
//导入组件
import News from '../components/News.vue'
import NotFound from '../components/NotFound.vue'
//将组件加进路由里
const routes = [{path:'/news/:id',component: News},{path:'/:path(.*)',component: NotFound}
]const router = createRouter({history:createWebHashHistory(),routes,
})export default router

news.vue

<template><div><h1>新闻页{{$route.params.id}}</h1></div>
</template>
<script>
export default {mounted(){console.log(this.$route)}
}
</script>

NotFound.vue

<template><div><h1>找不到页面</h1></div>
</template>


路由正则与重复参数

  • \d+: id必须是数字
  • +: id至少有一个
  • *: id可有可无可重复可多个
  • ? : id可有可无,不可重复,不可多个

index.js

mport News from '../components/News.vue'
import Article from '../components/Article.vue'
import Film from '../components/Film.vue'
import Song from '../components/Song.vue'
import Vidio from '../components/Vidio.vue'
import NotFound from '../components/NotFound.vue'const routes = [{path:'/news/:id',component: News},// \d+: id必须是数字{path:'/article/:id(\\d+)',component: Article},// + : id至少有一个{path:'/film/:id+',component: Film},// * : id可有可无可重复可多个{path:'/song/:id*',component: Song},// ? : id可有可无,不可重复,不可多个{path:'/vidio/:id?',component: Vidio},
]

嵌套路由

某些应用程序的 UI 由嵌套多级深的组件组成。在这种情况下,一个 URL 的参数(id)不同,对应嵌套组件的结构也不同,主结构相同,嵌套结构不同
index.js关键代码如下:

import User from '../components/User.vue'
import Hengban from '../components/Hengban.vue'
import Shuban from '../components/Shuban.vue'const routes = [{path:'/user/',component: User,children:[{path:'hengban',component:Hengban},{path:'shuban',component:Shuban}]
},
]

User.vue

<template><div><h1>user页面</h1><router-view></router-view></div>
</template>

Hengban.vue

<template><div><h1>这是横版页面</h1></div>
</template>

Shuban.vue

<template><div><h1>这是竖版页面</h1></div>
</template>

竖版运行视图

程序化导航:使用js跳转页面

导航到其他位置

除了<router-link to="url">用于创建用于声明性导航的锚标记之外,我们还可以使用路由器的实例方法以编程方式完成此操作。

  1. 参数可以是字符串路径
this.$router.push("/news/:id")
  1. 参数是具有path的对象
this.$router.push({path: '/news/:id'})
// 携带参数跳转
this.$router.push({path: '/news/123456'})
  1. 带参数的命名路由,让路由器构建路径
this.$router.push({name:'film',params:{id:123}})
  1. 带查询querry的路径
 this.$router.push({path:'/vidio',query:{search:'弯弯作死'}})

替换当前位置

 this.$router.replace({path: '/news/123456'})

替换当前位置

此方法采用单个整数作为参数,指示在历史堆栈中前进或后退的步数,类似于window.history.go(n)。

<button @click="$router.go(1)">前进</button>
<button @click="$router.go(-1)">后退</button>

命名路由与重定向和别名

命名路由

您可以拥有多个router-view并为每个router-view命名,一个router-view没有名字的将default作为它的名字。

App.vue关键代码

<router-view name="ShopTop"></router-view>
<router-view></router-view>
<router-view name="ShopFooter"></router-view>

index.js关键代码

import ShopMain from '../components/ShopMain.vue'
import ShopTop from '../components/ShopTop.vue'
import ShopFooter from '../components/ShopFooter.vue'{path: '/shop',components: {default:ShopMain,ShopTop:ShopTop,ShopFooter:ShopFooter}},

ShopMain.vue关键代码

<template><div><h1>ShopMain主要内容</h1></div>
</template>

ShopTop.vue关键代码

<template><div><h1>ShopTop头部组件</h1></div>
</template>

ShopFooter.vue关键代码

<template><div><h1>ShopFooter底部组件</h1></div>
</template>

重定向:redirect

  • 重定向也在routes配置中完成。从/a到重定向/b:
const routes = [{ path: '/home', redirect: '/' }]
  • 重定向还可以针对命名路由:
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
  • 重定向还可以使用一个函数进行动态重定向
    就是说输入/mall路由就会跳转到/shop页面
const routes = [{path:'/mall',redirect:(shop)=>{return {path:'/shop'}}},
]

别名:alias

/shop的别名/home意味着当用户访问时/store,URL 仍然存在/store,但它会像用户正在访问一样匹配/shop。通过通过数组取多个别名

{path: '/shop',alias: '/store',components: {default:ShopMain,ShopTop:ShopTop,ShopFooter:ShopFooter}},

路由模式

哈希模式

使用哈希模式URL会出现一个 # ,URL 的这部分永远不会发送到服务器,所以它不需要在服务器级别进行任何特殊处理

import { createRouter, createWebHashHistory } from 'vue-router'const router = createRouter({history: createWebHashHistory(),routes: [//...],
})

HTML5模式

使用HTML5模式,URL 将看起来“正常”,请求会发送到服务器。所以需要配置适当的服务器

import { createRouter, createWebHistory } from 'vue-router'const router = createRouter({history: createWebHistory(),routes: [//...],
})

导航守卫

Vue router 提供的导航守卫主要用于通过重定向或取消导航来保护导航。有多种方法可以连接到路由导航过程:全局、每个路由或组件内。

router.beforeEach

全局导航前守卫
index.js

router.beforeEach((to, from,next) => {// ...// explicitly return false to cancel the navigationconsole.log(to)console.log(from)next()
})

从store页面跳转到page页

router.beforeResolve

全局保护,当路由跳转完成之后触发

router.beforeResolve(async to => {if (to.meta.requiresCamera) {try {await askForCameraPermission()} catch (error) {if (error instanceof NotAllowedError) {// ... handle the error and then cancel the navigationreturn false} else {// unexpected error, cancel the navigation and pass the error to the global handlerthrow error}}}
})

beforeEnter

单路由保护,进入路由前触发

 {path: '/shop',alias: '/store',components: {default: ShopMain,ShopTop: ShopTop,ShopFooter: ShopFooter}},

从store页面跳转到page页

组件内防护

写在组件里面的

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
 // 组件内导航防护beforeRouteEnter() {console.log("路由进入组件");},beforeRouteUpdate() {console.log("路由更新");},beforeRouteLeave() {console.log("路由离开");},

状态管理

通过reactive响应式对象管理

通过reactive响应式对象,再通过依赖provide和inject注入子组件中
index.js

import { reactive} from 'vue'// 状态管理仓库
const store = {state : reactive({message:"你好"}),setMessage(value){this.state.message = value;}
}
export default store

父组件:App.vue

import store from './store/index.js'
export default {provide:{store}
}

子组件:HelloWord.vue

inject:['store']

Vuex状态管理

home.vue
调用$store

<template><div class="home"><h1>商品数量:{{ $store.state.count }}</h1><h2>商品价格:100</h2><h1>商品总价:{{ $store.getters.totalPrice }}</h1><button @click="changeEvent">添加数量</button><h1>段子</h1><p v-for="(item,i) in $store.state.dzList" :key="i">{{item.text}}</p></div>
</template><script>
// @ is an alias to /src
import HelloWorld from "@/components/HelloWorld.vue";export default {name: "Home",components: {HelloWorld,},methods: {changeEvent: function () {// 触发状态的方法// 触发无参数的方法// this.$store.commit("setCount");// 触有参数的方法this.$store.commit("setCountNum", 3);},},mounted:function(){this.$store.dispatch('getDz')}
};
</script>

index.js
使用store

import { createStore } from 'vuex'// 管理全局所用到的数据
export default createStore({// 设置全局数据state: {count:0,dzList:[]},/*** 含计算属性的方法*/getters:{totalPrice:function(state){return state.count*100}},/*** 同步的方法* 修改状态的方法*/mutations: {// 无参数setCount:function(state){state.count++;},// 有参数setCountNum:function(state,num){state.count+=num;},setDzList:function(state,arr){state.dzList = arr;}},/*** 异步的方法* 使用Ajax请求修改数据*/actions: {getDz:function(context){// 开放免费的APIlet api = "https://api.apiopen.top/getJoke?page=1&count=10&type=text";// 发出请求fetch(api).then((res) => res.json()).then((result) => {console.log(result)context.commit('setDzList',result.result)});}},modules: {}
})

map辅助函数

  • mapState
  • mapGetters
  • mapMutations
  • mapActions
    map映射可以使得数据调用更加方便,不用加上$store.state,可以直接使用变量名
    组件Home.vue
import {mapState, mapGetters,mapMutations,mapActions} from 'vuex'export default {name: "Home",components: {HelloWorld,},/*** 把状态映射到组件上* 直接调用数据*/computed:{//映射数据...mapState(['count']),...mapState({productCount:(state)=>state.count}),//映射计算属性...mapGetters(['totalPrice'])},methods: {changeEvent: function () {this.$store.commit("setCountNum", 3);},//映射改变状态的方法...mapMutations(['setCountNum']),...mapActions(['getDz'])},mounted:function(){this.$store.dispatch('getDz')}
};

vue3 实现前后端交互

通过fetch()

关键代码段

// 获取数据显示到页面setup() {// 开放免费的APIlet api = "https://api.apiopen.top/getJoke?page=1&count=10&type=text";// 发出请求fetch(api).then((res) => res.json()).then((result) => {store.setDzList(result.result);console.log(result.result);});return {store};

通过axios()

终端安装axios:npm install axios --save

import axios from 'axios'// 获取数据显示到页面setup() {// 开放免费的APIlet api = "https://api.apiopen.top/getJoke?page=1&count=10&type=text";// 发出请求axios.get(api).then((result)=>{console.log(result)store.setDzList(result.data.result)// store.setDzList(result);})return {store};},

vite 配置跨域请求

跨域配置文件vite.config.js

/*** 跨域服务器的配置文件*/module.exports = {proxy :{'/api':{target: 'https://pvp.qq.com/',changeOrigin:true, //是否允许跨域rewrite:  path => path.replace(/^\/api/,'')}}}

Mock.js 模拟获取数据

链接: 点击跳转到官网.
可以拦截 Ajax 请求,返回模拟的响应数据

index.js

import Mock from 'mockjs'
Mock.mock("/user/userinfo","get",(req,res)=>{console.log(req,res)return{username:"老陈",type:"帅!"}}
)

vue脚手架cli的使用

安装脚手架cli
npm install -g @vue/cli

查看版本
vue --version

创建项目
vue create vueproject01

选择版本

切换到项目路径
cd vueproject01

运行

npm run serve

模块化管理 vuex

在store中导入模块user,user1

import { createStore } from 'vuex'
import user from './user.js'
import user1 from './user1.js'// 管理全局所用到的数据
export default createStore({// 设置全局数据state: {...},getters:{...},mutations: {...},actions: {...},modules: {user,user1}
})

user模块,user.js代码如下:

/*** 用户模块*/const user = {state: () => ({username: "老陈",age: 30}),mutations: {setUsername:function(state){state.username = "小陈"},setAge:function(state){state.age = 40}},actions: {asyncSetAge:function(context){setTimeout(()=>{context.commit('setAge')},3000)}},getters: {description:function(state,getters,rootState){return state.username + '的年龄是' + state.age+'岁!'}}
}export default user

命名空间

作用:区分每个模块,以防每个模块的getters和actions肯定会出现同名的情况

const user = {//  命名空间namespaced: true,.....
export default user

路由中的渲染User.vue
要加上模块名

  <!-- 命名空间的写法 --><h1>用户名:{{ $store.state.user1.username }}</h1><h1>年龄:{{ $store.state.user1.age }}</h1><h1>描述:{{ $store.getters["user1/description"] }}</h1><button @click="changeAge1">修改年龄</button>

模块中辅助函数的写法

<template>
<!-- 命名空间:辅助函数的写法 --><h1>用户名:{{ user1.username }}</h1><h1>年龄:{{ user1.age }}</h1><h1>描述:{{ description }}</h1><button @click=" setAge">异步修改年龄</button></div>
</template><script>
import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
export default {computed: {...mapState(["user1"]),...mapGetters("user1", ["description"]),...mapMutations('user1',['setAge'])},methods: {...mapActions("user1", ["asyncSetAge"]),},
};
</script>

Vue3:基础学习笔记相关推荐

  1. guido正式发布python年份_Python 基础学习笔记.docx

    Python 基础学习笔记 基于<Python语言程序设计基础(第2版)> 第一部分 初识Python语言 第1章 程序设计基本方法 1.1 计算机的概念 计算机是根据指令操作数据的设备, ...

  2. ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步

    http://blog.jobbole.com/85008/ ASP.Net MVC开发基础学习笔记(5):区域.模板页与WebAPI初步 2015/03/17 · IT技术 · .Net, Asp. ...

  3. Python3 基础学习笔记 C09【文件和异常】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  4. Python3 基础学习笔记 C08 【类】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  5. Python3 基础学习笔记 C07【函数】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  6. Python3 基础学习笔记 C06【用户输入和 while 循环】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  7. Python3 基础学习笔记 C05【字典】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  8. Python3 基础学习笔记 C04【if 语句】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  9. Python3 基础学习笔记 C03【操作列表】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  10. Python3 基础学习笔记 C02【列表】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

最新文章

  1. 软件测试质量过程检测文档_如何编写实际上有效的质量检查文档
  2. 北科院分子互作实战专题培训班(10月底/11月底班)(生物医药与营养健康协同创新中心)...
  3. mybatis的快速入门
  4. python读取json配置文件_Python简单读取json文件功能示例
  5. ubuntu系统安装python hello_ubuntu 下python安装及hello world
  6. 您使用的是不受支持的命令行标记: --unsafely-treat-insecure-origin-as-se
  7. 同一个JDK,命令行运行,与JNI加载虚拟机,还是有差异
  8. y=asin(wx+φ)的对称中心_y=asin(wx+φ)怎么求
  9. python时间序列进行线性插值_精解Python实现线性插值法——一看就会
  10. IT学习网站,各大主流网站
  11. 这几天加班熬夜把所有Python库整理了一遍,非常全面!
  12. 网络技术安全开发安卓APP
  13. vs+html教学,VS Code怎么运行html文件
  14. React ,Redux 教程汇总
  15. 岗位述职报告PPT怎么做?
  16. android 通讯录 编程,以编程方式批量添加数千个Android联系人
  17. GTMBase64的详细用法
  18. 对比Ubuntu与Win10的资源占用
  19. 如何彻底禁用笔记本电脑的键盘或者禁用笔记本的触控屏,及禁用后如何恢复,解决笔记本电脑蓝屏信息显示:“systern thread exception no handled” 失败操作“etd.sys
  20. Vue-学习笔记-06 v-if详解

热门文章

  1. VS2019登陆时脚本错误
  2. 2007年春节联欢晚会相声《免费电话》李金斗、大兵、赵卫国
  3. AD学习笔记(二)原理图库以及原理图绘制
  4. 金山词霸不断的弹出窗口(金山词霸防欺诈提示),犹如病毒软件
  5. XML与XSD两兄弟
  6. STM32L476入坑-3-新建工程并点亮LED灯
  7. 惠普HP Color LaserJet Pro MFP M476 打印机驱动
  8. 《童梦奇缘-梦幻般的羁绊》第七章-流火
  9. android中adb是什么意思,adb是什么意思?安卓系统常用adb命令怎么用?
  10. ubuntu 19.10 建立拨号连接(PPPoE)