1 对于MvvM的理解?
MVVM是Model_View_ViewModel的缩写
Model: 是数据模型,可以在Model中定义数据修改和操作的业务逻辑。
View: 是UI组件,它负责将数据转化成UI展示出来。
ViewMode: 是同步View和Model的对象,连接View和Model ,监听模型数据的改变和控制视图行为,和处理用户交互。
在MVVM架构下,View和Modal之间并没有直接的联系,而是通过ViewModel进行交互,Model和ViewModel之间的交互式双向的,因此View数据的变化会同步到Model中,而Model数据的变化也会立即反应到View上。
2 Vue的生命周期
beforeCreate: 在数据观测和初始化事件还未开始。
created: 完成数据观测,属性和方法的运算,初始化事件,el属性还没有显示出来
beforeMount: 在挂载开始之前被调用,相关的render函数首次被调用,实例已完成下的配置: 编译模板,把data里面的数据和模板生成html,注意此时还没有挂载html到页面上
mounted: 在el被新创建的vm.$el替换,并挂载到实例上去之后调用,实例已完成以下的配置: 用上面编译好的html内容替换el属性指向的DOM的对象,完成模板中的html渲染到html页面中,此过程中进行ajax交互。
beforeUpdate: 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步更改状态,不会触发附加的重渲染的过程。
updated: 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用,调用时,组件的DOM已经更新,所以可以执行依赖于DOM的操作,然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致无限循环,在服务器渲染期间不被调用。
beforeDestroy: 在实例销毁之前调用,实例仍然完全可用。
destroy: 在实例销毁之后调用,调用后,所有的事件监听器会被移除掉,所有的子实例也会被销毁,在服务器端渲染期间不能被调用。
3 什么事vue生命周期?
Vue实例从创建到销毁的过程,就是生命周期,从开始创建,初始化数据,编译模板,挂载Dom--->渲染、更新--->渲染、销毁等系列过程,称之为Vue的生命周期
4 vue生命周期的作用是什么?
它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程是更容易形成好的逻辑。
5 第一次页面加载会触发哪几个钩子?
会触发下面beforeCreate、created、beforeMount、mounted。
6 vue生命周期总共有几个阶段?
它可以总共分为8个阶段:创建前/后 载入前/后 更新前/后 销毁前/后。
7 DOM渲染在哪个周期就已经完成了?
DOM渲染在mounted中就已经完成了。
8 Vue实现数据双向绑定的原理: Object.defineProperty()
vue实现数据的双向绑定主要是: 采用数据劫持+发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时候发布消息给订阅者,触发相应的监听回调,打把一个js对象传给Vue实例作为它的data选项时,Vue将遍历它的属性,用Object.defineProperty()将他们转为getter/setter,用户是看不到这个getter/setter,但是内部他们让Vue追踪依赖,在属性被访问和修改时候通知变化。
vue的数据双向绑定将mvvm作为数据入口,结合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭建起Observer和Compile的之间的通信,达到数据变化->视图更新;视图(input)变化->数据model变更的双向绑定的效果。
9 Vue组件间的参数传递
父组件传给子组件: 子组件通过props方法接受数据;
props: {
userInfo: {
type: Object,
required: true,//必须传入
default: function(){
return {
age: 18
}
}
}
}
子组件传给父组件: $emit方法传递参数;
平行组件传值: vuex, eventBus;
10 Vue的路由实现: hash模式和history模式
hash模式: 浏览器地址栏#号,以及#后面字符称之为hash,用window.location.hash读取,不被包括在http请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
history模式:history采用HTML5的新特性,提供两个方法:pushState(), replaceState() 可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
11 Vue路由的钩子函数
首页可以控制导航跳转,beforeEach, afterEach等,一般用于页面title的修改,一些需要登录才能调整页面的重定向功能。
beforeEach: 主要有3个参数to,from,next。
to:route即将进入的目标路有对象。
from:route当前导航正要离开的路由。
next:function一定要调用该方法resolve这个钩子,执行效果依赖next方法的调用参数,可以控制页面的跳转。
12 vuex是什么?怎么使用?哪种功能场景使用它?
只用来读取的状态集中放在store中,改变状态的方式是提交mutations,这个是同步事件,异步逻辑封装在action中
在main.js引入store,注入。
场景有:单页面应用中,组件之间的状态,音乐播放,登录状态,加入购物车。
state: Vuex使用单一状态树,即每个应用只能包含一个store实例,但单一状态树和模块化并不冲突,存放的数据状态,不可以直接修改里面的数据。
mutations:mutaions定义的方法动态修改Vuex的store中的状态或数据。
getters:类似vue的计算属性,主要来过滤一些数据。
action: actions可以理解通过将mutations里面处理数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据,view层通过store.dispatch来分发action
const store = new Vuex.Store({
//store实例
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
13 其他小知识点
1. css只在当前组件起作用?
在style标签中写入scoped 例如:
<style scoped></style>
2. v-if和v-show区别?
v-if按照条件是否渲染,v-show是display的block或者none;
3. router区别?
router是’路由实例‘对象包括了路由的跳转方法和钩子函数等。
全局注册过滤器 在main.js中
import vfilter from "./api/js/vfilter.js"//全局配置过滤器
for (let key in vfilter) {
Vue.filter(key, vfilter[key])
}
//配置过滤器vfilter.js文件
const vfilter = {
stringfilter(val) {
if (val == "" || val == undefined || val == null) {
return null;
} else {
return val;
}
},
timefilter(val) {//事件过滤器
var dateTime = new Date(val);
var year = dateTime.getFullYear();
var month = dateTime.getMonth() + 1;
var day = dateTime.getDate();
var hour = dateTime.getHours();
var minute = dateTime.getMinutes();
var second = dateTime.getSeconds();
var now = new Date();
var now_new = new Date().getTime(); //typescript转换写法
var milliseconds = 0;
var timeSpanStr;
milliseconds = now_new - val;
if (milliseconds <= 1000 * 60 * 1) {
timeSpanStr = '刚刚';
}
else if (1000 * 60 * 1 < milliseconds && milliseconds <= 1000 * 60 * 60) {
timeSpanStr = Math.round((milliseconds / (1000 * 60))) + '分钟前';
}
else if (1000 * 60 * 60 * 1 < milliseconds && milliseconds <= 1000 * 60 * 60 * 24) {
timeSpanStr = Math.round(milliseconds / (1000 * 60 * 60)) + '小时前';
}
else if (1000 * 60 * 60 * 24 < milliseconds && milliseconds <= 1000 * 60 * 60 * 24 * 15) {
timeSpanStr = Math.round(milliseconds / (1000 * 60 * 60 * 24)) + '天前';
}
else if (milliseconds > 1000 * 60 * 60 * 24 * 15 && year == now.getFullYear()) {
timeSpanStr = month + '-' + day + ' ' + hour + ':' + minute;
} else {
timeSpanStr = year + '-' + month + '-' + day + ' ' + hour + ':' + minute;
}
return timeSpanStr;
},
/**
* 时间格式化
* @param {*} date
* @param {*} fmt
* 用法: formatDate(new Date(), 'yyyy-MM-dd hh:mm')
* 用法: formatDate(new Date(time), 'yyyy-MM-dd')
* {{new Date()|formatDate('yyyy-MM-dd hh:mm')}}
*/
formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
};
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + '';
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : ('00' + str).substr(str.length));
}
}
return fmt;
}
}
export default vfilter;
网友评论