Vue如何去除url中的#
vue-router默认使用hash模式,所以在路由加载的时候,项目中的router
的另一中模式 history
new Router({
mode:'history',
routers:[]
})
//需要注意的是:当我们启用history模式的时候,由于
//我们的项目是一个单页面应用,所以在路由跳转的时候,
//就会出现访问不到静态资源而出现404的情况,这时候就需要服
//务端增加一个覆盖所有情况的候选资源,
//如果url匹配不到任何静态资源,则应该退回同一个index.html页面
MVC MVVM
Model:模型 ======data里面的数据
viewModel:======视图模型
View:=======视图 模板
Control 手动编写大量的DOM操作
(一旦View或Model发生变化,Controler被迫修改!)
ViewModel 将Model和View进行绑定
Model中的所有属性自动变成访问器属性,一旦修改自动触发通知机制
ViewModel通过虚拟DOM树,封装DOM操作,自动维护Model中的变化和View
上的显示同步,不用自己写DOM
(View和Model可分开维护)
当View改变时,View由ViewModel自动扫描生成,无需人工修改
当Model改变时,Model由ViewModel自动扫描生成,无需人工修改
真正做到将数据和界面真正分离开
介绍虚拟DOM树
什么是虚拟DOM树:
仅包含可能变化的节点和可能变化的属性的树结构
<body>
<div id="app">
<img src="log.png">
<h1>{{uname}}</h1>
<hr>
<h2>{{score}}</h2>
<div>
</body>
//虚拟dom
{
el:'#app',
children:[
{el:'h1',innerText:uname},
{el:'h2',innerText:score}
]
}
为什么:内容少,便于快速遍历比较不同
如何发挥作用:当data中模型变量改变时,会通知虚拟dom树,
虚拟dom树先缓存本次的修改在元素对象上,将一批修改生成
新的dom子树和原虚拟dom树做对比,一旦发现不同的元素或内容
,就只更新有修改的元素,虚拟dom树中,封装了传统dom API,
避免了程序员编写大量重复的代码
**VUE声明周期函数*
8个阶段 创建前后 载入前后 更新前后 销毁前后
new Vue时,先会创建data对象,并且把data对象中的值和变
量封装成访问器属性;
created:创建完vue对象后自动触发 只有data,没有虚拟dom树;
(数据的操作可以ajax请求,不能做dom操作(查找元素,修改内容));
mounterd:vue对象才算创建完成(想做什么就可以做什么)
(有些开发人员就会把数据和dom都在这个阶段完成)
当data中的变量被修改的时候,才会触发updated;
*
```javascript
在这里插入代码片
组件通信
父组件向子组件通信
子组件通过props属性,绑定父组件数据,实现双方通信
子组件向父组件通信
将父组件的事件在子组件上通过$emit触发
非父子组件、兄弟组件之间的数据传递
vue-router 路由实现
1.路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,
来请求不同的资源,请求不同的页面是路由的其中一种功能。
1:hash模式
前端路由默认使用hash模式,他去匹配#号后面的相对路径,去自己的路由字典中查找匹配的组件
加载并替换
路由组件的实现方式:
01:把所有的组件都准备好
02:创建一个路由字典(有相对路径和组件对象的对应关系)
03:把路由字典放入路由器对象中,
04:将路由对象放入newVue中
虚拟DOM树:
虚拟DOM树:
什么是: 仅包含可能变化的节点和可能变化的属性的树结构
<body>
<div id=”app”>
<img src=”logo.png”> alt title id ….
<h1>{{uname}}</h1>id class title name
<hr>
<h2>{{score}}</h2>
</div>
{
el:”#app”,
children:[
{el:”h1”, innerText:uname},
{el:”h2”,innerText:score}
]
}
为什么: 内容少,便于快速遍历比较不同
如何发挥作用:
当data中模型变量改变时,会通知虚拟DOM树
虚拟DOM树先缓存本次的修改在元素对象上
将一批修改生成新的DOM子树和原虚拟DOM树做对比。
一旦发现不同的元素或内容,就只更新有修改的元素
虚拟DOM树中,封装了传统DOM API: createElement() appendChild() .innerHTML,避免了程序员编写大量重复的代码。
v-if和v-show的区别
v-if:删除元素
v-show:display:none;
r o u t e 和 route和 route和router的区别
$router 不是一个值,是一个可以干活的东西,路由器,可以帮助我们跳转动作,
为vueRouter实例,想要导航到不同的URL
$route 值 url地址栏中的一切 就是location.href
为当前router跳转对象里面可以获取 name,path,query,查询字符串,参数列表,
懒加载Vue首屏加载非常慢
原因: 当打包应用时,将所有JavaScript代码打包在一个文件中,导致js代码非常庞大,严重影响页面加载速度。
解决:
1. 配置打包工具,将组件分别打包到不同的js代码块中
build/webpack.base.conf.js
output:{
path: config.build.assetsRoot,
filename:’[name].js’,
//新增
chunkFilename:”[name].js”,
publicPath: process.env.NODE_ENV===”production”
?config.build.assetsPublicPath
:config.dev.assetsPublicPath
}
2. 当路由请求到该组件时,才动态加载组件的内容
路由字典中,路由配置和以前完全一样
但是在引入组件对象时:
import Index from ‘@/views/Index.vue’
改为
const Index=()=>import(‘@/views/Index.vue’)//仅定义函数
//暂未执行
//暂时不引入Index.vue
当用户在vue中请求当前组件对应的路由地址时,由vue-router自动调用加载函数,动态请求Index.vue组件对象
Vue组件data为什么必须是函数
因为js本身的特性带来的,如果data是一个对象
因为每个组件(拥有独立的html,css和数据的页面),组件与组件之间数据不会相互影响
怎么保证组件与组件之间数据不相互影响呢?
把data定义为一个函数,让这个函数每次都return一个新的对象,这样每创建一个组件,就像老母鸡下蛋一样,就return一个新的对象给新的组件
计算属性computed:有缓存 和事件methods:无缓存 有什么区别
能用computed的地方就用computed,不用methods
computed 只要依赖的值不变,首次计算的结果会被Vue缓存下来,就算多次显示,也只需要计算1次,
对于method,只要发生重新渲染,method调用总和执行该函数
jQuery和Vue的不同
jQuery专注视图层,通过操作dom去实现页面的一些逻辑渲染,界面发生变化,js被迫要修改(直接影响了选择器)
Vue自动扫描页面,自动查找不同,自动封装domApi,让界面和模型松耦合
** 如果想为一个套在很多层标签内的子元素绑定内容或样式,怎么办?**
根本不要查找,哪里需要哪里绑定即可!页面中任何位置,都可使用各种绑定语法找到data中的变量。
能不能监控内嵌在对象中的变量或属性?
答: data中的一切变量都可被监控,但是,如果内嵌的变量或者属性,监控时,函数名时一个完整的查找对象的字符串:
data:{
divStyle:{
top:"50px",
left:"50px"
}
},
watch:{
"divStyle.top"(){
console.log(`top:${this.divStyle.top}`);
},
"divStyle.left"(){
console.log(`left:${this.divStyle.left}`);
}
}
SPA 单页面应用
何时: 今后,基本上都是单页面应用。
如何:
1. 先有一个完整的home.html文件
home.html中主体部分被用特殊标签占位,暂时为空
2. 再为每个"页面",定义组件对象
比如: index.js details.js products.js login.js
3. 创建路由地址列表
什么是: 保存每个路由地址和组件对象对应关系的列表
如何:
var routes=[
{ path:"/index", component: index },
{ path:"/details", component: details },
{ path:"/login", component: login },
]
4. 创建一个路由器对象: (router 路由器)(真正实现路由切换的人)
什么是: 专门监视地址栏中的变化,根据变化,在路由字典中查找对应的组件,用组件替换页面中占位符的位置。实现页面切换。
01:js的数据类型有哪些
原始类型 :
布尔型:boolean
数值型:number
字符串 :string
null
undefind
引用类型:对象Object,数组Array,函数:Function,正则RegExp,日期Date
02:如何判断一个变量属于哪种类型
在这里插入代码片
03:typeof和instanceof的区别
typeof 检测数据类型 执行后会返回一个小写字母的类型字符串
Undefind Null Boolean String Number
typeof(nan) /number
instanceof 检测对象之间的关联性
例子、实例(..的实例,...的例子)
a=new Number(999);
console.log(a instanceof Number); //true;
a=new String('333');
console.log(a instanceof String); //true
b= [4,3,4];
console.log(b instanceof Array); //true
d=new Object();
console.log(d instanceof Object); //true
左边需要是引用类型的值(数组、对象和用new创建的新函数)
作用:
typeof:检测数据类型
instanceof:检测对象之间的关联性
返回:
typeof:小写字母字符串
instanceof:布尔值
操作数:
typeof:简单数据类型、函数或者对象
instanceof:左边必须是引用类型,右边必须是函数
操作数量
typeof:1
instanceof:2
04::使用过es6的哪些新特性
01:let和const
let和const关键字:用于声明块级作用域的变量和常量
02:箭头函数
03:模板字符串
04:参数解构
05:扩展运算符...(对象和数组的扩展操作符:简化对象和数组的操作)
06:Promise:用于异步编程,更加优雅的处理回调函数。
07:类和继承:更加面向对象的编程方式。
08:模块化:用于将代码划分为各个模块,便于维护和复用。
05:说说你对js作用域的理解
作用域:函数的范围
函数作用域和全局作用域
06:说说你对闭包的理解
什么是: 即重用一个变量,又保护变量不被篡改
为什么:
全局变量: 优: 可重复使用。缺: 易被污染。
局部变量: 优: 仅函数内可用。缺: 不可重用。
何时: 当一个函数需要拥有一个可重用的专属的变量时
如何: 给函数和变量找一个共同的父母函数
3步:
1. 定义外层函数包裹内层函数和要保护的变量
问题: 原来全局的函数,现在变成局部的函数了,外边用不了了
2. 外层函数将内层函数抛出到外部!
问题: 外层函数如果不调用,是不执行的
3. 使用者调用外层函数,获得外层函数返回的内层函数保存在变量中。
结果: 使用者可反复调用保存在变量中的内层函数
function parent(){
//包 红包
var total=1000;//要保护的变量
//2. 外层函数将内层函数返回到外部
//生 一个孩子
return function(money){//内层函数
total-=money;
document.write(`本次花了${money}元,还剩${total}元<br>`)
}
}
//3. 使用者调用外层函数,返回内层函数的对象,使用者用自定义的变量接住返回的内层函数对象。
var child=parent();
/*child:function(money){
total-=money;
document.write(`本次花了${money}元,还剩${total}元<br>`)
}*/
total=0;
child(100);//剩900
child(100);//剩800
问题: 全局没有total=1000,内层函数也没有total=1000,total保存在哪儿了?又是怎么被重复使用的?
鄙视: 闭包如何形成:
外层函数parent调用后,外层函数的作用域被内层函数引用着,无法释放。
外层函数的作用域,因为是保存在内层函数的私密的scopes通讯录里,所以外人都不知道!且通过全局,绝对无法修改
01:如何产生闭包:
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
02:闭包到底是什么:
使用chrome调试查看;
闭包是嵌套的内层函数(绝大部分人)
闭包存在于嵌套的内部函数中
03:产生闭包的条件
函数嵌套
内部函数引用了外部函数的数据(变量/函数)
常见的闭包
1:将函数作为实参传递给另一个函数调用
function shwoDeay(msg,time){
setTimeout(function(){
alert(msg):
},time)
}
showDeay('11',2000);
闭包的作用
1.函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
2.让函数外部可以操作(读写)到函数内部的数据(变量/函数)
问题:函数执行完后,函数内部声明的局部变量是否还存在?
一般是不存在,存在于闭包中的会存在
在函数外部能直接访问函数内部的局部变量吗?
不能,但是通过闭包让外部操作它
闭包的生命周期
产生:执行完函数定义,创建完内部函数对象后就产生了()
死亡:在嵌套的内部函数成为垃圾对象时
2:将函数作为另一个函数的返回值
function fn1(){
//此时闭包就已经产生了(函数提升,内部函数对象已经创建了)
var a=2;
function fn2(){
a++;
console.log(a)
}
return fn2
}
var f=fn1();
f(); //3
f(); //4
f=null //闭包死亡(死亡原因:包含闭包的函数对象,成为了垃圾对象)
// fn1() 就会在产生一个闭包
//创建函数对象产生闭包 创建了一个闭包(创建外部函数的时候,才会创建内部函数对象,和内部函数执行几次没有关系)
//外部函数执行了几次,闭包就创建了几个
07:js中的深拷贝?实现一个深拷贝
08:说说你对this关键字的理解
09:call apply bind的作用以及区别
vuex
概念:
在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
何时使用:
多个组件需要共享数据时
准备actions对象——响应组件中用户的动作
准备mutations——用于操作数据(state)
准备state——用于存储数据
准备getters——用于将state中的数据进行加工(当state中的数据需要经过加工后再使用时,可以使用getters加工。)
组件中读取vuex中的数据:$store.state.sum
组件中修改vuex中的数据:
$store.dispatch('action中的方法名',数据)
$store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写```dispatch```,直接编写```commit```
路由
1. 理解: 一个路由(route)就是一组映射关系(key - value),
2. 多个路由需要路由器(router)进行管理。
3. 前端路由:key是路径,value是组件。
active-class可配置高亮样式
<router-link active-class="active" to="/about">About</router-link>
1. 路由组件通常存放在```pages```文件夹,一般组件通常存放在```components```文件夹。
2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
3. 每个组件都有自己的```$route```属性,里面存储着自己的路由信息。
4. 整个应用只有一个router,可以通过组件的```$router```属性获取到。