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等等
基本用法
Document
您好,{{name}}
胡子语法(插值语法)注意事项:
- 可以书写实例的属性
- 可以书写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:给标签绑定动态属性值
例如:
v-bind简写方式
//初始化Vue实例,进行关联
const VM = new Vue({
el: '#app',
data: {
url: "./images/1.jpg",
leixing: 'text',
name: 'box'
}
})
v-model(数据的双向绑定)
作用:可以让表单元素实现数据的双向绑定【页面+数据同步】,主要作用是 收集表单元素 的信息,
注意:非表单元素p、div、a、img等等不能使用v-model
文本框:
单选:
男
女
复选:在通过数据双向绑定收集数据的时候,复选框用数组收集数据
吃饭
睡觉
打豆豆
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"
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遍历数据:工作、项目当中一般只是使用数组!!!!
遍历数组
-
{{stu.name}}----{{index}}
遍历数字
{{num}}----{{index}}
遍历字符串
{{str}}---{{index}}
遍历对象
{{v}}---{{k}}
修饰符的使用
prevent修饰符的使用:
stop修饰符的使用:
once修饰符的使用:
注意:修饰符可以进行链式语法,谁先谁后无所谓,这种出现情况比较是少
这些语法都是支持的,只不过项目、工作当中基础没有这种写法!!!!
@click.stop.prevent.once
@click.once.prevent.stop
@click.prevent.stop.once
键盘事件的修饰符
键盘事件的修饰符,一般只是与表单元素一起使用。
键盘相关的修饰符有很多:
enter->回车键
left->左键
right->右键
up->上键
down->下键
esc、
a-z、
数字的都可以、书写相应的键盘码数字都可以
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)
今天天气不错,明天天气更好
今天天气不错,明天天气更好
当 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:计算属性算出来的数值有缓存机制,计算出一个可以多次使用
动态类名
大江东去浪淘尽,千古风流人物
动态类名-字符串写法
煮豆持 作羹,漉菽以为汁。
萁在釜下燃,豆在 釜中泣。
本自同 根生,相煎何太急?
动态类名对象写法
1.《长城》【唐】汪遵 秦筑长城比铁牢,蕃戎不敢过临洮。 虽然万里连云际,争及尧阶三尺高。
动态类名之数组的写法
北京(Beijing),简称“京”,古称燕京、北平,是中华人民共和国的首都、直辖市、国家中心城市、超大城市,国务院批复确定的中国政治中心、文化中心、国际交往中心、科技创新中心,截至2020年,全市下辖16个区,总面积16410.54平方千米。根据第七次
data: {
selector: 'tab',
obj: { one: true, two:0}
}
动态行内样式
我是祖国的老骨朵
行内样式的动态写法之--对象写法
Vue框架行内样式写法
行内样式动态写法之-数组写法
动态行内样式style支持数组写法
//动态行内样式写法:支持对象写法、支持数组写法。主要记忆对象写法
watch监听属性
//监听属性,作用:watch也是一个配置项,它主要的作用是,可以监听 VM响应式属性的值 的变化。
watch: {
//监听属性的时候,当属性值发生变化的监听的函数会立即执行一次
//底下书写的监听VM->属性名字【VM身上没有这个响应式属性,监听不到的】
//函数写法
// keyword(){
// console.log('我能监听到keyword关键字发生变化,只要关键字发生变化立即执行一次');
// }
//对象写法
keyword:{
//如果是对象的写法,通过handler方法监听属性值的变化
//函数的名字不能瞎写
handler(){
console.log('VM响应式属性值发生变化');
}
}
}
生命周期
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函数写法
版本说明
Vue依赖包:尤雨溪团队,给开发人员提供很多版本的依赖包 【完整版本、压缩版本、运行时版本】
全局组件
全局组件的使用:只需要定义一次,可以在任意组件中直接使用。就不用每一次都在注册了。
全局组件一般在这种情况下才会使用:项目当中很多地方(组件),大家频繁使用某一个功能,你就可以把这个功能封装为全局组件,定义一次,可以在任意地方直接使用【不需要引入、不需要注册】直接使用。
//定义一个组件
const Carousel = Vue.extend({
data(){
return {info:'我是轮播图组件,而且我还是全局组件'};
},
//结构编辑器
template:`
{{info}}
`
});
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
创建组件的简写方式
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指令
局部指令
//新增一个配置项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();
});
过滤器
{{ time|timeFormat }}
局部过滤器
//局部过滤器:在哪个组件定义的,就在哪个组件使用!!!!
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');
自定义事件
定义事件
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、下面这种写法是自定义事件简写形式.
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、使用
计数器:{{count}}
getters计算属性的数据复杂的写法:{{total}}
{{hobby}}
面试题:Vuex仓库存储的数据是否持久化?
不是持久化,项目重新运行,数据又恢复初始状态
面试题:如何实现v-model操作vuex流程
利用表单元素的value 和input事件实现的
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
第二部:
在less中声明变量
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')
第三步:使用
About
Home
vue-router细节研究
第一问:路由组件与非路由组件在使用的时候有什么区别?
非路由组件
定义->xxx.vue
注册->components注册
使用->组件标签的形式使用
路由组件:在使用的时候
根本看不见双标签|单标签,都是在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。这个组件的作用是可以缓存路由组件!!!
第六问、路由传递参数有几种方式?
Vue框架支持路由传递参数:路由传递参数有两种,query参数,params参数?
query参数:下面这种写法
params参数:下面这种写法
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。