共计 33964 个字符,预计需要花费 85 分钟才能阅读完成。
Vue 外围语法
面试题:Vue 框架的特点
- 组件【component】式开发,能够复用代码,进步开发效率
- 申明式编程
不必操作 DOM,操作数据,进步开发效率【数据发生变化,视图跟着变动,不必操作 DOM,只是关怀数据】
- 采纳虚构 DOM+ 优良 DIFF 算法,能够复用 DOM
总结:组件化、申明式编程、虚构 DOM+ 优良 DIFF 算法
获取 Vue 依赖包
官网下载:https://cn.vuejs.org/v2/guide…
npm:npm、yarn 下载
cdn:cdn 下载都能够
首次理解
Vue 首次理解:
一、Vue 框架次要关注于视图 (view) 的一个框架
二、Vue 渐进式 JavaScript 框架
总结: 渐进式,Vue 框架提供外围的语法,能够在外围语法根底之上欠缺我的项目性能、路由、集中式治理等等慢慢欠缺我的项目。
Vue 全家桶:vue+ 周边外围插件,统称为全家桶
渐进式:Vue 框架提供一些外围的语法【指令等等】
我的项目当中须要应用路由性能:Vue 框架没有这个性能 -vue-router 配置路由
我的项目中须要应用一些通用组件成果:轮播图、遮罩层,element-ui
我的项目当中想要集中式治理数据:vuex 等等
根本用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 第一步:引入 vue.js -->
<!-- vue 框架对外裸露了一个构造函数【类】Vue 构造函数 function Vue(){}-->
<script src="../js/vue.js"></script>
</head>
<body>
<!-- 第二部:筹备容器 -->
<div id="root">
<!-- 展现动态数据 , 要用双大花括号 -->
<!-- {{}}: 插值语法,胡子语法 -->
<!-- 留神:插值语法只能在文本区域书写,不能再标签属性中书写 -->
<h2> 您好,{{name}}</h2>
</div>
<script>
//Vue 对外裸露一个构造函数 Vue
// Vue 的实例个别叫做 VM
// new Vue 构造函数的时候须要传递一个【配置对象】const VM = new Vue({
el:"#root",//el 的属性值个别是字符串类型的 css 选择器,它的作用是 VM 与容器进行关联
data:{//data 的属性值个别是对象,它的作用是给实例对象 VM 增加一些属性
name:'浩哥'
}
});
console.log(VM);
/*
VM:Vue 类的实例,数据能够和容器进行关联
VM 实例属性的属性值发生变化,视图上的数据就跟着变动
数据变动跟着视图变动
留神:VM 身上的属性是【响应式数据】,数据发生变化,视图跟这变动!!!*/
</script>
</body>
</html>
胡子语法(插值语法)注意事项:
- 能够书写实例的属性
- 能够书写 JS 表达式
表达式:最终会产生一个数值,能够书写在胡子语法外面
eg:数学运算符:+ – * / %;
比拟运算符;
逻辑运算符
三元运算符
固定的某一个数值
函数调用,函数执行的后果也有返回值
切记:如下的语法不能在胡子语法中书写:
if、for、switch 等等,不是表达式
Vue 开发者工具的装置
Vue 开发者工具,是服侍开发者的,对我的项目调试有很大用途
能够判断一个我的项目是不是 Vue 我的项目
配置对象的其余写法
const VM = new Vue({
// 配置属性 data 的作用:给实例对象 VM 减少响应式数据
//data 第二种写法(函数的写法)
//data functions should return an object: 如果 data 配置项写法如果是函数, 必须要返回一个对象
//data 函数返回后果作为 VM 属性与属性值
data(){
return {
name:"明天是一个好日子, 吃了火锅",
age:18,
sex:'爷们',
hobby:'游戏'
}
},
//methods 配置项的作用:能够给实例对象 VM 减少办法, 留神:办法不能书写为箭头函数
methods:{handle(){}}
});
// 上面这行代码:也能够将 VM 与容器进行关联
//$mount 是 Vue.prototype 原型上的一个办法,Vue 类的实例能够调用, 作用是与 el 配置项性能一样的
// 就是把 VM 实例与容器进行关联
// 小总结:Vue 类的实例办法个别都是以 $ 结尾的
VM.$mount('#app');
指令【directive】
v-bind
作用:能够给标签绑定动静属性值【数据发生变化、标签的属性值也跟着变动】动静属性值与 VM 无关,VM 属性值发生变化,视图跟着变动!!!
简写 (1 个冒号):
总结:
胡子{{}}:给标签绑定动静文本
v-bind:给标签绑定动静属性值
例如:
<img v-bind:src="url"><br />
<input v-bind:type="leixing">
<p v-bind:id="name"></p>
<hr>
<h1>v-bind 简写形式 </h1>
<img :src="url"><br />
<input :type="leixing">
<p :id="name"></p>
// 初始化 Vue 实例, 进行关联
const VM = new Vue({
el: '#app',
data: {
url: "./images/1.jpg",
leixing: 'text',
name: 'box'
}
})
v-model(数据的双向绑定)
作用:能够让表单元素实现数据的双向绑定【页面 + 数据同步】,次要作用是 收集表单元素 的信息,
留神:非表单元素 p、div、a、img 等等不能应用 v -model
文本框:
<input type="text" v-model="msg">
<hr>
单选:
<input type="radio" value="nan" v-model="sex"/> 男
<input type="radio" value="nv" v-model="sex"/> 女
<hr>
复选: 在通过数据双向绑定收集数据的时候,复选框用数组收集数据
<input type="checkbox" value="eat" v-model="hobby"> 吃饭
<input type="checkbox" value="sleep" v-model="hobby"> 睡觉
<input type="checkbox" value="fire" v-model="hobby"> 打豆豆
<hr>
<!--
下拉菜单: 下拉菜单数据双向绑定的时候,给 select 进行绑定的
-->
<select v-model="city">
<option value="bj"> 北京 </option>
<option value="sh"> 上海 </option>
<option value="gz"> 广州 </option>
<option value="sz"> 深圳 </option>
</select>
const VM = new Vue({
el: '#app',
data() {
return {
msg:'我是祖国的老花骨朵',
sex:'nv',
hobby:['eat'],
city:'sz'
}
}
})
v-on
用法:v-on: 事件名字 =” 事件处理函数 ” v-on:click=”handle”
作用:给标签绑定事件
简写:@ @click=”handle”
<!-- 传递参数 -->
<button @click="getMessage(666)"> 点击我传递一个参数 </button>
<!--
事件对象的写法 $event, 切记 $ 必须要书写
event: 事件对象, 事件对象能够获取鼠标地位、键盘码、阻止默认事件、阻止事件流传
-->
<button @click="getMessage2($event,12306,' 喜爱张杰 ')"> 点击我传递多个参数 </button>
<!--
@click="getMessage3", 不传递参数,不写小括号,事件回调函数默认注入事件对象,第一个参数就是事件对象
@click="getMessage3($event)", 这样代表的传递参数事件对象,回调能力获取到事件对象
@click="getMessage3()" 这样书写代表传递参数,然而你没有传递参数,形参获取的第一个变量数值为 undefined
-->
<button @click="getMessage3">event 获取注意事项 </button>
v-if 的应用
//v-if: 是 Vue 框架给咱们提供一个指令, 它次要的作用是能够让元素进行显示或者暗藏
//v-if 指令,右侧须要个别是布尔值,真代表以后元素显示、假代表元素暗藏。//v-bind|v-model|v-on|v-if, 右侧属性值能够 VM 对象的属性 |JS 表达式
// 须要留神: 在应用 v -if|v-else-if|v-else 两头不要呈现其余的标签【货色】,否则生效!!!//v-if 是通过何种伎俩实现元素的显示与暗藏?
// 显示:每一次展现都是创立一个新的 DOM
// 暗藏:每一次都须要移出、干掉 DOM 进行暗藏。// 因为 v -if:间接操作 DOM 创立与销毁,频繁的操作 DOM,很耗性能的。
v-show 的应用
//v-show 通过什么实现的显示与暗藏?
//v-show 是通过款式 display 实现元素的显示(block)与暗藏(none)
总结:
v-if|v-show: 都能够实现元素的显示与暗藏。
v-if: 通过创立新的 DOM 节点 | 移除 DOM 节点实现 DOM 显示与暗藏【频繁的创立、销毁 DOM】比拟耗费性能的
v-show: 通过 CSS 款式管制元素的显示与暗藏【DOM 节点仅仅只是须要创立一次即可】
v-for 的应用
//v-for 指令,到底能遍历哪些数据?
//v-for 能够遍历以下数据: 数组、数字、字符串、对象
//v-for 遍历数据: 工作、我的项目当中个别只是应用数组!!!!
<!-- 列表的渲染
v-for 右侧的属性值不能瞎写、不能胡写、不能乱写。依照人家的语法来搞
v-for = "元素 in 数组"
stu: 是数组外面的每一个元素 stu 你能够当中一个变量,变量在应用的时候,须要用到插值语法
students: 须要遍历的数据【数组】index: 是数组外面元素的索引值
留神:in 与后面、前面切记保留住空格,如果没有空格把 in 当中 = 做一个整体了,就没有关键字 in,导致报错
v-for 渲染列表的时候, 也须要加上 key 属性,且 key 属性值应该是举世无双的
key: 属性值,是举世无双的,不能雷同。key:属性值能够用 index,尽可能别应用, 万一有逆序的操作会有问题的。尽可能应用的是元素的 id
-->
<h1> 遍历数组 </h1>
<ul>
<li v-for="(stu,index) in students" :key="stu.id">
{{stu.name}}----{{index}}
</li>
</ul>
<hr>
<h1> 遍历数字 </h1>
<!-- 遍历数字的时候,从数字 1 开始的 -->
<!-- 索引值肯定是从数字零开始的 -->
<p v-for="(num,index) in 6" :key="index">
{{num}}----{{index}}
</p>
<hr>
<h1> 遍历字符串 </h1>
<p v-for="(str,index) in' 明天是好日子 '":key="str">
{{str}}---{{index}}
</p>
<hr>
<h1> 遍历对象 </h1>
<!--
v: 对象的属性值
k: 对象的属性名称
-->
<p v-for="(v,k) in obj" :key="k">
{{v}}---{{k}}
</p>
修饰符的应用
prevent 修饰符的应用:
<!-- form 表单:action,action 属性的作用是,是把表单数据提交到哪里 -->
<!--
当初点击按钮: 点击完按钮, 网页会跳转到百度,form 标签 action 属性的作用,有默认行为
-->
<form action="http://www.baidu.com">
<!--
润饰:prevent-> 阻止默认事件
@click.xxxx -> 即为修饰符
-->
<button @click.prevent="showMessage"> 点击我弹出 1126 很帅 </button>
</form>
stop 修饰符的应用:
<div class="cur" @click="showMessage1">
<!--
stop: 修饰符,能够阻止事件的冒泡
-->
<button @click.stop="showMessage1"> 阻止事件流传 </button>
</div>
once 修饰符的应用:
<!--
修饰符:once, 润饰只会让事件触发一次!!!因为有的我的项目,须要让元素事件只会触发一次,利用修饰符 once
-->
<button @click.once="showMessage2">once 修饰符 </button>
留神: 修饰符能够进行链式语法, 谁先谁后无所谓,这种呈现状况比拟是少
这些语法都是反对的,只不过我的项目、工作当中根底没有这种写法!!!!@click.stop.prevent.once
@click.once.prevent.stop
@click.prevent.stop.once
键盘事件的修饰符
键盘事件的修饰符, 个别只是与表单元素一起应用。键盘相干的修饰符有很多:
enter-> 回车键
left-> 左键
right-> 右键
up-> 上键
down-> 下键
esc、a-z、数字的都能够、书写相应的键盘码数字都能够
<input type="text" v-model="game" @keyup.enter="handle">
Object.defineProperty 的补充
//Object.defineProperty() 办法会间接在一个 对象上定义一个新属性,或者批改一个对象的现有 属性
let obj1 = {age:19,sex:'男'};
// 能够通过 Object.definedProperty 办法,给对象 obj 增加新的属性
// 参数: 第一个参数 对象
// 参数: 第二个参数 对象新增 | 已有的属性的属性名字
// 参数:第三个参数 描述符 对象【描述符】// 第三个参数:配置项【描述符: 数据描述符 -> value、enumerable、writable、configurable】// Object.defineProperty(obj1,'name',{
// value:'曹操',//obj1 增加了一个新的属性, 且属性值为曹操
// enumerable:true,//enumerable 属性值设置为真,代表新增的属性能够进行遍历,默认是 false
// writable:true,// 代表新增的属性的属性值能够批改,默认初始值 false
// configurable:true,// 描述符,代表新增的属性能够删除,默认初始值 false
// });
// obj1.name = "貂蝉";
// delete obj1.name;
// console.log(obj1);
// 读取描述符:get||getter、set|setter,办法,是函数
Object.defineProperty(obj1,'name',{
//get: 在读取 name 的属性值的时候会触发
//get 办法执行返回后果作为属性的属性值
get(){console.log('在读取 name 属性值的时候 get 办法会触发');
return "我爱你 1126";
},
//set: 在设置 name 的属性的属性值的时候触发
set(val){
//set 办法执行, 零碎会注入一个参数,参数即为这个属性最新的属性值
console.log(6666,val);
}
});
// 设置 name 新的属性值
obj1.name = '鲁班七号';
面试高频题:apply、call、bind 区别?
只管 call、apply 和 bind 三个办法的作用都是扭转函数执行时 this 的指向,但它们在应用上还是有肯定的区别。
(1)call、apply 与 bind 的区别
call 和 apply 都是扭转函数的上下文 this 的指向后立刻执行该函数,而 bind 则是返回扭转上下文 this 后的一个函数。
(2)call 和 apply 两者的区别
call 和 apply 的第一个参数都是要扭转的上下文对象,call 从第二个参数开始以及前面的参数都是以参数列表的模式展示,而 apply 则是把除了要扭转的上下文对象外的其余参数放在一个数组作为它的第二个参数。
面试:响应式数据的原理剖析
Vue2 版本响应式数据实现的原理: 利用 Object.defineProperty 实现的
面试题:怎么晋升性能?
- 应用按需加载
- 尽可能应用 v -show
ref 属性(在 Vue 实例上是 $ref)
<!-- vue 框架提供 ref 技术, 能够让你获取实在 DOM 节点 -->
<!-- ref 属性值惟一:如果雷同取后者 -->
<h1 ref="tab"> 今天天气不错, 今天天气更好 </h1>
<h2 ref="tab1"> 今天天气不错, 今天天气更好 </h2>
<button @click="getMessage"> 点击我的时候, 弹出 h1 文本内容 </button>
当 v-for 用于元素或组件的时候,援用信息将是蕴含 DOM 节点或组件实例的数组。
计算属性
// 计算属性: 单词千万别写错, 配置项 K, 没有商量余地
computed: {
// 这种写法: 代表的是给 VM 增加一个新的属性, 且这和办法的返回值即为这个新增的属性的属性值
//computed 计算属性,新增的属性也是响应式的【底层也是利用 Object.defineProperty 实现】allName() {
//this, 即为 Vue 实例 VM
console.log('测试是否执行');
// 当新增的属性, 依赖的 响应式数据 发生变化的时候, 以后函数会再次执行, 计算出一个新的属性值提供应用
// 留神的事件事件是: 计算属性这里个别不书写异步语句
// 异步语句: 提早器、定时器、ajax 等等
// 上面写法是谬误的:return 返回值作为定时器回调函数的返回值
// setTimeout(() => {
// 并非是 allName 这个函数返回值
// return this.xing + '-' + this.ming;
// }, 1000);
return this.xing + '-' + this.ming;
}
}
//computed 计算属性, 它次要的作用是利用已有的属性与属性值, 创立出一个新的属性与属性值
// 计算属性还有另外一种写法:第一种写法 -> 函数写法
// 计算属性还有第二种写法:第二种写法 -> 对象
computed: {
// 计算出新的属性
allName: {
//get 办法, 不能瞎写、不能胡写、乱写
get() {
//this:this 即为以后 Vue 类的时候, 也就是 VM
return this.xing + '-' + this.ming;
},
//set: 当这个属性的属性值赋予新的数值的时候会触发
set(val) {
// 获取设置新的数值
let arr = val.split("-");
this.xing = arr[0];
this.ming = arr[1];
}
}
}
## 面试题:methods 与 computed 区别?
//methods 它次要的作用是给 VM 实例增加办法 ------- 办法
//computed:它是利用已有的属性与属性值创立出一个新的属性与属性值 ---- 属性
// 区别 1:methods 办法在应用的时候个别须要加上小括号,computed 计算出来的属性, 在应用的时候是不须要加小括号的
// 区别 2:计算属性算进去的数值有缓存机制, 计算出一个能够屡次应用
动静类名
<!-- 当初这种写法: 退学时候所学习,p 标签的类名属性值死的 -->
<p class="box box1"> 大江东去浪淘尽, 千古风流人物 </p>
<!-- 动静类名的写法, 动静类名也能够联合非动静类名一起应用,能够增加多个类名 -->
<h1> 动静类名 - 字符串写法 </h1>
<pre class="tab1" :class="selector">
煮豆持 作羹,漉菽认为汁。萁在釜下燃,豆在 釜中泣。本自同 根生,相煎何太急?</pre>
<h1> 动静类名对象写法 </h1>
<!--
动静类名能够右侧对象的写法:{K:V}
k: 就是未来要增加动静类名
V: 判断的条件,真,动静类名就有,如果是假,动静类名就没有
-->
<p :class="obj">
1.《长城》【唐】汪遵 秦筑长城比铁牢, 蕃戎不敢过临洮。尽管万里连云际, 争及尧阶三尺高。</p>
<h1> 动静类名之数组的写法 </h1>
<p :class="['cur','ka',selector,obj]">
北京(Beijing),简称“京”,古称燕京、北平,是中华人民共和国的首都、直辖市、国家核心城市、超大城市,国务院批复确定的中国政治核心、文化核心、国际交往核心、科技翻新核心,截至 2020 年,全市下辖 16 个区,总面积 16410.54 平方千米。依据第七次
</p>
data: {
selector: 'tab',
obj: {one: true, two:0}
}
动静行内款式
<!-- 容器 | 模板 -->
<div id="app">
<!-- 学习 CSS 时候,行内款式是上面写法,非动静写法 -->
<div style="width: 400px;height: 100px;background: red;"> 我是祖国的老骨朵 </div>
<h1> 行内款式的动静写法之 -- 对象写法 </h1>
<p v-bind:style="{width:'600px',height:'50px',color:'red'}">
Vue 框架行内款式写法
</p>
<h1> 行内款式动静写法之 - 数组写法 </h1>
<p :style="[obj,obj1]">
动静行内款式 style 反对数组写法
</p>
</div>
// 动静行内款式写法:反对对象写法、反对数组写法。次要记忆对象写法
watch 监听属性
// 监听属性,作用:watch 也是一个配置项, 它次要的作用是, 能够监听 VM 响应式属性的值 的变动。watch: {
// 监听属性的时候,当属性值发生变化的监听的函数会立刻执行一次
// 底下书写的监听 VM-> 属性名字【VM 身上没有这个响应式属性,监听不到的】// 函数写法
// keyword(){// console.log('我能监听到 keyword 关键字发生变化,只有关键字发生变化立刻执行一次');
// }
// 对象写法
keyword:{
// 如果是对象的写法,通过 handler 办法监听属性值的变动
// 函数的名字不能瞎写
handler(){console.log('VM 响应式属性值发生变化');
}
}
}
<script>
// 关联 VM
const VM = new Vue({
el: '#app',
data: {
a: {
b: {
count: 1,
msg:'我爱你'
}
}
}
,
watch: {// 监听 VM 属性,VM 身上有的响应式属性 a,[b,count 只是这个 a 属性的属性值]
// 为什么监听不到:因为对象 a 的属性值,是一个对象【内存地址素来没有变动过,也就是数之没有产生过变动】// 因而监听不到
// a(){// console.log('我爱你塞北的雪');
// }
//deep, 深度监听。尽管 a 的属性值对象没有发生变化,只有 a 的属性值发生变化就能检测到数据变动
a: {
// immediate:true,// 如果加上 immediate 属性,不论你属性值有没有发生变化,上来立刻执行一次监听。deep:true,// 深度监听, 只能在对象写法当中呈现
handler() {console.log('监听 count 变动');
// 监听属性函数外面能够书写异步语句
setTimeout(()=>{this.a.b.msg = '我是祖国的花骨朵'},2000);
}
}
}
});
//watch 监听, 监听的是 VM 身上响应式属性的属性值的变动 ->VM 身上的属性
</script>
生命周期
4->2->2
beforeCreate:VM 未实现齐全的初始化【不能获取 VM 的属性、办法】
created:VM 齐全初始化结束了【能够获取属性、办法】
beforeMount:VM 挂载之前
mounted:VM 挂载结束*[构造曾经残缺,能够获取 DOM 节点]beforeUpdate:VM 响应式属性发生变化之前
updated:VM 响应式属性值发生变化当前beforeDestroy:VM 销毁之前
destroyed:VM 销毁*
// 生命周期函数: 全副的生命周期函数中最先执行的 beforeCreate 钩子函数
//VM 残缺的初始化未结束
beforeCreate() {// 这个钩子 this->VM(初始化配置还未结束), 在这里获取不到 VM 属性 | 办法
console.log('初始化阶段:beforeCreate', 'VM 未实现初始化');
},
//VM 初始化结束了
created() {
//VM 初始化结束, 能够获取属性、办法等等能够获取到了
console.log('初始化阶段:created', 'VM 初始化结束', this.count);
},
//VM 挂载之前会执行一次
beforeMount() {
//this->VM
// 以后钩子能够获取 VM 属性、办法,获取不到实在 DOM 节点.
console.log('初始化阶段:beforeMount', 'VM 挂载之前执行一次', this.count);
}
,
//VM 挂载结束了 *****
//mounted 是比拟重要的一个钩子函数, 咱们当前比方发申请 axios.get|axios.post|axios({})都在这里书写
mounted() {console.log('初始化阶段:mounted', 'VM 挂载结束', this.$refs.cur);
}
,
// 更新阶段: 当 VM 的响应式的数据发生变化的时候会触发一次
beforeUpdate() {console.log('更新阶段:beforeUpdate',this.count);
}
,
// 更新阶段: 当 VM 的响应式数据发生变化之后触发一次
updated(){console.log('更新阶段:updated',this.count);
}
,
//VM 销毁之前
beforeDestroy(){
//this->VM
console.log('销毁阶段 beforeDestroy')
}
,
//VM 销毁结束: 解决后事,比方后面开启定时器、销毁时候清革除定时器!!!destroyed(){console.log('销毁阶段 destroyed');
}
});
//Vue 生命周期函数
// 初始化阶段:beforeCreate、created、beforeMount、mounted---> 会执行一次
// 更新阶段:beforeUpdate、updated-> 当 VM 的响应式的数据发生变化的时候, 会执行
// 销毁阶段: beforeDestroy、destroyed!!!!!//VM 销毁并不是说,视图看不见了,VM 还是能够拜访到,然而它 '不工作了'!!!!
响应式数据数组和对象的注意事项
VM 身上的属性 -> 对象的写法【都是响应式数据】
-> 数组的写法, 数组外面的元素可能是响应式、不是响应式的
如果数组外面的元素不是响应式,Vue 框架就做不到数据发生变化,视图跟着变动。
一种: 数组变更
unshift、shift、push、pop、splice、reverse、sort
二种: 数组的替换
利用新的数组替换原始数组:map、filter、slice 等等办法都能够应用,因为这些办法都会返回一个新的数组
const VM = new Vue({
el:'#app',
data:{
name:"曹操",
age:18,
sex:'男',
hobby:['吃饭','睡觉','打豆豆'],
arr:["我爱你",123,{name:'豪哥'},true]
},
methods: {
// 更新性别
updateSex(){this.sex = '女';},
// 更新喜好
updateHobby(){
// 将睡觉变为游戏
// 这种写法是谬误的:hobby 是响应式属性,然而 hobby 右侧数组外面元素 吃饭、睡觉、打豆豆并非是响应式
//this.hobby[1] = '游戏';
// 因而数据变动了, 视图不会更新
// 数组检测伎俩 ---- 变更办法(7 个葫芦娃)
//shift、unshift、push、pop、splice、sort、reverse-> 对于起始数组都是有影响的
//this.hobby.reverse();
//this.hobby.unshift('喝酒');
//this.hobby.splice(1,1,"喝酒");
// 替换: 利用的新的数据替换原始的数组【Vue 框架也能检测到数据变动达到响应式】//this.hobby = ['吃饭','喝酒','打豆豆'];
// 数组 map、filter、slice 都会返回一个新的数组
this.hobby = this.hobby.map(item=>item=='睡觉'?'游戏':item);
},
handle1(){
//arr, 是一个响应式属性,数据变动视图跟这边
// 数组外面的元素 我爱你、123、布尔值 true,并非是响应式的数据,尽管批改数据,然而视图不跟着更新
// 这三者只能用数字组的变更(七个)、替换伎俩
// this.arr[0] = '我恨你',这种形式不会更新视图
// 通过控制台查看数组外面元素{name:'豪哥'}, 这玩意是响应式的。数据变动视图跟着变动
this.arr[2].name = '1126';
}
}
});
// 真的很重要:你在 data 当中定义对象都是响应式的。数组外面元素有可能是响应式【对象】、有可能不是响应式的【数字、字符串、布尔值:数组套路变更、替换】// 响应式数据:VM 身上的属性值发生变化,视图跟着变动。
单文件组件和非单文件组件
单文件组件: 一个文件即为一个组件,这个文件的尾缀.vue 文件
非单文件组件: 一个文件外面能够定义多个组件, 这个文件能够是.html 文件
组件的根本应用
// 组件:component
// 组件: 复用的【代码 + 资源(图片、款式、视频)】汇合在一起即为组件!//Vue 框架中从书写角度登程:分为两大类组件
// 单文件组件: 一个文件即为一个组件, 这个文件的尾缀务必是.vue
// 非单文件组件: 一个文件外面,能够定义多个组件,这个文件尾缀.html
//el 配置项: 只有 new Vue 构造函数初始化 VM 实例才能够应用,el 配置项只能呈现一次!!!// 组件不须要书写 el 配置项!!!!// 组件的 Data 的配置项 b 函数写法
<script>
//Vue 组件应用分为三步骤:
// 第一步: 定义
// 第二步: 注册
// 第三步: 应用
// 定义一个组件: 利用的是 Vue.extend 办法去定义组件
//extend 办法外面也须要传递配置对象,extend 配置对象与 Vue 配置对象简直截然不同!!!// 组件: 作为 Count 子组件
let Hello = Vue.extend({
template:"<h1> 我是 Hello 组件 </h1>",
mounted(){},
watch:{ },
computed:{}})
let Count = Vue.extend({components:{Hello},
// 组件的本身的数据
data() {return { count: 1};
},
// 组件的构造: 模板字符串才能够换行,双引号字符串不能换行
template: `
<div class="box">
<Hello></Hello>
<button @click="minus">-</button>
<span>{{count}}</span>
<button @click="add">+</button>
</div>
`
,
methods: {add() {this.count++;},
minus() {this.count--;}
}
});
let Big = Vue.extend({data() {return { f: 16}
},
template: `
<div class="box1">
<p :style="{fontSize:f+'px'}" @click="f++"> 路是脚踏进去的,历史是人写进去的 </p>
</div>
`
})
// 关联 VM
const VM = new Vue({
el: '#app',
data: { },
//VM 要注册本人想要应用的组件
components: {
// 注册组件的时候,在应用组件的时候用的 K 的名字,并不是 V
Count,
Big
}
});
// 总结: 第一, 组件的应用分为三步。// 第一步: 定义,须要通过 Vue.extend 办法进行定义。[extend 外面配置项与 Vue 配置项简直截然不同]
// 不能书写 el、组件的响应式数据务必比是函数写法
// 第二步: 注册。某一个中央须要组件,进行注册。在 components 配置项进行注册
// 第三步: 应用。【是以自定义标签的模式应用,首字母个别大写】</script>
版本阐明
Vue 依赖包: 尤雨溪团队,给开发人员提供很多版本的依赖包【残缺版本、压缩版本、运行时版本】
全局组件
全局组件的应用: 只须要定义一次,能够在任意组件中间接应用。就不必每一次都在注册了。
全局组件个别在这种状况下才会应用: 我的项目当中很多中央(组件),大家频繁应用某一个性能,你就能够把这个性能封装为全局组件,定义一次,能够在任意中央间接应用【不须要引入、不须要注册】间接应用。
// 定义一个组件
const Carousel = Vue.extend({data(){return {info:'我是轮播图组件, 而且我还是全局组件'};
},
// 构造编辑器
template:`
<h1>{{info}}</h1>
`
});
Vue.component("Erha",Carousel);
// 定义为全局组件 : 定义一次, 能够在任意中央间接应用,不须要注册。// 第一个参数:全局组件的名字(字符串) 第二个参数: 组件(不能书写为字符串)
// 全局组件个别在这种状况下才会应用: 我的项目当中很多中央(组件),大家频繁应用某一个性能,// 你就能够把这个性能封装为全局组件,定义一次,能够在任意中央间接应用【不须要引入、不须要注册】间接应用。
VM 与组件的关系
Vue 框架中组件, 本质是 Vue.extend 函数返回的构造函数 VueComponent
组件:即为构造函数 VueComponent,Vue.extend 函数返回的后果【构造函数】
组件外面 this 并非是 VM(Vue 类的实例), 组件实例是 VueComponent 类的实例,只不过 VueComponent 构造函数不是咱们本人调用的,
组件实例身上属性与 Vue 类的实例 VM 很类似。组件外面 this 是 VueComponent 类的实例,(简称 VC);
组件实例能够借用 Vue.prototype 的办法,震惊三观!!!
VC[组件的实例]原型的原型指向的 Vue.prototype
VC.__proto__.__proto__===Vue.prototype
创立组件的简写形式
<script>
// 创立组件: 定义、注册、应用
// 上面的写法是 Vue.extend 简写形式,间接书写配置项即可。let App = {
// 组件 name 配置项, 对于组件的应用没有任何影响, 只不过 name 配置项,会影响到开发者工具外面审查组件的显示名字而已。name:'Erha',
data(){return {name:'豪哥你真帅, 臭不要脸'};
},
template:`
<div>
<h1 @click="handler">{{name}}</h1>
</div>
`,
methods: {handler(){
this.name = '豪哥爱你们 1126';
console.log(this);
}
}
}
// 关联 VM
const VM = new Vue({
el:'#app',
template:`
<App></App>
`,
components:{
// 注册组件的时候 K,决定了组件在应用的时候,这个标签名字
// 开发者工具中审查组件的时候,也是显示 K
App:App
}
})
</script>
Vue 脚手架
小提示:
ES5 与 ES6 模块的引入与裸露肯定要把握。
简介
脚手架 ->vue-cli
vue 框架中也存在脚手架 ’ 工具 ’, 能够辅助你疾速开发我的项目。应用脚手架工具之前, 电脑当中须要装置脚手架工具。
1.1 装置脚手架工具。利用 npm|yarn 工具装置脚手架性能。
脚手架工具官网地址:https://cli.vuejs.org/zh/guide/
npm install -g @vue/cli 这是装置 vue 脚手架指令
舒适提醒: 关上 CMD 命令行 输出 vue -V 打印出 5.0.4 版本代表装置脚手架工具胜利。
Vue.js: 框架版本 1 2 3
vue/cli: 工具[脚手架版本] 1 2 3 4 5
脚手架工具的应用.
vue/cli 脚手架工具: 它次要的作用是能够疾速创立 Vue 根本构造。怎么疾速创立 Vue 我的项目构造。
第一步: 找到一个文件夹(未来搁置我的项目中央), 关上 CMD 命令,输出【vue create 我的项目的名字】
第二步: 抉择提醒第二项 Default(vue2 babel,eslint), 这代表的是装置 Vue 框架 2.xxx 版本
(babel: 将 ES6->ES5,eslint: 语法测验器)
第三步: 怎么运行, 找到 package.json 文件,查看 script 这个 K
“scripts”: {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
npm run serve : 以后我的项目在本地服务器 8080 运行起来
npm run build: 我的项目完事了, 我的项目打包给后盾用这个。->dist
npm run lint:也是本地运行, 把 webpack 一些暗藏的配置项裸露进去。
我的项目运行的注意事项: 在我的项目根目录下输出 npm run serve
意识意识脚手架目录。
node_modules 文件夹: 搁置的是我的项目依赖的文件夹
public 文件夹:public 个别搁置动态资源【HTML|CSS| 图片等等】, 这个文件夹外面的动态资源,在打包的时候,
会一成不变的打包到 dist 文件夹外面.
舒适提醒:<%= BASE_URL %>,webpack 曾经给你配置好了,就是 public 文件夹
src 文件夹:src 文件夹程序员文件夹,当前书写代码都是在 src 文件夹外面搞。
assets 文件夹: 也是搁置动态资源的文件夹,assets 文件夹外面个别搁置的是组件共用的动态资源,assets 文件夹外面的动态资源, 在打包的时候, 会当中 webpack 一个模块,打包到 JS 文件夹外面。
main.js: 入口文件, 是你整个我的项目最先执行的中央, 个别初始化一个 VM。
App.vue: 整个我的项目根组件
components 文件夹: 搁置组件的中央
.gitignore 文件 :git 疏忽文件 配置文件很少触碰
babel.config.js: 以后这个文件 babel’ 翻译官 ’ 配置文件。很少触碰
jsconfig.json 文件: 它也是一个配置文件。给 src 文件夹起一个别名。
在你的我的项目当中能够应用 @符号,代表的是 src 文件夹。
目前而言 @个别在 JS 区域书写(其实也能够在 css 区域书写)
// @代表是 src 文件夹, 相当于给 src 起了一个别名。// 当前在开发大型项目的时候常常用到找 src 文件夹外面文件关系的。import MyComponent1 from '@/components/MyComponent1'
import MyComponent2 from '@/components/MyComponent2'
package.json 文件: 记录我的项目名字、我的项目版本号、我的项目如何运行、我的项目依赖有哪些。
package-lock.json 记录依赖下载地址,再次下载依赖的时候,间接从电脑缓存中获取依赖。
readme.md: 这玩意不是笔记, 我的项目说明书。比方如何装置依赖、比方运行。
vue.config.js 文件: 能够当做 webpack.config.js
举例子: 通过 webpack 代理解决代理跨域问题,就在这个文件外面操作。
启动我的项目后,主动关上浏览器
第一步:
在 package.json 中增加 –open
"scripts": {
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
}
第二部:
在 vue.config.js 文件中增加配置项
{
transpileDependencies: true,
// 敞开 eslint 校验工具
lintOnSave:false,
// 浏览器弹出 URL 设置
devServer:{
host:'127.0.0.1',
port:'8080'
}
}
面试题:scoped
scoped:英文含意范畴
scoped 不增加: 代表以后组件外面的款式是全局款式(全副的组件都会受到影响)
scoped 增加上: 代表以后组件内的款式, 部分款式,只对于以后组件失效。
咱们当前开发我的项目的时候,大多数状况下都会加上 scoped,因为组件款式互相不影响。
目前脚手架默认反对 css 款式, 默认不反对 less|scss 写法【未来能够】
面试:public 与 assets 文件夹区别?
public 文件夹: 个别搁置一些动态资源【html、css、图片等等】, 放在 public 文件夹中的动态资源,webpack 在打包的时候, 会把这些动态资源一成不变打包到 dist 文件夹中。
src 文件夹下的 assets 文件夹: 它也是搁置动态资源的文件夹, 个别搁置组件共用的动态资源(比方 1000 个组件都应用同一个图片),assets 文件夹外面的动态资源,webpack 在打包的时候,会把动态资源当作一个模块打包到 js 文件夹外面。
vue-cli 脚手架其余配置项。
vue-cli 脚手架的确不便咱们开发、学习 Vue。然而有一些细节操作须要整整。
我的项目执行 npm run serve 命令后,浏览器是不是本人主动关上。
第一步: 找到 package.json 文件, 在 serve 前面加上 –open(代表浏览器主动关上)
“scripts”: {
"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
发现:浏览器的确主动关上了 http://0.0.0.0:8080/ 在这个 URL 上拜访不到我的项目。
第二步:
第一种解决方案: 批改脚手架源码.
node_modules/@vue/cli-service/lib/commands/serve.js—-> 源码文件
serve.js 源码批改
const defaults = {
host: ‘127.0.0.1’,
port: 8080,
https: false
}
第二种解决方案:
在 vue.config.js 文件中新增配置项
devServer: {
host: ‘127.0.0.1’,
port: 8080,
https: false,
}
把 eslint 校验工具敞开
举例子: 申明一个变量,然而没有应用, 我的项目会在顶上弹出一个遮罩层,让你无奈观看我的项目。
第一步: 找到 vue.config.js 文件,进行配置敞开 eslint 校验工具.
新增配置项,即可敞开 eslint 工具。
lintOnSave:false
vscode 插件的装置!!!
Vetur 插件:语法提醒、组件格式化、组件观看起来难看
vue-beautify: 让你的组件难看
vue-helper:element-ui 组件提醒的插件
插件: 疾速生成组件模板 vue
配置项: 都是一 V 结尾的
父子组件通信 props
父组件给子组件传递数据,能够利用 props 实现【自定义属性】,
子组件的接管到的 props 是只读的(只能用不能批改),数据来自于谁,用谁的办法进行批改。
子组件接管父组件传递过去的数据
第一种写法: 数组写法,数组外面书写的是自定义属性的名字
props:["car",'money','changeAppMoney']
第二种写法: 对象写法[算两种写法,然而都是对象写法]
// 对象的这种写法能够束缚 props 数值类型
props:{
// 承受的是 props 名字
msg:{
// 束缚这个属性的属性值
// 字符串:String 数字:Number 数组 Array 对象 Object 函数 Function
type:String,
default:"abc",// 设置初始值,然而父组件传递了, 初始值生效
}
}
// 简写
props:{
todos:Array,
a:String
}
props: 父子组件通信, 次要做的事件,父组件给子组件传递数据!!!!!
第一种: 并非函数状况
父组件给子组件的数据:数组、字符串、对象等等
第二种:函数
父组件给子组件传递函数: 父组件给子组件传递数据【函数:props】,本质不就是儿子给爹传递数据吗?
面试题:h5 新增了哪些个性?
在 HTML5【超文本标记语言第五次重大批改当中】
结构层:新增的语义化标签:main、header、footer 等等,视频 (video)、音频(audio) 等等
款式层:2D、3D 动画、flex 等等
行为层:浏览器存储性能(本地存储,会话存储),canvas 画布
浏览器的存储分为两大类:
本地存储:利用 localStorage 对象实现浏览器浏览器长久化存储 j 数据
会话存储:利用 sessionStorage 对象,会话存储应用的语法,与本地存储简直截然不同
浏览器本地存储
本地存储性能: 浏览器存储性能之一,本地存储,能够实现浏览器【长久化】存储数据。
浏览器存储性能个别存储字符串类型的数据!!!!
思考问题: 开发当中,JSON、数组怎么存储?
答:如果你想存储援用类型的数据:套路先把它变为字符串 -> 存储 JSON.stringify
读取的时候再把字符串转换援用类型 -> 读取 JSON.parse
面试:本地存储有哪些个性:
第一: 本地存储个别存储字符串
第二: 援用类型数据须要转换为字符串进行操作
第三: 浏览器本地存储性能,存储数据是有下限 5M 左右!!!!
第四: 本地存储长久化存储数据, 电脑关机、网页敞开,只有步本人手动删除,存储一辈子!!
会话存储特点:
1 会话存储存储数据并非长久化, 电脑关机、网页敞开,会话存储数据隐没!!!
2:会话存储,存储数据也是有下限的大概 5M
代码如下:
// 浏览器存储性能之一:本地存储, 是通过 localStorage 对象实现的!!!本地存储数据个别存储的是字符串。// 本地存储存储数据实现 第一个参数:相当于 K 第二个参数:相当于 V
// 长久化存储数据: 电脑关机重启数据也在或者把网页敞开也在!!!// 存储性能: 如果 K 一样,后者笼罩前者
//localStorage.setItem("todo",'我是本地存储性能, 个别存储字符串');
//localStorage.setItem("todo1",'我是小明, 我很帅');
// 读取: 读取的时候,通过 K,获取相应存储的 V
// 读取浏览器存储数据的时候,如果没有存储过的 K,获取数据为 null
// let result = localStorage.getItem("todo");
// let result1 = localStorage.getItem('todo1');
// console.log(result);
// console.log(result1);
// 删除本地存储的数据
// 删除本地存储数据:通过 K 移出相应的 V
// localStorage.removeItem('todo');
// 开发当中咱们个别存储:JSON、数组。// 先把援用类型的数据,转换为字符串进行存储
let todo = ['我爱你','塞北的雪','鲁班七号挺猛'];
let obj = {a:1,b:2};
// 本地存储: 存储援用类型的数据,先把他们转换为字符串
localStorage.setItem('data',JSON.stringify(todo));
localStorage.setItem('data1',JSON.stringify(obj));
// 读取:JSON.parse, 能够把字符串转换为援用类型的数据
let result = JSON.parse(localStorage.getItem('data'));
let result1 = JSON.parse(localStorage.getItem('data1'))
console.log(result,result1);
自定义指令
Vue 官网提供的指令:
v-bind
v-on
v-model
等等
Vue 框架反对程序员本人去定义一个指令:举例;自定义一个 upper 指令
<!-- 在应用的时候切记:别忘记后面 v - -->
<h1 v-upper="msg"></h1>
部分指令
// 新增一个配置项 directives
directives: {
// 书写的时候,不须要书写 v -. 应用的时候:v-upper
// 当程序员应用 v -upper 指令的时候会执行一次!!!// upper(element,options){
// //element 形参: 以后绑定指令的实在的 DOM 节点
// //options 形参: 以后指令一些配置项参数【对象】// // 自定义指令:本质能够获取到实在 DOM 节点,操作 DOM 节点!!!// element.innerHTML = options.value.toUpperCase();
// }
},
全局指令: 在 main.js 中定义全局指令
// 定义全局自定义指令。只须要定义一次, 在任意组件都能够间接应用!!!// 第一个参数: 自定义指令名字【定义的时候不须要带 v -xxx】// 第二个参数: 回调函数[当在某一个 VC,当中应用指令的时候会执行一次]
Vue.directive('upper',(element,options)=>{console.log(element);
//element: 是你绑定指令的 DOM 节点!!!!element.innerHTML = options.value.toUpperCase();});
过滤器
<!-- 底下语法: 常常叫做 '管道' -->
<h1>{{time|timeFormat}}</h1>
部分过滤器
// 部分过滤器: 在哪个组件定义的,就在哪个组件应用!!!!filters: {
// 定义一个过滤器
// 当模板中应用过滤器的时候,底部函数会执行一次
// 过滤器函数须要有返回值, 返回值即为格式化后果
//params 第一个参数: 须要格式化数据,就是管道后面的表达式存储数值!!!// timeFormat(params){// return moment(params).format('YYYY-MM-DD');
// }
},
全局过滤器
// 定义一个全局的过滤器
// 第一个参数: 是过滤器的名字
// 第二个参数: 是回调函数。【当你应用这个过滤器的时候, 会执行一次】Vue.filter("timeFormat",(val)=>{
//val: 须要格式化的数据
// 回调函数返回的后果即为格式化数据
return moment(val).format('YYYY-MM-DD');
});
自定义插件
在 Vue 框架中,Vue 官网团队给咱们提供很多插件。
element-ui 插件 (相似 React 中的 antd)
vue-router 插件(相似 react-router)
vuex(相似于 redux)
尝试本人封装 Vue 框架中的插件性能:Vue 框架中插件次要的目标,给你的 Vue 我的项目增加全局的性能。
舒适提醒: 装置插件务必应用 Vue.use 办法装置插件!!!
舒适提醒: 插件是一个 JS 对象, 务必要 install 办法,当装置插件的时候 Vue.use, 会主动调用 install 办法
舒适提醒: 插件的装置务必在初始化 VM 之前调用!!!!
在 src 目录下新建一个文件夹 plugins, 在 plugins 下新建 element.js 文件
element.js 代码如下:
// 开发本人定义 (封装的) 插件。插件的目标是给我的项目提供全局的性能!!!!// 定义一个对象: 以后对象即为插件对象
// 引入 moment
import moment from 'moment';
let plguins = {
// 肯定要留神:插件对象身上务必要有 install 办法
// 当我的项目应用插件的时候 ->Vue.use(). 当插件被应用的时候,插件对象的 install 办法会执行一次
install(Vue, options) {// 第一个参数:Vue 构造函数(初始化 VM、全局组件、全局指令、全局过滤器)
// 第二参数:Vue.use(plugins,1000), 将 1000 赋值给 options
// 本人开发最简略的插件
// 提供全局的自定义指令
Vue.directive('upper', (element, options) => {element.innerHTML = options.value.toUpperCase();
});
// 全局过滤器
Vue.filter('timeFormat', (value) => {return moment(value).format('YYYY-MM-DD');
});
// 全局组件
// Vue.component();
// 全局性能
Vue.prototype.$erha = function () {alert('二哈咬人');
}
}
}
// 对外裸露:别的模块要应用
// 默认裸露
export default plguins;
在 main.js 中装置插件
import Vue from 'vue'
import App from './App.vue'
// 入口文件引入插件【默认对外裸露一个对象】import plugins from './plugins/element';
// 如果你想让你的我的项目应用这个插件性能:须要给我的项目装置插件 ->Vue.use 办法装置插件!!!// 上面的代码:代表的含意是,给你的我的项目装置插件!!!!//Vue.use(plugins)插件对象的 install 办法会执行一次。// 小留神: 装置常见切记在 new VM 之前装置插件!!!!Vue.use(plugins, {name: 'upper'});
new Vue({render: h => h(App),
}).$mount('#app');
自定义事件
定义事件
<!--
自定义事件, 程序员本人定义的事件!!!事件源:MySon 组件标签
事件类型:erha(自定义类型)
事件的回调函数:handler
自定义事件回调外面没有 event;怎么触发自定义事件: 在事件源 (组件) 外部通过 $emit 办法手动触发自定义事件!!!!-->
<MySon @erha="handler"></MySon>
export default {
name: "",
components: {MySon,},
// 父组件王健林的办法
methods: {handler(params1,params2) {
// 自定义事件回调外面没有 event;console.log('爸爸组件',params1,params2);
},
},
};
自定义事件的骚操作
// 当组件挂载结束执行一次 ----mounted
mounted(){
//$on|$emit 都是 Vue.prototype 原型对象的办法:vm 能够应用,vc 能够应用!!!// 上面的代码代表含意是:给事件源 MySon1 组件实例绑定一个自定义事件 car
// 第一个参数: 自定义事件名字 第二个参数: 自定义事件的回调
this.$refs.cur.$on('car',(params)=>{console.log(params);
})
}
触发事件
export default {
name: "",
methods: {clickHandler(){
//VC 的原型的原型【Vue.prototype】身上领有 $emit 办法。// 能够触发自定义事件
// 第一个参数: 自定义事件的类型
// 第二参数当前:注入到事件回调的参数
this.$emit("erha",'王思聪给你一个亿','王思聪怼央视新闻');
}
}
};
自定义事件总结:
1、上面这种写法是自定义事件简写模式.
<MySon @erha=”handler”></MySon>
this.$emit(“erha”,’ 王思聪给你一个亿 ’,’ 王思聪怼央视新闻 ’);
2、自定义事件残缺写法
事件源.$on(‘erha’,(params)=>{});
事件源.$emit(‘erha’,’ 一个亿 ’)
面试题:开发我的项目的时候,组件通信形式接触过多少种?(11 种伎俩)
1、props 能够实现父给子传递数据。【父 -> 子】
2、自定义事件, 能够实现儿子给父亲传递数据【子 -> 父】
3. 全局事件总线
全局事件总线
利用的就是 Vue.prototype 原型对象的 $on,$emit 实现的。
//Vue 原型对象身上增加一个新的属性
// 相当于在 Vue.prototype 原型对象的身上挂载一个 Vue 类的实例【VM:$on、$emit】
//VC 都能够通过原型链找到雷同的属性值【事件源】
在 main.js 中配置全局事件总线
new Vue({
// 生命周期函数
beforeCreate(){
// 配置全局事件总线,在 Vue 的原型上增加 $bus 属性,属性值为 VM【Vue 类的实例】// 底下的 this, 并非是 VC,是 VM【Vue 类的一个实例】Vue.prototype.$bus = this;
},
render: h => h(App),
}).$mount('#app');
触发事件
// 上面事件源: 都是 Vue 类的实例 VM,并非 VC
this.$bus.$emit('money',30000);
绑定事件
// 组件挂载结束
mounted(){this.$bus.$on('money',(money)=>{console.log('爷爷'+money);
})
}
代理服务器
在 vue.config.js 增加配置
devServer: {
proxy: {
'/erha': {
target: 'http://localhost:9999',
pathRewrite: {'^/erha': ''},
},
},
}
//erha: 如果你的我的项目当中,申请的地址带 /erha, 代理服务器才会帮你做事!!!!//target:获取数据那台服务器地址【书写到端口号即可】//pathRewrite: 门路重写
重启我的项目, 因为配置项发生变化
留神:发申请后面须要加上 /erha
对 axios 进行二次封装
通常会在 src 文件夹下,新建一个 api 文件夹,新建 request.js 文件
// 对于 axios 模块进行二次封装!!!
// 须要引入 axios
import axios from "axios";
// 进度条的业务
import nprogress from 'nprogress';
// 应用进度条的时候,须要把人家的款式引入!!import "nprogress/nprogress.css";
// 申请拦截器: 当你申请的时候触发(服务器没有做出响应)!
axios.interceptors.request.use((config) => {
// 申请拦截器
//config 配置对象, 身上有一个很重要货色, 申请头 ****
console.log('捕捉到发申请');
// 进度条开始动
nprogress.start();
return config;
}, (error)=> {
// 对申请谬误做些什么
return Promise.reject(error);
});
// 响应拦截器: 当服务器数据响应胜利触发!axios.interceptors.response.use((res) => {
// 响应胜利
console.log('捕捉到申请胜利');
nprogress.done();
// 个别咱们会简化服务器返回的数据【因为服务器返回的数据个别须要的 data: 右侧数据】return res.data;
}, (error) => {nprogress.done();
// 响应失败
return Promise.reject(error);
});
// 对外裸露 axios
export default axios;
node 相干知识点
express 是 node 的一个框架
koa[也是 node 平台搭建服务器用的,是 express 降级版本]
面试题: 在工作时候有没对 axios 进行二次封装!!!二次封装你次要干什么?
答:咱们工作的时候常常对于 axios 进行二次封装, 次要给 axios 增加申请、响应拦截器!!
面试题: 什么是跨域? 解决跨域的伎俩有哪些?
Vuex
vuex 也是一个插件,插件的作用:提供一些全局性能!
装置
npm i –save vuex@3
单词
dispatch-> 公布、差遣
commit-> 提交
actions-> 口头
mutations-> 扭转
state-> 状态
vuex 外围概念
actions-> 口头(能够书写业务逻辑的中央,比方 if 判断、异步语句等等)
mutations-> 扭转(惟一能够批改仓库数据的中央)
state-> 状态(仓库存储数据的中央。组件实例能够应用)
getters: 仓库的计算属性
应用步骤
1、在 src 文件夹下创立一个文件夹 store,在 store 文件夹中新建 index.js 文件
// 当前 store 文件夹外面 index 文件,就是与 vuex 仓库相干的文件!!!
import Vue from 'vue';
// 引入 vuex 插件,vuex 插件对外裸露是一个对象【插件对象:install 办法】import Vuex from 'vuex';
// 应用插件:Vue.use();
Vue.use(Vuex);
// 创立咱们仓库
//Vuex 插件对象, 身上有一个 Store 办法, 它是一个构造函数。执行会返回一个 Store 类的一个实例【仓库】let store = new Vuex.Store({
// 存储数据的中央
state: {
count: 1,
hobby: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
// 是惟一能够批改 state 外面数据中央
mutations: {
// 惟一批改批改数据的中央
// 第一个参数:state 即为以后仓库的数据
ADD(state) {state.count++;}
,
MINUS(state) {
state.count--;
//this 即为以后仓库,Store 类的实例, 就是不必!!},
ADDNINE(state, payload) {state.count += payload;},
UPDATECOUNT(state,payload){state.count = payload;}
},
// 书写业务逻辑, 比方书写 if、异步语句等等。然而这里不能间接批改数据!!!actions: {
// 解决 add 类型的 action
//miniStore 就是一个对象 (小仓库) 领有的办法根本与 Store 类的实例截然不同!!!add({commit, state, dispatch}) {
// 生存例子: 相当于 add 这个办公室这个人,曾经批准这次申请【呈现 commit】// 这次批准人家通知你了, 找叫做 ADD 这个工人去解决这个批改!!!
commit("ADD");
},
// 解决 minus 类型的 action
//commit: 提交 mutation 办法
//state: 即为以后仓库存储的数据
//dispatch: 派发小弟用的办法
minus({commit, state, dispatch}) {commit("MINUS");
//this 即为以后仓库:Store 类的实例。在 vuex 中不必 this
},
evenAdd({commit, state, dispatch}) {
// 生存例子: 这次办事, 并不是立马就许可了。有条件了【业务判断】if (state.count % 2 == 0) {commit('ADD');
} else {console.log('不符合条件, 临时不解决');
}
},
oddMinus({commit, state, dispatch}) {if (state.count % 2 != 0) {commit("MINUS")
} else {console.log('不符合条件, 不受理');
}
},
// 第一个参数:miniStore 小仓库
addNine({commit, state, dispatch}, payload) {// 相当于(批准): 你去找名字 ADDNINE 这个工人, 携带一些信息【信外面:VC 让我给你带的信息】commit("ADDNINE", payload);
}
,
//delayAdd 类型的 action
delayAdd({commit, state, dispatch}) {
// 能够书写异步语句
// 异步语句: 定时器、提早器、ajax、promise 等等
setTimeout(() => {commit("ADD");
}, 2000);
},
updateCount({commit,state,dispatch},payload){commit('UPDATECOUNT',payload);
}
},
// 了解为仓库中的计算属性
getters: {
//state, 即为仓库中的数据
total(state) {
// 留神:getters 外面的函数 this->undefined
// 这里即为计算属性,服侍仓库,利用已有的属性与属性值,造出一个新的属性与属性值!!!!
return state.hobby.reduce((a, b) => a + b, 0)
}
}
});
// 对外裸露仓库: 裸露的仓库到底是什么鬼?
// 裸露的仓库本质即为 Store 类的一个实例而已!!!export default store;
2、在 main.js 中减少 store 配置项
import Vue from 'vue'
import App from './App.vue'
// 仓库曾经建设好了, 应用仓库性能!!!
import store from '@/store';
new Vue({render: h => h(App),
// 这行代码代表含意是: 我的项目当中应用仓库性能, 给每一个 VC 实例身上增加 $store 属性.【让 VC 与仓库进行关联】store,
}).$mount('#app')
3、应用
<template>
<div>
<h1> 计数器:{{count}}</h1>
<h2>getters 计算属性的数据简单的写法:{{total}}</h2>
<h1>{{hobby}}</h1>
<button @click="add"> 点击我加上 1 </button>
<button @click="minus"> 点击我减去 1 </button>
<button @click="evenAdd"> 点击我偶数加 1 </button>
<button @click="oddMinus"> 点击我奇数减 1 </button>
<button @click="addNine"> 点击我加上 9 </button>
<button @click="delayAdd"> 点击我两秒之后加上 1 </button>
<hr>
<!--
原生 DOM 也有这个事件:
input: 当文本框内容发生变化, 立刻触发事件
change: 当文本框内容发生变化 (点击空白的中央) 才会执行!!!
-->
<input type="text" :value="count" @input="changeHandler">
</div>
</template>
<script>
//vuex 提供一些辅助性的函数, 函数能够把仓库的数据增加组件实例!!//mapState 是 vuex 别离裸露的函数, 须要传递数组 | 对象
//mapGetters 是 vuex 别离裸露的函数, 须要传递数组 | 对象
import {mapState,mapGetters} from 'vuex';
export default {
name: "",
methods:{
// 点击按钮加上 1 的回调函数
add(){
// 生存例子: 张三差遣一个小弟, 通知他【去仓库办公室 action, 找到名字叫做 add 这个人, 审批这次申请】// 程序员:VC 派发一个 add 类型的 action
this.$store.dispatch("add");
console.log(this);
},
// 点击减去 1 的回调函数
minus(){
// 派发 actions
this.$store.dispatch('minus');
}
,
// 偶数加上 1
evenAdd(){this.$store.dispatch('evenAdd');
},
// 奇数减去 1
oddMinus(){this.$store.dispatch('oddMinus');
}
,
// 点击按钮加上 9
addNine(){
// 派发 action
// 第一个参数:vuex 仓库外面的 actions 名字
// 第二个参数: 载荷【payload】, 第二个参数起始就是 VC 组件实例给 actions 传递参数
// 没有第三个参数了
this.$store.dispatch('addNine',9);
}
,
// 两秒之后加上 1 的回调
delayAdd(){
// 派发 action
this.$store.dispatch('delayAdd');
},
changeHandler(e){this.$store.dispatch('updateCount',e.target.value)
}
},
// 计算属性: 利用已有的属性 [$store] 与属性值, 发明出一个新的属性与属性值!!!// 计算属性:缓存
computed:{
// 数组外面书写的是 state 右侧对象的 K, 将仓库数据作为组件实例的数据!!!!
...mapState(['count','hobby']),
...mapGetters(['total'])
},
};
</script>
<style scoped>
</style>
面试题:Vuex 仓库存储的数据是否长久化?
不是长久化,我的项目从新运行,数据又复原初始状态
面试题:如何实现 v -model 操作 vuex 流程
利用表单元素的 value 和 input 事件实现的
<input type="text" :value="count" @input="changeHandler">
methods:{changeHandler(e){this.$store.dispatch('updateCount',e.target.value)
}
},
computed:{
// 数组外面书写的是 state 右侧对象的 K, 将仓库数据作为组件实例的数据!!!!
...mapState(['count','hobby']),
...mapGetters(['total'])
},
过渡动画成果
步骤:
第一步: 元素或者组件必须要用到 v -if 或 v-show
显示:称之为进入状态
暗藏:称之为来到状态
第二部:外层用 transition 全局组件包裹
第三部:写 css
v-enter
:定义进入过渡的开始状态。在元素被插入之前失效,在元素被插入之后的下一帧移除。v-enter-active
:定义进入过渡失效时的状态。在整个进入过渡的阶段中利用,在元素被插入之前失效,在过渡 / 动画实现之后移除。这个类能够被用来定义进入过渡的过程工夫,提早和曲线函数。v-enter-to
:2.1.8 版及以上 定义进入过渡的完结状态。在元素被插入之后下一帧失效 (与此同时v-enter
被移除),在过渡 / 动画实现之后移除。v-leave
:定义来到过渡的开始状态。在来到过渡被触发时立即失效,下一帧被移除。v-leave-active
:定义来到过渡失效时的状态。在整个来到过渡的阶段中利用,在来到过渡被触发时立即失效,在过渡 / 动画实现之后移除。这个类能够被用来定义来到过渡的过程工夫,提早和曲线函数。v-leave-to
:2.1.8 版及以上 定义来到过渡的完结状态。在来到过渡被触发之后下一帧失效 (与此同时v-leave
被删除),在过渡 / 动画实现之后移除。
/** 进入阶段:**/
/** 进入开始阶段:**/
/** 进入定义动画阶段:**/
/** 进入完结阶段:**/
脚手架中如何应用 less?
第一步:npm i less less-loader –save
第二部:
<style scoped lang="less"></style>
在 less 中申明变量
<style scoped lang="less">
@color:red;
.box{
width: 400px;
height: 200px;
background: blue;
h3{color:@color;}
}
.v-enter{opacity: 0;}
.v-enter-active{transition: opacity 2.5s;}
.v-enter-to{opacity: 1;}
</style>
Vue-router
后端路由的概念
后盾语言:Java、PHP、python、C++ 等等,在后盾当中他们也存在路由的概念。
K: 即为地址栏的 URL。
V: 对应的中间件。
let express = require(‘express’);
let app = express();
app.get(‘/students’,(req,res)=>{
res.send('我是字符串');
});
app.get(“/luban”,(req,res)=>{
res.send('鲁班常常挨揍');
})
app.listen(3000);
前端路由的概念
K:url
v:相应的组件
辨别两个单词
router:路由器
route:路由
vue-router 的根本应用
配路由的时候分两个区域,导航区和展示区
提醒 1:当前再我的项目中,路由组件个别搁置在 pages|views 文件夹中
提醒 2:vue-cli 工具 (官网团队提供工具), 倡议组件的名字【两个单词: 首字母大写】,
如果 eslint 校验工具敞开, 组件名字能够是一个字母【首字母大写即可】!!!
留神
Vue 框架自身只是提供外围语法【指令、生命周期、计算属性、监听】。Vue 框架本身是没有路由能力的。
vue-router 最新的版本 4【vue-router@4 版本在 vue-cli5】当中跑不起来。
装置 vue-router 插件的时候,升高版本,装置 3 版本。
须要装置插件npm i --save vue-router@3
步骤
第一步:配置我的项目路由
当前我的项目配置路由,须要在 src/router 文件夹中,在 router 文件夹下新建 index.js
// 配置路由
// 引入 vue-router 插件: 通过打印查看, 引入进来的 VueRouter 构造函数
//vue 根底学习构造函数:Vue、VueComponent、Vuex.Store、VueRouter
import VueRouter from 'vue-router';
import Vue from 'vue';
// 装置插件
Vue.use(VueRouter);
// 引入路由组件
import Home from '@/pages/Home';
import About from '@/pages/About';
// 配置我的项目的路由
// 通过 VueRouter【路由器】类, 创立了一个 VueRouter 类的一个实例!!!// 对外裸露
export default new VueRouter({// 配置项的 K 是没有磋商的余地[route: 路由]
routes: [
{//path 设置路由的 K,path 有的属性值务必都是小写的(设置 path 右侧 V 的时候,别忘记反斜杠)
path: "/home",
//component 设置路由的 V, 一个 K 对应一个 V
component: Home
},
{
path: '/about',
component: About,
children: [
{
// 第一种写法: 门路书写全面, 把上一级的门路带上
// /home/news news
path: 'news',
component: News
},
{
// 第二种写法: 起一个子路由的名字即可【后面页不须要带 /】// /home/message message
path: 'message',// 相当于 ->/home/message
component: Messaage,
children: [
{
// 命名路由, 给路由起一个名字
name:"erha",
// 动静路由务必传递两个 params 参数
path: 'detail/:id/:name',
component:Detail
}
]
}
]
}
]
});
第二步:在 main.js 中引入、注册路由
import Vue from 'vue'
import App from './App.vue'
// 引入路由, 并且注册路由
import router from '@/router';
new Vue({
// 注册路由: 通过配置项 router 设置【K: 不能瞎写、不能胡写、不能乱写】// 注册路由这行代码作用: 注册路由性能, 能够给全副 VC 实例身上增加 $router|$route 属性
router,
render: h => h(App),
}).$mount('#app')
第三步:应用
<!-- 导航区域 -->
<div class="col-xs-2 col-xs-offset-2">
<!-- 导航链接: 能够设置 K 的数值, 导航链接通过【vue-router 插件提供的】全局组件 router-link 实现 -->
<!-- 导航链接:务必要有 to 属性 -->
<router-link class="list-group-item" to="/about">About</router-link>
<router-link class="list-group-item" to="/home">Home</router-link>
</div>
<!-- 展示区: 展现的内容 home|about 路由组件 -->
<!-- 路由组件进口的中央: 路由组件在哪里展现 -->
<!--
展现区域: 展现路由组件的区域(中央),router-view, 它也是 Vue-router 提供的一个全局组件
它的作用是: 路由组件的进口的中央的设置,说白了, 就是路由组件在哪里展会
-->
<router-view></router-view>
vue-router 细节钻研
第一问:路由组件与非路由组件在应用的时候有什么区别?
非路由组件
定义 ->xxx.vue
注册 ->components 注册
应用 -> 组件标签的模式应用
<div>
<TodoFooter></TodoFooter>
</div>
路由组件: 在应用的时候
基本看不见双标签 | 单标签,都是在 router 文件夹外面应用【组件名字】
第二问:router|route 区别?
router: 路由器【router 文件: 对外裸露的 VueRouter 类的实例,路由器】
route: 路由, 一个路由器能够治理多个路由
第三问: 入口文件,注册路由器作用?
注册 router 作用: 注册后全副 VC 身上都会领有 $router|$route 属性
第四问:router-link|router-view。
router-link|router-view 是全局组件:在任意 VC 外面都能够间接应用【vue-router 提供的全局组件】
router-link: 申明式导航链接, 能够批改 K,务必要有 to 属性!!!
router-view: 路由组件进口中央设置
肯定要留神一件事件: 路由组件切换的时候, 每一次路由组件的 mounted 都会再一次执行。
因为每一次路由的切换,都会导致上一次的路由组件被销毁重建!!!!
第五问:keep-alive 全局组件有什么作用?
在我的项目中路由组件切换的时候:相应的路由组件会被销毁重建。
Vue 框架中,提供了一个全局组件 kepp-alive。这个组件的作用是能够缓存路由组件!!!
<keep-alive :include="['home','about']">
<router-view></router-view>
</keep-alive>
第六问、路由传递参数有几种形式?
Vue 框架反对路由传递参数: 路由传递参数有两种,query 参数,params 参数?
query 参数:上面这种写法<router-link to="/home/message/detail?a=1&b= 烤鸭"> 申明式导航链接:query 参数 </router-link>
params 参数: 上面这种写法<router-link to="/home/message/detail/10/ 容嬷嬷"> 申明式导航链接:params 参数 </router-link>
query 参数: 不是门路当中一部分 ?k=v&k=v
params 参数: 算作门路当中一部分,params 参数肯定要将路由的配置改成path:'detail/:id/:name'
配置路由的时候上面这种写法代表含意
代表你的 Detail 路由组件务必传递 params 参数。
path: ‘detail/:id/:name’,
编程式导航
在 vue-router 插件中,导航有两种模式。
第一种即为申明式导航 router-link 标签。
第二种即为编程式导航, 任意标签都能够作为导航链接。
goDetail(item) {// 能够通过 VC 的 $router[路由器], 实现路由的跳转!!!
//VC 身上的 $router 属性, 本质它的属性值即为 VueRouter 类的实例。//VueRouter.prototype 原型对象的身上有 push|replace 办法,他们能够实现路由的跳转!!// 编程式导航: 跳转到 Detail
// 编程式导航: 第一种写法【纯纯的字符串写法, 这种写法当前不会用了】query|params 参数都能够
//this.$router.push("/home/message/detail?a="+item.a+"&b="+item.b);
// 编程式导航:第二种写法【不罕用】, 模板字符串写法
//this.$router.push(`/home/message/detail?a=${item.a}&b=${item.b}`);
// 第三种写法: 对象写法【很重要: 下面两种写法你能够遗记】// 书写配置对象
// 传递 query 参数:path: 设置的跳转门路 query
//this.$router.push({path: "/home/message/detail",query:{a:item.a,b:item.b}});
// 传递 params 参数: 记住豪哥交给你们的顺口溜, 两个 P 犯相【不行】!!!!
// 编程式导航:路由跳转传递 params 参数,务必给路由命名【2 个 P 犯相】this.$router.replace({name:'erha',params:{id:item.a,name:item.b}})
// 传递 query| 传递 params
// 书写逻辑的
// if (item.id > 1) {
// this.$router.push({
// name: "erha",
// query: {a: 1, b: 2},
// params: {id: 4, name: 5},
// });
// }
}
编程式导航与申明式导航有啥区别?
雷同中央: 都能实现路由的跳转以及传递参数【query、params】
不同的中央: 编程式导航能够书写业务逻辑、申明式导航就是一个破标签,点击就跳转了,没有书写判断中央!!!
vc 身上的 $route 和 $router 的区别是什么?
$route:与路由相干【路由的 URL、query 参数、params 都都能够获取到】
$router:push|replace, 实现编程式导航路由跳转!!!
push 与 replace 区别?
push 模式: 能够记录历史记录
replace: 不会记录历史记录
vue-router 路由的模式有几种?
hash:hash 模式【门路当中带有 #】
history: 历史模式【门路当中不带 #】
面试题:vue 的路由模式有几种?有什么区别?
两种模式:hash 模式、history 模式!
区别:
1: 眼睛能看到,hash 模式门路携带 #,history 模式门路当中不须要携带#
2:history 模式下我的项目,在打包的时候上线, 须要与后盾紧密配合【nginx】, 如果于后盾配合不好经常出现 404。