1.vue的生命周期
组件创建期间的四个生命周期函数:
beforeCreate 实例初始化之后,this指向创建的实例,不能访问到data、computed、watch、methods上的方法和数据,常用于初始化非响应式变量。
created 实例创建完成,可访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到$el属性,$ref属性内容为空数组,常用于简单的ajax请求,页面的初始化。
beforeMount 在挂载开始之前被调用,页面中的元素,还没有真正的替换过来,只是之前的一些模板字符串,如{{}}中的data中的数据并不能调用,只会显示字符串。
mounted 实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。用户已经可以看到渲染好的页面,是实例创建期间最后一个生命周期函数,执行完mounted就表示,实例已经被完全创建好了。
组件运行周期的生命周期函数:
beforeupdate 表示界面还没有被更新,但是数据(data)已经更新了,执行时,页面显示数据还是旧的数据,此时data已经更新,页面上的数据暂时未和data保持同步。
updated 事件执行的时候,页面 data数据已经保持同步了,都是最新的。
组件销毁的生命周期函数:
beforeDestroy 钩子函数时,vue实例就已经从运行阶段进入了销毁阶段,实例身上所有的data和所有的methods,以及过滤器,指令都是处于可用状态,还没有被完全销毁。
destroyed 组件已经被完全销毁了,此时组件中所有的数据、方法、指令、过滤器都无法使用。
2.如何封装axios
https://zhuanlan.zhihu.com/p/32734197
这个知乎网站查看
3.vue-router的钩子函数
1.vue router.beforeEach(全局前置守卫)
beforeEach的钩子函数,他是一个全局的before钩子函数,(beforeeach)意思是在每次每一个路由改变时都执行一次。
它的三个参数:
to:(router路由对象)即将要进入的目标路由对象to对象下面的属性: path params query hash...
from:(router路由对象)当前导航正要离开的路由
next:(function函数)一定要调用该方法来resolve这个钩子。
next(无参数的时候):进行管道中的下一个钩子,如果走到最后一个钩子函数,那么导航的状态就是confirmed(确认的)
next('/')或者next({path:'/'}):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
4.vue项目上线后出现白屏的情况怎么处理
第一种:由于把路由模式mode设置成了history了,默认是hash.
解决办法:路由里面router/index.js路由配置里面默认模式是hash,如果改成了history模式的话,打开也会是一片空白。所以改为hash或者直接把模式配置删除,让它默认的就行。如果非要使用history模式的话,需要你在服务端加一个覆盖所有的情况的候选资源;如果url匹配不到任何静态资源,则应该返回一个index.html,这个页面就是你项目的依赖页面。
第二种:打包后的dist目录下的文件引用路径不对,会因找不到文件而报错导致白屏。
解决办法:修改一下config下面的index.js中build模块导出的路径。因为index.HTML里面的内容都是通过script标签引入的,而前面的路径不对,打开肯定是空白的。
第三种:在项目中使用了es6的语法,一些浏览器不支持es6,造成编译错误不能解析而造成白屏
解决方法:1.安装npm install --save-dev babel-preset-es2015
2.安装 npm install --save-dev babel-preset-stage-3
3.在项目根目录创建一个.babelrc文件 里面内容 最基本配置是:
{
// 此项指明,转码的规则
"presets": [
// env项是借助插件babel-preset-env,下面这个配置说的是babel对es6,es7,es8进行转码,并且设置amd,commonjs这样的模块化文件,不进行转码
["env", { "modules": false }],
// 下面这个是不同阶段出现的es语法,包含不同的转码插件
"stage-2"
],
// 下面这个选项是引用插件来处理代码的转换,transform-runtime用来处理全局函数和优化babel编译
"plugins": ["transform-runtime"],
// 下面指的是在生成的文件中,不产生注释
"comments": false,
// 下面这段是在特定的环境中所执行的转码规则,当环境变量是下面的test就会覆盖上面的设置
"env": {
// test 是提前设置的环境变量,如果没有设置BABEL_ENV则使用NODE_ENV,如果都没有设置默认就是development
"test": {
"presets": ["env", "stage-2"],
// instanbul是一个用来测试转码后代码的工具
"plugins": ["istanbul"]
}
}
}
然后重启npm run dev 你会发现,可以在其他低版本浏览器跑了,基本兼容所有浏览器,ie8以下除外。而且大多数的手机浏览器也ok。重新打包到正式环境也正常。
5.token值的应用,存储在什么地方
token可以存在 Storage (localStorage sessionStorage cookie )。这些基本上支持H5的浏览器对这个本地储存都兼容。如果您是IE678之类的,建议存cookie。
Storage的localStorage长期有效,sessionStorage关闭浏览器时会自动清除
cookie的可以设置有效期。
在做登录界面时代码如下:
登录页面(login.vue)
代码语言:javascript复制methods: {
handleLogin (data) {
api.AuthResource.save(data).then(response => {
if (!response.ok) {
console.log('登录失败')
}
const token = response.data.token
window.localStorage.setItem('token', token)
window.location.pathname = '/'
}, response => {
console.log('登录失败')
})
}
}
接口配置(api.js)
代码语言:javascript复制 Vue.http.interceptors.push((request, next) => {
if (window.localStorage.getItem('token')) {
Vue.http.headers.common['Authorization'] = 'Bearer ' window.localStorage.getItem('token')
}
next((response) => {
if (response.status === 401) {
del('token')
window.location.pathname = '/login'
}
})
})
配置路由(router.js)
代码语言:javascript复制import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
component: require('./views/Home'),
meta: {
requiresAuth: true
}
},
]
const router = new VueRouter({
routes: routes
})
router.beforeEach((to, from, next) => {
let token = window.localStorage.getItem('token')
if (to.matched.some(record => record.meta.requiresAuth) && (!token || token === null)) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
})
export default router
原理是通过vue-router的beforeEach钩子,在每次路由到一个地址的时候先判断该路由是否携带了meta信息,且该信息中的requireAuth是否为true,如果为true表示该路由是需要身份验证的。则去localStorage找token,若token不存在则表示用户未认证,去登录请求token。若token存在则拿着token去请求。
6.vue路由的说明以及应用
路由中有三个基本的概念 route, routes, router。
1, route,它是一条路由,由这个英文单词也可以看出来,它是单数, Home按钮 => home内容, 这是一条route, about按钮 => about 内容, 这是另一条路由。
2, routes 是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, { about按钮 => about 内容}]
3, router 是一个机制,相当于一个管理者,它来管理路由。因为routes 只是定义了一组路由,它放在哪里是静止的,当真正来了请求,怎么办?就是当用户点击home 按钮的时候,怎么办?这时router 就起作用了,它到routes 中去查找,去找到对应的 home 内容,所以页面中就显示了 home 内容。
4,客户端中的路由,实际上就是dom 元素的显示和隐藏。当页面中显示home 内容的时候,about 中的内容全部隐藏,反之也是一样。客户端路由有两种实现方式:基于hash 和基于html5 history api.
7. 跨域问题的解决
1)后台更改header:
代码语言:javascript复制 header('Access-Control-Allow-Origin:*');//允许所有来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
2)使用jQuery提供的jsonp:
代码语言:javascript复制methods: {
getData () {
var self = this
$.ajax({
url: 'http://f.apiplus.cn/bj11x5.json',
type: 'GET',
dataType: 'JSONP',
success: function (res) {
self.data = res.data.slice(0, 3)
self.opencode = res.data[0].opencode.split(',')
}
})
}}
3)使用http-proxy-middleware代理解决(项目需要使用到vue-cli脚手架搭建)
比如请求url:"http://f.apiplus.cn/bj11x5.json"
1.打开config/index.js,在Proxytype中添加如下代码:
代码语言:javascript复制 proxyTable: {
'/api': { //使用"/api"来代替"http://f.apiplus.c"
target: 'http://f.apiplus.cn', //源地址
changeOrigin: true, //改变源
pathRewrite: {
'^/api': 'http://f.apiplus.cn' //路径重写
}
}
}
2.使用axios请求数据时直接使用“/api”
代码语言:javascript复制 getData () {
axios.get('/api/bj11x5.json', function (res) {
console.log(res)
})
8、vuex是什么?怎么使用?哪种功能场景使用它?
答:vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,….. export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
9、mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?
答:一个model view viewModel框架,数据模型model,viewModel连接两个
区别:vue数据驱动,通过数据来显示视图层而不是节点操作。
场景:数据操作比较多的场景,更加便捷
10、自定义指令(v-check、v-focus)的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?
答:全局定义指令:在vue对象的directive方法里面有两个参数,一个是指令名称,另外一个是函数。组件内定义指令:directives
钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新)
钩子函数参数:el、binding
11、Vue的双向数据绑定原理是什么?
12、vue如何实现父子组件通信,以及非父子组件通信?
可以通过props属性来实现
父组件:
//这里必须要用 - 代替驼峰
data(){ return { msg: [1,2,3] }; }
子组件通过props来接收数据: 方式1:
props: ['childMsg']
方式2 :
props: { childMsg: Array //这样可以指定传入的类型,如果类型不对,会警告 }
方式3:
props: { childMsg: { type: Array, default: [0,0,0] //这样可以指定默认的值 } }
这样呢,就实现了父组件向子组件传递数据。
可以通过eventHub来实现通信. 所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件.
let Hub = new Vue(); //创建事件中心
组件1触发:
methods: { eve() { Hub.$emit('change','hehe'); //Hub触发事件 } }
组件2接收:
created() { Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }
这样就实现了非父子组件之间的通信了.原理就是把Hub当作一个中转站!
13. Vue中插槽-----特殊特性slot、slot-scope与指令v-slot的使用方法
https://blog.csdn.net/qq_40616529/article/details/94033417
14、说说你对 SPA 单页面的理解,它的优缺点分别是什么?
15、组件中 data 为什么是一个函数?
【更多扩展】30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度) -- 基础必须掌握
https://blog.csdn.net/xu_song/article/details/102861394