前端框架|Vue保姆级教程
文章目录
- 一、Vue
-
- 1.1 Vue介绍
- 1.2 Vue特点
- 1.3 Vue周边库
- 二、初始Vue
-
- 2.1 插值语法
- 2.2 指令语法
-
- 2.2.1 v:bind / 简写 : 指令 单向数据绑定
- 2.2.2 v-model 双向数据绑定
- 2.3 事件处理
- 2.4 事件修饰符
- 2.5 键盘事件
- 2.6 计算属性
- 2.7 监听属性
- 2.8 计算属性与监听属性之间的区别
- 2.9 条件渲染
- 2.10 条件渲染
- 2.11 收集表单数据的细节
- 2.12 内置指令
-
- 2.12.1 v-text
- 2.12.2 v-html
- 2.12.3 v-once
- 2.12.4 v-pre
- 2.13 Vue生命周期
-
- 2.13.1 什么是生命周期
- 2.13.2 声明周期总结
- 三、Vue组件化编程
-
- 3.1组件的理解
- 3.2 非单文件组件
- 3.3 组件的基本实用(以后基本不会使用)
- 3.4 VueComponent
- 3.5 模块化的三种暴露方式
- 四、安装vue-cli
-
- 4.1 步骤
- 4.2 文件结构
- 4.3 ref属性
- 4.4 props属性
- 4.5 mixin属性
- 4.6 插件
- 4.7 scoped样式
- 4.8 组件自定义事件
- 4.9 解绑自定义事件
- 4.10 全局事件总线(开发中用的较多)
- 4.11 Vue过度动画
-
- 4.11.1 继承第三方动画库
- 五、Axios
-
- 5.1 使用axios
- 5.2 Vue脚手架配置代理
- 5.3 插槽
- 六、Vuex
-
- 6.1概念
- 6.2 搭建Vuex环境
- 6.3 基本使用
- 6.5 getters
- 七、路由
-
- 7.1 基本使用
- 7.2 多级路由(覆盖路由)
- 7.3 路由的query参数
- 7.4 命名路由
- 7.5 路由的params参数(RestFul风格)
- 7.7 路由的props配置
- 7.8 编程式路由导航
- 7.9 缓存路由组件
- 7.10 两个新的生命周期钩子
- 7.11 路由守卫
-
- 7.11.1 全局加守卫
- 7.11.2 独享守卫
- 7.11.3 组件守卫
- 7.12 路由的两种工作模式
- 8、Element-UI组件库
提示:以下是本篇文章正文内容,下面案例可供参考
一、Vue 1.1 Vue介绍
- Vue官网
- 动态构建用户界面的渐进式 JavaScript 框架
- 作者: 尤雨溪
- 遵循 MVVM 模式
- 编码简洁, 体积小, 运行效率高, 适合移动/PC 端开发
- 它本身只关注 UI, 也可以引入其它第三方库开发项目
- vue-cli: vue 脚手架
- vue-resource
- axios
- vue-router: 路由
- vuex: 状态管理
- element-ui: 基于 vue 的 UI 组件库(PC 端)
- 功能: 用于解析标签体内容
- 语法: { {xxx}} ,xxxx 会作为 js 表达式解析
Document - 锐客网
="js/vue.js">{
{
name}}
>
// 创建一个vue实例对象
let x=new Vue({//对应的容器id,也可以是类选择器
el:"#root",
//存放的数据
data:{name:"zhangsan",
url:"www.baidu.com",
}
});
2.2 指令语法 2.2.1 v:bind / 简写 : 指令 单向数据绑定
- 功能: 解析标签属性、解析标签体内容、绑定事件
- 举例:v-bind:href = https://www.it610.com/article/‘xxxx’ ,xxxx 会作为 js 表达式被解析 xxx为数字时,不会被当做String类型解析
- 说明:Vue 中有有很多的指令,此处只是用 v-bind 举个例子
Document - 锐客网
="js/vue.js">
>
// 创建一个vue实例对象
let x=new Vue({//对应的容器id,也可以是类选择器
el:"#root",
//存放的数据
data:{name:"zhangsan",
url:"www.baidu.com",
}
});
2.2.2 v-model 双向数据绑定
- 语法:v-mode:value=https://www.it610.com/article/“xxx” 或简写为 v-model=“xxx”
- 特点:数据不仅能从 data 流向页面,还能从页面流向 data
- 备注:v-model:value可以简写为v-model,因为v-model默认收集的就是value值
- 注意:v-model只能应用在表单类元素(输入类元素 input,select 等)
2.3 事件处理 语法:v-on:xxx 或 @xxx 绑定事件,十中xxx是事件名 例: v-on:click 单击事件
Document - 锐客网
="js/vue.js">="cli" v-on:click="showInfo">点我
="showInfo($event,66)">点我
2.4 事件修饰符
- 加在事件处理的后面 以 . 开始 加
1. prevent:阻止默认事件(常用)
点我阻止默认事件
2. stop:阻止事件冒泡(常用)
3. once:事件只触发一次(常用)
2.5 键盘事件
- Vue中常用的按键别名 @keyup.xxx=“方法名”/@keydown.xxx=“方法名” xxx代表下面的按键别名
1. 回车=> enter
2. 删除=> delete(捕获“删除”和“退格”键)
3. 退出=> esc
4. 空格=> space
5. 换行=> tab(特殊,必须配合@keydown使用)
6. 上=> up
7. 下=> down
8. 左=> left
9. 右=>right
- 使用按键别名
Document - 锐客网
="js/vue.js">
键盘事件:
>
// 创建一个vue实例对象
let x=new Vue({//对应的容器id,也可以是类选择器
el:"#root",
//存放的数据
data:{name:"zhangsan",
url:"www.baidu.com",
},
methods: {keycode(e){//打印文本的值
console.log(e.target.value);
}},
});
2.6 计算属性
计算属性:
1. 定义:要用的属性不存在,要通过已有属性计算得来
2. 原理:底层借助了Object.defineproperty方法提供的getter和setter
3. get函数什么时候执行?
(1). 初次读取时会执行一次
(2). 当依赖的数据发生改变时会被再次调用。
4. 优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5. 备注:
(1). 计算属性最终会出现在vm上,直接读取使用即可。
(2). 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
Document - 锐客网
="js/vue.js">
firstName:
lastName:
全名:> {
{
fullName}}
>
new Vue({el:"#root",
data:{firstName:"张",
lastName:"三",
},
computed: {// 直接当做普通属性调用不加括号
// 任何data中数据变化立即重新计算
// 计算属性会缓存
fullName:{//get有什么用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
//get什么时候用? 1.初次读取fullName时候。 2.所依赖的数据发生变化时。
get(){return this.firstName+"-"+this.lastName;
}
set(value){console.log(属性被修改);
const arr=value.split["-"];
this.firstName=arr[0];
this.lastName=arr[1];
}
}
},
})
- 计算属性简写:只考虑展示数据,不考虑修改数据时,可以使用
firstName:
lastName:
全名:> {
{
fullName}}
>
new Vue({el:"#root",
data:{firstName:"张",
lastName:"三",
},
computed: {// 直接当做普通属性调用不加括号
// 任何data中数据变化立即重新计算
// 计算属性会缓存
// fullName:{////get有什么用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
////get什么时候用? 1.初次读取fullName时候。 2.所依赖的数据发生变化时。
//get(){//return this.firstName+"-"+this.lastName;
//},
//set(value){//console.log(属性被修改);
//const arr=value.split["-"];
//this.firstName=arr[0];
//this.lastName=arr[1];
//}
// },//上面fullName的简写 可以直接写要展示的方法即可
fullName(){return this.firstName+"-"+this.lastName;
}
},
})
2.7 监听属性
>
new Vue({el: "#root",
data: {firstName: "张",
lastName: "三",
},
watch: {//语法
/** 1.
*要监视的对象:{
*handler(newVal,oldVal){
*
*}
*}
*2.
*要监视的对象:(newVal,oldVal)->{
*业务
*}
**/
firstName: (newVal, oldVal) => {console.log(newVal, oldVal);
},
lastName: {immediate:true, //初始化时让handler调用一下
handler(newVal, oldVal) {console.log(newVal, oldVal);
}
},
//监测属性 简写
firstName(newVal, oldVal){console.log(newVal, oldVal);
}
},})
2.8 计算属性与监听属性之间的区别
- computed和watch的区别
1. computed能完成的功能,watch都可以完成。
2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
- 两个重要的小原则:
1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是 vm 或 组件实例对象
2. 所有不被Vue管理的函数(定时器回调函数,ajax的回调函数,Promise的回调函数),最好写成箭头函数,这样this的指向才是 vm 或 组件实例对象
2.9 条件渲染
超链接
超链接超链接
超链接
2.10 条件渲染
-
{
{
person.name}}--{
{
person.age}}-{
{
index}}--{
{
person.id}}
>
new Vue({el:"#root",
data:{persons:[
{
id:"001",name:"张三",age:16},
{
id:"002",name:"李四",age:17},
{
id:"003",name:"王五",age:18},
]
}
})
2.11 收集表单数据的细节
="text/javascript">
Vue.config.productionTip = falsenew Vue({el:'#root',
data:{userInfo:{account:'',
password:'',
age:18,
sex:'female',
hobby:[],
city:'beijing',
other:'',
agree:''
}
},
methods: {demo(){console.log(JSON.stringify(this.userInfo))
}
}
})
2.12 内置指令 2.12.1 v-text
- 向其所在的标签插入文本
v-text指令:
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{
{xx}}则不会。你好,{
{name}}
2.12.2 v-html
你好,{
{
name}}
2.12.3 v-once
初始化的n值是:{
{
n}}
当前的n值是:{
{
n}}
="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',
data:{n:1
}
})
2.12.4 v-pre
Vue其实很简单
当前的n值是:{
{
n}}
="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',
data:{n:1
}
})
2.13 Vue生命周期 2.13.1 什么是生命周期
生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm 或 组件实例对象。
- 演示
你好啊
欢迎学习Vue
="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',
data:{a:false,
opacity:1
},
methods: {},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){console.log('mounted',this)
setInterval(() => {this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
})//通过外部的定时器实现(不推荐)
/* setInterval(() => {
vm.opacity -= 0.01
if(vm.opacity <= 0) vm.opacity = 1
},16) */
- 借鉴声明周期图
文章图片
常用的生命周期钩子:
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生DOM事件依然有效。
3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
三、Vue组件化编程 3.1组件的理解
- 组件的定义:实现应用中局部功能代码和资源的集合
文章图片
- 一个文件中包含n个组件
Vue中使用组件的三大步骤:
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)一、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。二、如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component('组件名',组件)三、编写组件标签:
- 演示
>
>
//第一步:创建school组件
const student=Vue.extend({template:`{
{student}}
{
{major}}`,
// el:'#root', //组件定义时,一定不要写el配置项,因为最终所有的组件都要被一个vm管理,由vm决定服务于哪个容器。
data(){return {student:"安阳工学院",
major:"计算机",
}
},
})
//第二步:全局注册组件
Vue.component('student',student)
new Vue({el:"#root",
//第二步:注册组件(局部注册)
components:{student:student,
}
})
3.4 VueComponent
关于VueComponent:
1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。 2.我们只需要写或,Vue解析时会帮我们创建school组件的实例对象,
即Vue帮我们执行的:new VueComponent(options)。 3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!! 4.关于this指向:
(1).组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
(2).new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
3.5 模块化的三种暴露方式
- 模块化三种暴露方式
- 分别暴露
>
// 组件交换相关的代码(数据、方法等)
export const student=Vue.extend({data(){return {student:"安阳工学院",
major:"计算机",
}
},
})
- 同意暴露
>
// 组件交换相关的代码(数据、方法等)
const student=Vue.extend({data(){return {student:"安阳工学院",
major:"计算机",
}
},
})
export {
school}
- 默认暴露(用的较多)
>
// 组件交换相关的代码(数据、方法等)
export default {name:"和当前vue组件的文件名同步"
data(){return {student:"安阳工学院",
major:"计算机",
}
},
}
export default school
四、安装vue-cli
- 安装 vue-cli之前先安装node
- 使用cmd 管理员
1. 配置npm淘宝镜像 防止下载过慢
npm config set registry https://registry.npm.taobao.org
2.全局安装@Vue/cli
npm install -g @vue/cli
3. 创建项目
vue create 项目名
创建vue2项目要使用 npm
4. 启动项目
npm run serve
4.2 文件结构
文章图片
4.3 ref属性
1. 被用来给元素或子组件注册引用信息(id的替代者)
2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(VueComponent)
3. 使用方式
打标识:或
获取:this.$refs.xxx
4.4 props属性
- 当别人要用我们的组件,数据不一样时,我们就不能把当前组件的数据写死,我们需要让调用者给我们这个组件的标签 传入参数
- 传入参数
//动态传入参数
="张三" :age="16">
>
import Student from "./components/Student.vue";
export default {data() {return {msg: "欢迎学习Vue",
}
},
components: {Student,
},};
- 定义props 接收参数
姓名:{
{
name}}
年龄:{
{
age}}
>
export default {name:"Student",
data() {return {// name:"法外狂徒-张三",
// age:16,
}
},
//简单声明接收
props:["name","age"],
//接收的同时对数据进行类型的限制
props:{name:String,
age:Number,
},
//接收的同时对数据:进行类型限制+默认值指定+必要性的限制
props:{name:{type:String,//name的类型
required:true,//name是必须要传的
},
age:{type:Number,//age的类型
default:22,//age如果不传,默认值是22
}
}
}
- 备注:
props是只读的,Vue底层会检测你对props的修改,如果进行了修改,就会发出警告。若业务需要确实需要修改,那么请赋值props的内容到data中一份,然后去修改data中的数据。
4.5 mixin属性
- mixin(混入)
功能:可以把多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混合,例如:
export default {
data(){...},
methods:{...},
...
}
第二步使用混入,例如:
1. 全局混入:Vue.mixin(xxx)
2. 局部混入:mixins:[xxx]
4.6 插件
- 功能:用于增强Vue
- 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
export default{
install(Vue){
插件,
插件,
...
}
}
使用插件:
引入插件:
import plugins from "插件的js文件"
应用插件:
Vue.use(plugins)
4.7 scoped样式
- 作用:让样式在局部(每个组件中)生效,防止冲突
- 写法:
- 一种组件之间的通信方式,适用于 子组件===>父组件
- 写法1:
- 组件Student.vue
姓名:{
{
name}}
年龄:{
{
age}}
>
export default {name:"Student",
data() {return {name:"法外狂徒-张三",
age:16,
}
},
methods:{sendStudentName(){//触发Student组件实例对象身上的mk事件
this.$emit("mk",this.name);
}
}
}
>
- App.vue
//自定义组件 名称 mk 当触发了mk事件 调用 demo方法
-on:mk="demo">
>
import Student from "./components/Student.vue";
export default {data() {return {msg: "欢迎学习Vue",
}
},
methods:{demo(name){console.log("demo方法被调用了",name);
}
},
components: {Student,
},};
- 写法2:
- 组件Student.vue
姓名:{
{
name}}
年龄:{
{
age}}
>
export default {name:"Student",
data() {return {name:"法外狂徒-张三",
age:16,
}
},
methods:{sendStudentName(){//触发Student组件实例对象身上的mk事件
this.$emit("t1",this.name);
}
}
}
- App.vue
="t1">
>
import Student from "./components/Student.vue";
export default {data() {return {msg: "欢迎学习Vue",
}
},
methods:{demo(name){console.log("demo方法被调用了");
}
},
//当App.vue中的数据创建好后,会触发mounted方法执行
mounted() {//this.$refs.mk会拿到mk的这个组件实例对象
//给mk这个组件实例对象绑定 自定义事件t1,当t1这个自定义事件被触发调用 demo方法
this.$refs.mk.$on("t1",this.demo);
},
components: {Student,
},};
4.9 解绑自定义事件
- 组件Student.vue 解绑自定义事件
>
export default {name:"Student",
data() {return {name:"法外狂徒-张三",
age:16,
}
},
methods:{sendStudentName(){//触发Student组件实例对象身上的mk事件
this.$emit("t1",this.name);
this.$emit("t2",this.age);
},
unbind(){this.$off("t1");
//解绑一个自定义事件
this.$off(["t1","t2"]);
//解绑多个自定义事件
this.$off();
//解绑所有自定义事件
}
}
}
- App.vue
>
import Student from "./components/Student.vue";
export default {data() {return {msg: "欢迎学习Vue",
}
},
methods:{demo(name){console.log("demo方法被调用了");
},
t2(age){console.log(age);
}
},
//当App.vue中的数据创建好后,会触发mounted方法执行
mounted() {//this.$refs.mk会拿到mk的这个组件实例对象
//给mk这个组件实例对象绑定 自定义事件t1,当t1这个自定义事件被触发调用 demo方法
this.$refs.mk.$on("t1",this.demo);
this.$refs.mk.$on("t2",this.t2);
},
components: {Student,
},};
4.10 全局事件总线(开发中用的较多)
- 全局时间总线:任意组件之间的通信
- 安装全局事件总线 main.js
//引入Vue
import Vue from "vue"
import App from './App.vue'
//关闭生产提示
Vue.config.productionTip=false
new Vue({//将App组件放入到容器中
render:h=>h(App),
beforeCreate() {Vue.prototype.$bus=this;
//安装全局事件总线,this指的是当前应用的vm
},
}).$mount("#app")
- 使用全局事件总线:A想接受数据
export default {data() {return {msg: "欢迎学习Vue",
}
},
methods:{demo(name){console.log("demo方法被调用了");
},
t2(age){console.log(age);
},
t3(data){console.log("全局事件总线===>",data);
}
},
//当App.vue中的数据创建好后,会触发mounted方法执行
mounted() {//给$bus这个全局事件总线绑定 自定义事件hello,当hello这个自定义事件被触发调用 this.t3方法
this.$bus.$on("hello",this.t3);
},
components: {Student,
},};
- 使用全局事件总线:
export default {name:"Student",
data() {return {name:"法外狂徒-张三",
age:16,
}
},
methods:{sendStudentName(){//触发全局事件总线身上的hello事件,给hello的回调方法传参
this.$bus.$emit("hello",this.name);
},
beforeDestroy(){//最好用beforeDestory钩子中,用$off("事件名")去解绑当前组件所用到的事件
this.$bus.$off("hello");
}
}
}
4.11 Vue过度动画
你好啊
>
export default {name:"Test",
data() {return {isShow:true,
}
},
}
>
h1{background-color: orange;
}
/* Vue定义的动画起始类名 */
.v-enter-active{animation: ani 1s;
}
/* Vue定义的动画反转类名 */
.v-leave-active{animation: ani 1s reverse;
}
/* 定义一个动画 */
@keyframes ani {from{transform: translateX(-100%);
}
to{transform: translateX(0px);
}
}
4.11.1 继承第三方动画库
animate第三方动画库官网
- 使用
0. 下载animate.css
npm install animate.css --save
1. 引入animate.css文件
import 'animate.css'
2. 在Vue动画标签上的name属性写入动画库指定的名称
name="animate__animated animate__bounce"
3. 在Vue动画标签上写入进场动画类名和退场动画类名
enter-active-class="进场效果" leave-active-class="退场效果"
4. 效果去官方获取想要的写入类名即可
- 测试
你好啊
>
import 'animate.css'
export default {name:"Test",
data() {return {isShow:true,
}
},
}
>
h1{background-color: orange;
}
五、Axios 5.1 使用axios
- 下载axios
npm i axios
- 引用axios
import axios from 'axios'
5.2 Vue脚手架配置代理
- 解决跨域问题
- 方法一: 在vue.config.js中添加如下配置
//配置代理对象
devServer: {
proxy: 'http://localhost:后端端口号'
}
- 说明:
- 优点:配置简单,请求资源时直接发给前端(8080)即可
- 缺点:不能配置多个代理,不能灵活控制请求是否走代理
- 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器(有限匹配前端资源)
- 方法二
module.exports = { devServer: {proxy: {'/api1': {
// 匹配所有以 '/api1'开头的请求路径
target: 'http://localhost:5000',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {
'^/api1': ''}//把以api1开头的路径去掉发送给target路径
},
'/api2': {
// 匹配所有以 '/api2'开头的请求路径
target: 'http://localhost:5001',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {
'^/api2': ''}
}
}
}
}
/*
changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
changeOrigin默认值为true
*/
- 前台发送请求
export default {
methods: {
getStu(){
axios.get("http://localhost:8080/api1/students").then(
response=>{
console.log("请求成功了",response,response.data);
},error=>{
console.log("请求失败了",error,error.message);
}
)
}
},};
说明:
- 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
- 缺点:配置略微繁琐,请求资源时必须加前缀。
- 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件 。
- 分类:默认插槽、具名插槽、作用域插槽
- 默认插槽
父组件中:
>
html结构1
子组件中:
>插槽默认内容...
- 具名插槽
父组件中:
>
html结构1
html结构2
子组件中:
="center">插槽默认内容...
="footer">插槽默认内容...
- 作用域插槽
- 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(数据在Stu组件中,但使用数据遍历出来的解构由App主组件决定)
父组件中:
>
//scope中定义的变量名就是子组件中定义的games所有数据(名字不强制要求可以随意)
- {
{
g}}
>
{
{
g}}
子组件中:
:games="games">
>
export default {name:'Stu',
props:['title'],
//数据在子组件自身
data() {return {games:['红色警戒','穿越火线','劲舞团','超级玛丽']
}
},
}
六、Vuex
文章图片
6.1概念
- 在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
- 何时使用? 多个组件需要共享数据时
- 创建文件:
src/store/index.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)//准备actions对象——响应组件中用户的动作
const actions = {
}
//准备mutations对象——修改state中的数据
const mutations = {
}
//准备state对象——保存具体的数据
const state = {
}//创建并暴露store
export default new Vuex.Store({ actions,
mutations,
state
})
- 在
main.js
中创建vm时传入store
配置项
......
//引入store
import store from './store/index.js'
......//创建vm
new Vue({ el:'#app',
render: h => h(App),
store
})
6.3 基本使用
- 初始化数据、配置
actions
、配置mutations
,操作文件store.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)const actions = {//响应组件中加的动作
jia(context,value){// console.log('actions中的jia被调用了',miniStore,value)
context.commit('JIA',value)
},
}const mutations = {//执行加
JIA(state,value){// console.log('mutations中的JIA被调用了',state,value)
state.sum += value
}
}//初始化数据
const state = {sum:0
}//创建并暴露store
export default new Vuex.Store({ actions,
mutations,
state,
})
- 组件中读取vuex中的数据:
$store.state.sum
- 组件中修改vuex中的数据:
$store.dispatch('action中的方法名',数据)
或$store.commit('mutations中的方法名',数据)
- 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写
dispatch
,直接编写commit
- 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
- 在
store/index.js
中追加getters
配置
const getters = { bigSum(state){return state.sum * 10
}
}//创建并暴露store
export default new Vuex.Store({ ......
getters
})
七、路由
- 理解: 一个路由(route)就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。
- 前端路由:key是路径,value是组件。
当访问key路径时,指定的位置会展示指定的组件
注意点
- 路由组件通常存放在
pages
文件夹,一般组件通常存放在components
文件夹。 - 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
- 每个组件都有自己的
$route
属性,里面存储着自己的路由信息。 - 整个应用只有一个router,可以通过组件的
$router
属性获取到。
- 路由组件通常存放在
- 安装vue-router路由命令: npm i vue-router
- 应用插件:
Vue.use(引入路由的自定义名称)
- 编写route配置:在src下创建index.js配置路由
src/index.js
//该文件专门用于创建整个应用的路由器
//引入VueRouter
import VueRouter from 'vue-router'
//引入Luyou 组件
import About from '../components/About'
import Home from '../components/Home'//创建router实例对象,去管理一组一组的路由规则
export default new VueRouter({ routes:[
{path:'/about',
component:About
},
{path:'/home',
component:Home
}
]
})
- 实现切换(active-class可配置高亮样式)
About
- 指定展示位置
7.2 多级路由(覆盖路由)
- 在一个路由规则中再定义路由
- 配置路由规则,使用children配置项:
//创建一个路由器
export default new VueRouter({//路由
routes:[
{path:'/about',component:About,},
{path:'/home',component:Home,
//配置子级路由
children:[
{//此处不要加 /
path:"news",
component:News,
},
{path:"message",
component:Message,
}
]
},
]
})
- 跳转(要写完整路径):
News
7.3 路由的query参数
- 当我们利用router路由发送请求时,可以携带一些参数进行传递
- 传递参数
-
{
{
data.title}}
-
{
{
data.title}}
>
export default {name:"Message",
data() {return {DataList:[
{
id:"001",title:"message001"},
{
id:'002',title:"message002"},
{
id:'003',title:"message003"},
]
}
},
};
- 接收参数
- 消息编号:{
{
$route.query.id}}
- 消息详情:{
{
$route.query.title}}
$route.query.id
$route.query.title
7.4 命名路由
- 作用
可以简化路由的跳转。
- 如何使用?
2.1 给路由命名
//创建一个路由器
export default new VueRouter({//路由
routes:[
{path:'/about',component:About,},
{path:'/home',component:Home,
//配置子级路由
children:[
{//此处不要加 /
path:"news",
component:News,
},
{path:"message",
component:Message,
children:[
{name:"detail",//给当前路由命名
path:"detail",
component:Detail,
}
]
}
]
},
]
})
2.2 简化跳转:
跳转 跳转 跳转
7.5 路由的params参数(RestFul风格)
- 在
router/index.js
配置路由,声明接收params参数 使用:参数名
来当占位符
{ path:'/home',
component:Home,
children:[
{path:'news',
component:News
},
{component:Message,
children:[
{name:'xiangqing',
path:'detail/:id/:title', //使用占位符声明接收params参数
component:Detail
}
]
}
]
}
- 传递参数
跳转 跳转
特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!
7.7 路由的props配置
- 在
router/index.js中
配置 作用:让路由组件更方便的收到参数
{ name:'xiangqing',
path:'detail/:id',
component:Detail, //第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
// props:{a:900} //第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数(RestFul风格传参)通过props传给Detail组件
// props:true
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
props(route){return {id:route.query.id,
title:route.query.title
}
}
}
- 接收props
- 消息编号:{
{
$route.query.id}}
- 消息详情:{
{
$route.query.title}}
- 消息详情:{
{
id}}
- 消息详情:{
{
title}}
>
export default {name:"Detail",
props:['id','title'],
mounted(){console.log(this);
}
}
7.8 编程式路由导航
- 作用:不借助
实现路由跳转,让路由跳转更加灵活
//$router的两个API
this.$router.push({ name:'detail',
params:{id:xxx,
msg:xxx,
}
})
//会覆盖上一次点击的记录
this.$router.replace({ name:'detail',
params:{id:xxx,
msg:xxx,
}
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退(正数代表向前走几次路径,负数代表向后退几次路径)
7.9 缓存路由组件
- 作用:让不展示的路由组件保持挂载,不被销毁。
- 编写:
若include不写 默认router-view中所有呈现的组件都会保持挂载
7.10 两个新的生命周期钩子
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
- 两个路由名字:
activated
路由组件被激活时触发。deactivated
路由组件失活时触发。
- news001
- news002
- news003
>
export default {name: "News",
activated() {console.log("News组件被激活了");
},
deactivated(){console.log("News组件没有被激活");
}
};
7.11 路由守卫
- 作用:对路由进行权限控制
- 分类:
全局守卫、独享守卫、组件内守卫
//创建一个路由器
const router= new VueRouter({//路由
routes:[
{path:'/about',component:About,},
{path:'/home',component:Home,
//配置子级路由
children:[
{//此处不要加 /
path:"news",
component:News,
},
{path:"message",
component:Message,
children:[
{name:"detail",//给当前路由命名
//自定义属性必须放在meta中
meta:{
a:true},
path:"detail",
component:Detail,
}
]
}
]
},
]
})
//全局前置守卫:初始化时执行、每次路由切换前执行
router.beforeEach((to,from,next)=>{ // 参数1:to 当前路由要去哪儿
//参数2:from 当前路由从哪儿来
//参数3:放行
if(判断条件 或者 to.meta.a(自定义参数进行判断)){
//判断当前路由是否需要进行权限控制
next() //放行
}else{//不放行
}
})//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to,from)=>{ console.log('afterEach',to,from)
})
export default router
7.11.2 独享守卫
//创建一个路由器
const router= new VueRouter({//路由
routes:[
{path:'/about',component:About,},
{path:'/home',component:Home,
//配置子级路由
children:[
{//此处不要加 /
path:"news",
component:News,
},
{path:"message",
meta:{
a:true},
component:Message,
children:[
{name:"detail",//给当前路由命名
path:"detail",
component:Detail,
}
],
//独享路由守卫
beforeEnter(to,from,next){console.log('beforeEnter',to,from)
if(to.meta.a){
//判断当前路由是否需要进行权限控制
next()
}
}
}
]
},
]
})export default router
7.11.3 组件守卫
- news001
- news002
- news003
>
export default {name: "News",
activated() {console.log("News组件被激活了");
},
deactivated(){console.log("News组件没有被激活");
},
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {}
};
7.12 路由的两种工作模式
- 【前端框架|Vue保姆级教程】对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
- hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
- hash模式:
- 地址中永远带着#号,不美观 。
- 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
- 兼容性较好。
- history模式:
- 地址干净,美观 。
- 兼容性和hash模式相比略差。
- 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
# 总结 提示:这里对文章进行总结: 例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
推荐阅读
- android第三方框架(五)ButterKnife
- vue-cli|vue-cli 3.x vue.config.js 配置
- 2020-04-07vue中Axios的封装和API接口的管理
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- Jsr303做前端数据校验
- VueX--VUE核心插件
- 7、前端--jQuery简介、基本选择器、基本筛选器、属性选择器、表单选择器、筛选器方法、节点操作、绑定事件
- 前端代码|前端代码 返回顶部 backToTop
- vue组件中为何data必须是一个函数()
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了