Ⅰ vue-lazyload 源码解析
/src/lazy.js
定义变量接收实例化参数。
lazy.js 默认导出一个函数,该函数返回一个 Lazy 类,形成闭包,保持对 Vue 的引用。
判断是否支持Webp图片
/src/listener.js
定义变量接收实例化参数。
filter 方法将配置的 filter 对象中的方法执行,接收两个参数,一个为 ReactiveListener 实例,一个为 options 参数对象。
initState 方法给元素添加 data-set 属性,值为图片地址 src,并且定义了图片状态对象 state 。在 Lazy 中已经根据像素比选择了最适配屏幕的图片,顾这里不需要考虑 srcset 属性。另外,我们自定义指令是 v-lazy,到目前为止,还没有给图片的 src 属性赋值。
render 方法,是在 Lazy 中实例化 ReactiveListener 时传递过来的参数。
回过头再来结合 lazy.js 中的 lazyLoadHandler 方法与 ReactiveListener 暴露的方法来看。
/src/lazy-container.js
LazyContainer 的核心是 container 下的选择器selector(默认 img 标签)遍历后调用 lazy 的 add 方法进行绑定,自定义指令 v-lazyload-container。
/src/lazy-component.js
上述实现元素绑定主要是通过自定义指令 v-lazy , v-lazy-container 。那么 LazyComponent 则是通过注册的 lazy-component 组件,完成绑定,默认渲染成为 div 标签,作为 img 的容器。
/src/lazy-image.js
通 LazyComponent 组件,只不过 LazyImage 注册的 lazy-image 组件,渲染成的是 img 标签,多了 src 属性。
通过自定义指令 v-lazy 将设置背景图的元素或者 img元素,通过 _addListenerTarget 方法收集与数组 TargetQueue 中,并遍历触发懒加载的方法, addEventListener 绑定在该元素上,触发的事件为 lazyLoadHandler ;
在需要懒加载的元素上设置属性 data-src ,这是期望的图片地址(filter 配置项可以预先过滤赋值),元素上自定义 lazyLoad 表示图片状态(状态变更后,adapter 中触发回调);
ListenerQueue 数组中收集的是 ReactiveListener 类的实例,主要是用于懒加载不同状态下的图片加载,loading - loaded - error;
当触发 EventListener 了,执行 lazyLoadHandler 方法,根据算法,进入 viewport 后, ReactiveListener 元素如果与触发元素匹配,则进行图片的加载及渲染。
Ⅱ 【面试题解析】从 Vue 源码分析 key 的作用
最近看了面试题中有一个这样的题, v-for 为什么要绑定 key?
Vue 中 key 很多人都弄不清楚有什么作用,甚至还有些人认为不绑定 key 就会报错。
其实没绑定 key 的话,Vue 还是可以正常运行的,报警告是因为没通过 Eslint 的检查。
接下来将通过源码一步步分析这个 key 的作用。
Virtual DOM 最主要保留了 DOM 元素的层级关系和一些基本属性,本质上就是一个 JS 对象。相对于真实的 DOM,Virtual DOM 更简单,操作起来速度更快。
如果需要改变 DOM,则会通过新旧 Virtual DOM 对比,找出需要修改的节点进行真实的 DOM 操作,从而减小性能消耗。
传统的 Diff 算法需要遍历一个树的每个节点,与另一棵树的每个节点对比,时间复杂度为 O(n²)。
Vue 采用的 Diff 算法则通过逐级对比,大大降低了复杂性,时间复杂度为 O(n)。
VNode 更新首先会经过 patch 函数, patch 函数源码如下:
vnode 表示更新后的节点,oldVnode 表示更新前的节点,通过对比新旧节点进行操作。
1、vnode 未定义,oldVnode 存在则触发 destroy 的钩子函数
2、oldVnode 未定义,则根据 vnode 创建新的元素
3、oldVnode 不为真实元素并且 oldVnode 与 vnode 为同一节点,则会调用 patchVnode 触发更新
4、oldVnode 为真实元素或者 oldVnode 与 vnode 不是同一节点,另做处理
接下来会进入 patchVnode 函数,源码如下:
1、vnode 的 text 不存在,则会比对 oldVnode 与 vnode 的 children 节点进行更新操作
2、vnode 的 text 存在,则会修改 DOM 节点的 text
接下来在 updateChildren 函数内就可以看到 key 的用处。
key 的作用主要是给 VNode 添加唯一标识,通过这个 key,可以更快找到新旧 VNode 的变化,从而进一步操作。
key 的作用主要表现在以下这段源码中。
updateChildren 过程为:
1、分别用两个指针(startIndex, endIndex)表示 oldCh 和 newCh 的头尾节点
2、对指针所对应的节点做一个两两比较,判断是否属于同一节点
3、如果4种比较都没有匹配,那么判断是否有 key,有 key 就会用 key 去做一个比较;无 key 则会通过遍历的形式进行比较
4、比较的过程中,指针往中间靠,当有一个 startIndex > endIndex,则表示有一个已经遍历完了,比较结束
从 VNode 的渲染过程可以得知,Vue 的 Diff 算法先进行的是同级比较,然后再比较子节点。
子节点比较会通过 startIndex、endIndex 两个指针进行两两比较,再通过 key 比对子节点。如果没设置 key,则会通过遍历的方式匹配节点,增加性能消耗。
所以不绑定 key 并不会有问题,绑定 key 之后在性能上有一定的提升。
综上,key 主要是应用在 Diff 算法中,作用是为了更快速定位出相同的新旧节点,尽量减少 DOM 的创建和销毁的操作。
希望以上内容能够对各位小伙伴有所帮助,祝大家面试顺利。
Vue 的文档中对 key 的说明如下:
关于就地修改,关键在于 sameVnode 的实现,源码如下:
可以看出,当 key 未绑定时,主要通过元素的标签等进行判断,在 updateChildren 内会将 oldStartVnode 与 newStartVnode 判断为同一节点。
如果 VNode 中只包含了文本节点,在 patchVnode 中可以直接替换文本节点,而不需要移动节点的位置,确实在不绑定 key 的情况下效率要高一丢丢。
某些情况下不绑定 key 的效率更高,那为什么大部分Eslint的规则还是要求绑定 key 呢?
因为在实际项目中,大多数情况下 v-for 的节点内并不只有文本节点,那么 VNode 的字节点就要进行销毁和创建的操作。
相比替换文本带来的一丢丢提升,这部分会消耗更多的性能,得不偿失。
了解了就地修改,那么我们在一些简单节点上可以选择不绑定 key,从而提高性能。
如果你喜欢我的文章,希望可以关注一下我的公众号【前端develop】
Ⅲ 慕课网上没搜到vue源码,有没有课程透彻分析Vue 源码的
有,你在实战里找是huangyi讲的,印象中是从 Vue 的跨平台编译入手,从 Vue 的几个核心能力开始分析Vue 源码。 Vue 的静态全局 API 与属性, Vue 的响应式原理,异步组件、组件化、diff 算法等等方面,都是进行了详细的分析,最后还附带了vuex和vuerouter。
Ⅳ vuejs源码用了什么设计模式,具体点的
最简单的订阅者模式
// Observer
class Observer {
constructor (data) {
this.walk(data)
}
walk (data) {
// 遍历
let keys = Object.keys(data)
for(let i = 0; i < keys.length; i++){
defineReactive(data, keys[i], data[keys[i]])
}
}
}
function defineReactive (data, key, val) {
observer(val)
// dep 为什么要在这里实例化, 就是为了实现, 对象每一层的 每一个key都有自己的一个订阅实例, 比如 a.b 对应 dep1, a.c 对应dep2, 这里虽然都是let dep = new Dep()
// 但每次来到这个方法, dep都是独立的, 会一直保留在内存. 这样在每次调用set方法都能找到这个a.b对应的dep
// dep 这里会一直保存, 是因为闭包的关系, Object这个全局的函数, 引用了上层的作用域, 这个作用域包含了 dep, 除非Object = null, 或者退出浏览器, dep才会消失
//实例化之后, dep就有了被订阅, 和发布消息的功能, dep不写在这里也是可以的, 多定义一个全局函数, 每次obser的时候增加一个dep
let dep = new Dep()
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function () {
//每次new Watch('a.b'), 都会先执行get方法, 进而来到这里, 触发 dep.depend(), 这个dep就是 a.b 对应的 订阅,
dep.depend()
return val
},
set: function (newVal) {
if(val === newVal){
return
Ⅳ vue项目实现动态路由和动态菜单搭建插件式开发框架免费源码
以往我们在开发vue项目的时候,总是通过将路径和路由写在route/index.js文件中,然后直接进行访问即可,一般实现权限匹配都是通过菜单下面的权限参数和路由守卫进行一个验证拦截和权限匹配,然而这样安全性仍然不足。因为我们在route/index.js中已经写满了所有的路由,这样子不仅造成静态路由内容过多、修改困难,同时当静态路由内容过多的时候,我们在路由中的内容就显得极其复杂。
而后端对前端的控制也显得较为无力,无法实现严格性的控制。
由此我们发现通过动态路由控制是必然的,此时我们只需要通过后端获取数据菜单和路由信息json,然后动态添加路由并生成菜单,使菜单与动态路由内容进行一个匹配,这样子我们可以实现由后端控制前端的菜单和路由,我们的项目往往只需要内置几个组件无需权限的公共页面如登陆、注册、忘记密码和404错误这几个常用页面组件。
我们只需要将写好的组件放置到我们的view视图下,然后我们通过动态的路由和菜单实现路由添加和菜单进行匹配,我们便可实现对插件进行访问,我们减少了对route/index.js内容写入,同时也有利于减少内存的占用。
我们通过动态路由的形式,我们生成的菜单权限更加的完善,不仅实现依靠菜单与路由守卫拦截实现鉴权,也可以通过动态路由实现动态加载vue文件,控制更加深度
我们通过动态路由的形式,我们可以将项目分给不同的人进行完成,便于组建一个开发团队,因为他们所开发的组件,我们只需要在具备基本的javascript库的情况下。我们直接进行动态路由的一个挂载和菜单生成便可完成项目合作,减少了对route/index.js文件的操作,保证项目的完整性。
最后我发现在非node环境的开发条件下,我们可以实现远程的vue文件加载,这不仅为我们开发提供了便利,同时也有利于我们及时修改文件,以达到项目的需求,更有利于保障安全,实现服务器vue文件加载。
Vue:2.6.11。
Vue-route:3.2.0。
主页
聊天
第一通过后端返回的一个路由json数据,我们通过前端生成符合路由路由静态内容数组的一个数组,然后再通过addRoute进行一个循环添加,我们以此生成动态路由。在登陆时获取后端返回的菜单信息,我们进行菜单的一个循环生成,由此我们的一个动态项目就已经完成。
第二怎样对动态路由和菜单项目进行一个管理。
我们首先可以通过搭建一个组件通过添加路由信息和管理菜单实现二者的动态匹配。我们只需要对路由信息进行一个添加和修改,并和菜单相互间进行匹配,我们便可实现简单的路由挂载。
组件管理
菜单管理
此时将数据提交的后端由后端进行数据保存,我们此时的组件只需要放在views文件夹下,添加路由进行文件加载,我们便可实现路由管理。
第一登陆页面配置。
我们需要在静态文件夹下创建一个menu.json和route.json。两个json文件模拟服务器登录时返回的数据。
我们在登录页面模拟获取数据之后,我们通过菜单的一个方法进行生成菜单,通过路由的方法生成路由数组并进行循环添加,然后执行路由跳转。
第二配置路由初始化内容。我们将route/index.js的路由信息填为空是非常不理智的,而且会报错,因为路由初始化在加载前已经完成。有些页面完全不需要权限便可访问,比如登录、注册、找回密码和404错误,这种不需要权限的页面,我们还是需要将其直接以静态的形式写在route/index.js文件中。
Index初始数据
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue . use ( VueRouter )
const routes = [{
path: '/' , //访问url
name: 'login' , //路由名称
component : () => import ( '@/unitui/pages/Login.vue' ), //加载模板文件
meta: {
show_site: 0 , //是否全屏显示
web_title: "登录" //网站标题
}
},
{
path: '/register' , //访问url
name: 'register' , //路由名称
component : () => import ( '@/unitui/pages/Register.vue' ), //加载模板文件
meta: {
show_site: 0 , //是否全屏显示
web_title: "注册" //网站标题
}
},
{
path: '/forget' , //访问url
name: 'forget' , //路由名称
component : () => import ( '@/unitui/pages/Forget.vue' ), //加载模板文件
meta: {
show_site: 0 , //是否全屏显示
web_title: "找回密码" //网站标题
}
},
{
path: '/404' , //访问url
name: '404' , //路由名称
component : () => import ( '@/unitui/pages/404.vue' ), //加载模板文件
meta: {
show_site: 0 , //是否全屏显示
web_title: "404错误" //网站标题
}
},
]
const router = new VueRouter ({
routes
})
router . beforeEach (( to , from , next ) => {
document . title = to . meta . web_title
console . log ( to );
next ()
})
export default router
第三,关于防止刷新后丢失的问题。我们需要在app.vue文件中的methods方法中定义一个路由生成方法。
示例:
init_route () { //初始化路由,防止刷新丢失
if ( sessionStorage . getItem ( "route_data" ) != null ) { //只有后端已经返回数据的情况下才允许生成
const route_data = JSON . parse ( sessionStorage . getItem ( "route_data" )); //获取路由信息
const data = []; //默认路由数组
for ( let index = 0 ; index < route_data . length ; index ++) { //生成路由信息
data [ index ] = {
path: route_data [ index ]. path , //访问url
name: route_data [ index ]. name , //路由名称
component : resolve =>
require ([ `@/views/ ${ route_data [ index ]. component } ` ], resolve ), //加载模板文件
meta: {
show_site: route_data [ index ]. meta . show_site , //是否全屏显示
web_title: route_data [ index ]. meta . web_title //网站标题
}
};
}
for ( let index = 0 ; index < data . length ; index ++) { //循环添加路由
this . $router . addRoute ( data [ index ]);
}
}
}
在mounted中进行方法调用,防止刷新的时路由丢失,导致发生错误。该方法内容基本和登陆页面的菜单出路由初始内容基本相同,但我们唯一差别的是,我们需要判断登陆所获取的路由信息是否存在,只有在存在的时候及后端已经返回了路由信息,即证明登录成功的时候,我们才会动态添加路由。
第一在刷新之后,默认跳转到path:’*’的一个路由界面中去,此时我们解决方法只需要将path:’*’路由进行一个删除,将其删除就变可正常访问。
第二动态路由跳转时发生Cannot find mole xxx错误。
意思是无法加载我们指定的一个vue文件,这是由于route3.0版本后import方式不支持传入变量,此时我们只需要将其改为require方式便可。
我们此次动态vue项目开发已经基本完成,我的开发的项目是基于element-ui进行,那么如果你需要源码参考。可以私信回复unit便可获取。
Ⅵ 什么是vue框架
什么是vue
是一套构建用户界面的渐进式(用到哪一块就用哪一块,不需要全部用上)前端框架,Vue 的核心库只关注视图层
vue的兼容性
Vue.js 不支持 IE8 及其以下版本,因为 Vue.js 使用了 IE8 不能模拟的 ECMAScript 5 特性。 Vue.js 支持所有兼容 ECMAScript 5 的浏览器。
vue学习资源
vue.js中文官网:http://cn.vuejs.org/
vue.js源码:https://github.com/vuejs/vue
vue.js官方工具:https://github.com/vuejs
vue.js官方论坛:forum.vuejs.org
对比其他框架-React
React 和 Vue 有许多相似之处,它们都有使用 Virtual DOM;提供了响应式(Reactive)和组件化(Composable)的视图组件。将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。React 比 Vue 有更丰富的生态系统
都有支持native的方案,React的RN,vue的Wee下
都支持SSR服务端渲染
都支持props进行父子组件间的通信
性能方面:React 和 Vue 在大部分常见场景下都能提供近似的性能。通常 Vue 会有少量优势,因为 Vue 的 Virtual DOM 实现相对更为轻量一些。
不同之处就是:
数据绑定方面,vue实现了数据的双向数据绑定,react数据流动是单向的
virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制
state对象在react应用中不可变的,需要使用setState方法更新状态;在vue中,state对象不是必须的,数据由data属性在vue对象中管理(如果要操作直接this.xxx)
组件写法不一样, React推荐的做法是 JSX , 也就是把HTML和CSS全都写进JavaScript了,即'all in js'; Vue推荐的做法是webpack+vue-loader的单文件组件格式,即html,css,js写在同一个文件
对比其他框架-angular
在性能方面,这两个框架都非常的快,我们也没有足够的实际应用数据来下一个结论。如果你一定想看些数据的话,你可以参考这个第三方跑分。单就这个跑分来看,Vue 似乎比 Angular 要更快一些。
在大小方面,最近的 Angular 版本中在使用了 AOT 和 tree-shaking 技术后使得最终的代码体积减小了许多。但即使如此,一个包含了 vuex + vue-router 的 Vue 项目 (30kb gzipped) 相比使用了这些优化的 Angular CLI 生成的默认项目尺寸 (~130kb) 还是要小的多。
灵活性:Vue 相比于 Angular 更加灵活,Vue 官方提供了构建工具来协助你构建项目,但它并不限制你去如何组织你的应用代码。有人可能喜欢有严格的代码组织规范,但也有开发者喜欢更灵活自由的方式。
vue.js的核心特点—响应的数据绑定
传统的js操作页面:在以前使用js操作页面的时候是这样的,需要操作某个html元素的数据,就的使用js代码获取元素然后在处理业务逻辑
响应式数据绑定的方式操作页面,可以直接使用像下面代码那样的写法就可以将数据填充到页面中
<template>
<div id="app">
{{ message }}
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
message: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style>
</style>
vue.js的核心特点—可组合的视图组件
一个页面映射为组件树。划分组件可维护、可重用、可测试,也就是一个页面由多个组件组合而成
vue中实现组件引入示例
第一步:import导入需要引入的组件文件;
第二步:注册组件;
第三步:在需要引入组件的文件中加上组件标签(这个标签的标签名就是注册的组件名字,多个单词的和这里有xx-xx的形式)
需要注意的是:组件可以嵌套引入,也就是说组件可以引入其他组件
首先创建一个组件,用于被引入的组件,组件名字叫Hello.vue
————————————————
版权声明:本文为CSDN博主“胡椒粉0121”的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
Ⅶ 如何阅读Vuejs源码,学习笔记
# 下载最新的vue$ npm install vue
js 引用 vue.js
开始代码,感受vue强大的双向数据绑定
实战代码:
<divid="app"><inputv-model="newTodo"v-on:keyup.enter="addTodo"><ul><liv-for="todointodos"><span>{{todo.text}}</span><buttonv-on:click="removeTodo($index)">X</button></li></ul></div>newVue({el:'#app',data:{newTodo:'',todos:[{text:'Addsometodos'}]},methods:{addTodo:function(){vartext=this.newTodo.trim()if(text){this.todos.push({text:text})this.newTodo=''}},removeTodo:function(index){this.todos.splice(index,1)}}})Vue整个生命周期示意图:
Ⅷ 47道基础的VueJS面试题(附答案)
1、什么是MVVM框架?它适用于哪些场景?
MVVM框架是一个 Model-View-View Model框架,其中 ViewModel连接模型Model)和视图(View)。
在数据操作比较多的场景中,MVVM框架更合适,有助于通过操作数据渲染页面。
2、active- class是哪个组件的属性?
它是 vue-router模块的 router-link组件的属性。
3、如何定义Vue- router的动态路由?
在静态路由名称前面添加冒号,例如,设置id动态路由参数,为路由对象的path属性设置/:id。
4、如何获取传过来的动态参数?
在组件中,使用$router对象的 params.id,即 $route.params.id 。
5、vue- router有哪几种导航钩子?
有3种。
第一种是全局导航钩子:router.beforeEach(to,from,next)。作用是跳转前进行判断拦截。
第二种是组件内的钩子。
第三种是单独路由独享组件。
6、mint-ui是什么?如何使用?
它是基于 Vue.js的前端组件库。用npm安装,然后通过 import导入样式和JavaScript代码。vue.use(mintUi)用于实现全局引入, import {Toast} from ' mint-ui'用于在单个组件局部引入。
7、V-model是什么?有什么作用?
v- model是 Vue. js中的一条指令,可以实现数据的双向绑定。
8、Vue.js中标签如何绑定事件?
绑定事件有两种方式。
第一种,通过v-on指令, 。
第二种,通过@语法糖, input@ click= doLog()/>。
9、vuex是什么?如何使用?在哪种功能场景中使用它?
vuex是针对 Vue. js框架实现的状态管理系统。
为了使用vuex,要引入 store,并注入Vue.js组件中,在组件内部即可通过$ ostore访问 store对象。
使用场景包括:在单页应用中,用于组件之间的通信,例如音乐播放、登录状态管理、加入购物车等。
10、如何实现自定义指令?它有哪些钩子函数?还有哪些钩子函数参数?
自定义指令包括以下两种。
它有如下钩子函数。
钩子函数的参数如下。
11、至少说出vue.js中的4种指令和它们的用法。
相关指令及其用法如下。
12、Vue-router是什么?它有哪些组件?
它是 Vue. js的路由插件。组件包括 router-link和 router-vIew。
13、导航钩子有哪些?它们有哪些参数?
导航钩子又称导航守卫,又分为全局钩子、单个路由独享钧子和组件级钧子。
全局钩子有 beforeEach、beforeResolve(Vue2.5.0新增的)、 afterEach。
单个路由独享钩子有 beforeEnter。
组件级钩子有 beforeRouteEnter、 beforeRouteUpdate(Vue2.2新增的) beforeRouteLeave。
它们有以下参数。
14、Vue.js的双向数据绑定原理是什么?
具体步骤如下。
(1)对需要观察的数据对象进行递归遍历,包括子属性对象的属性,设置set和get特性方法。当给这个对象的某个值赋值时,会触发绑定的set特性方法,于是就能监听到数据变化。
(4)MVVM是数据绑定的入口,整合了 Observer、 Compile和 Watcher三者,通过Observer来监听自己的 model数据变化,通过 Compile来解析编译模板指令,最终利用Watcher搭起 Observer和 Compile之间的通信桥梁,达到数据变化通知视图更新的效果。利用视图交互,变化更新数据 model变更的双向绑定效果。
15、请详细说明你对Vue.js生命周期的理解。
总共分为8个阶段,分别为 beforeCreate、created、beforeMount、 mounted、beforeUpdate、 updated、 beforeDestroyed、 destroyed。
当使用组件的kep- alive功能时,增加以下两个周期。
Vue2.5.0版本新增了一个周期钩子:ErrorCaptured,当捕获一个来自子孙组件的错误时调用。
16、请描述封装Vue组件的作用过程。
组件可以提升整个项目的开发效率,能够把页面抽象成多个相对独立的模块,解决了传统项目开发中效率低、难维护、复用性等问题。
使用Vue.extend方法创建一个组件,使用Vue.component方法注册组件。子组件需要数据,可以在 props中接收数据。而子组件修改妤数据后,若想把数据传递给父组件,可以采用emit方法。
17、你是怎样认识vuex的?
vuex可以理解为一种开发模式或框架。它是对 Vue. js框架数据层面的扩展。通过状态(数据源)集中管理驱动组件的变化。应用的状态集中放在 store中。改变状态的方式是提交 mutations,这是个同步的事务。异步逻辑应该封装在 action中。
18、Vue- loader是什么?它的用途有哪些?
它是解析.vue文件的一个加载器,可以将 template/js/style转换成 JavaScript模块。
用途是通过 vue-loader, JavaScript可以写 EMAScript 6语法, style样式可以应用scss或less, template可以添加jade语法等。
19、请说出vue.cli项目的src目录中每个文件夹和文件的用法。
assets文件夹存放静态资源;components存放组件;router定义路由相关的配置;view是视图;app. vue是一个应用主组件;main.js是入口文件。
20、在Vue.cli中怎样使用自定义组件?在使用过程中你遇到过哪些问题?
具体步骤如下。
(1)在 components目录中新建组件文件,脚本一定要导出暴露的接口。
(2)导入需要用到的页面(组件)。
(3)将导入的组件注入uejs的子组件的 components属性中。
(4)在 template的视图中使用自定义组件。
21、谈谈你对vue.js的 template编译的理解。
简而言之,就是首先转化成AST( Abstract Syntax Tree,抽象语法树),即将源代码语法结构抽象成树状表现形式,然后通过 render函数进行渲染,并返回VNode( Vue. js的虚拟DOM节点)。
详细步骤如下。
(1)通过 compile编译器把 template编译成AST, compile是 create Compiler的返回值, createCompiler用来创建编译器。另外, compile还负责合并 option。
(2)AST会经过 generate(将AST转化成 render funtion字符串的过程)得到 render函数, render的返回值是 VNode, VNode是 Vue.Js的虚拟DOM节点,里面有标签名子节点、文本等。
22、说一下Vue.js中的MVVM模式。
MVVM模式即 Model- View- ViewModel模式。
Vue.js是通过数据驱动的, Vue. js实例化对象将DOM和数据进行绑定,一旦绑定,和数据将保持同步,每当数据发生变化,DOM也会随着变化。
ViewModel是Vue.js的核心,它是 Vue.js的一个实例。Vue.js会针对某个HTML元素进行实例化,这个HTML元素可以是body,也可以是某个CSS选择器所指代的元素。
DOM Listeners和 Data Bindings是实现双向绑定的关键。DOM Listeners监听页面所有View层中的DOM元素,当发生变化时,Model层的数据随之变化。Data Bindings会监听 Model层的数据,当数据发生变化时,View层的DOM元素也随之变化。
23、v-show指令和v-if指令的区别是什么?
v-show与v-if都是条件渲染指令。不同的是,无论v-show的值为true或 false,元素都会存在于HTML页面中;而只有当v-if的值为true时,元素才会存在于HTML页面中。v-show指令是通过修改元素的 style属性值实现的。
24、如何让CSS只在当前组件中起作用?
在每一个Vue.js组件中都可以定义各自的CSS、 JavaScript代码。如果希望组件内写的CSS只对当前组件起作用,只需要在Style标签添加Scoped属性,即 。
25、如何创建vue.js组件?
在vue.js中,组件要先注册,然后才能使用。具体代码如下
26、如何实现路由嵌套?如何进行页面跳转?
路由嵌套会将其他组件渲染到该组件内,而不是使整个页面跳转到 router-view定义组件渲染的位置。要进行页面跳转,就要将页面渲染到根组件内,可做如下配置。
首先,实例化根组件,在根组件中定义组件渲染容器。然后,挂载路由,当切换路由时,将会切换整个页面。
27、ref属性有什么作用?
有时候,为了在组件内部可以直接访问组件内部的一些元素,可以定义该属性此时可以在组件内部通过this. $refs属性,更快捷地访问设置ref属性的元素。这是一个原生的DOM元素,要使用原生 DOM API操作它们,例如以下代码。
注意:在Ve2.0中,ref属性替代了1.0版本中v-el指令的功能。
28、Vue. js是什么?
Vue. js的目标是通过尽可能简单的API实现响应式的数据绑定的组件开发。
29、描述vue.js的一些特性。
Vue.js有以下持性。
(1)MVVM模式。
数据模型( Model)发生改变,视图(View)监听到变化,也同步改变;视图(View)发生改变,数据模型( Model)监听到改变,也同步改变。
使用MVVM模式有几大好处。
(2)组件化开发
(3)指令系统
(4)Vue2.0开始支持虚拟DOM。
但在Vue1.0中,操作的是真实DOM元素而不是虚拟DOM,虚拟DOM可以提升页面的渲染性能。
30、描述vue.js的特点。
Vue. js有以下特点。
31、在vue.js中如何绑定事件?
通过在v-on后跟事件名称=“事件回调函数( )”的语法绑定事件。事件回调函数的参数集合( )可有可无。如果存在参数集合( ),事件回调函数的参数需要主动传递,使用事件对象要传递 $event。当然,此时也可以传递一些其他自定义数据。如果没有参数集合,此时事件回调函数有一个默认参数,就是事件对象。事件回调函数要定义在组件的 methods属性中,作用域是 Vue. js实例化对象,因此在方法中,可以通过this使用 Vue. js中的数据以及方法,也可以通过@语法糖快速绑定事件,如@事件名称=“事件回调函数( )”。
32、请说明 组件的作用。
当 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
keep-alive>是一个抽象组件,它自身不会渲染一个DOM元素,也不会出现在父组件链中。
当在 内切换组件时,它的 activated和 deactivated这两个生命周期钧子函数将会执行。
33、axios是什么?如何使用它?
axios是在vue2.0中用来替换 vue-resource.js插件的一个模块,是一个请求后台的模。
用 npm install axios安装 axios。基于 EMAScript 6 的 EMAScript Mole规范,通过 import关键字将 axios导入,并添加到 Vue. js类的原型中。这样每个组件(包括vue.js实例化对象)都将继承该方法对象。它定义了get、post等方法,可以发送get或者post请求。在then方法中注册成功后的回调函数,通过箭头函数的作用域特征,可以直接访问组件实例化对象,存储返回的数据。
34、在 axios中,当调用 axios.post('api/user')时进行的是什么操作?
当调用post方法表示在发送post异步请求。
35、sass是什么?如何在ue中安装和使用?
sass是一种CSS预编译语言安装和使用步骤如下。
(1)用npm安装加载程序( sass-loader、 css-loader等加载程序)。
(2)在 webpack. config. js中配置sass加载程序。
(3)在组件的 style标签中加上lang属性,例如lang="scss"。
36、如何在 Vue. js中循环插入图片?
对“src”属性插值将导致404请求错误。应使用 v-bind:src格式代替。
代码如下:
Ⅸ vue生命周期详解
vue源码中最终执行生命周期函数都是调用 callHook 方法, callHook 函数的逻辑很简单,根据传入的生命周期类型 hook ,去拿到 vm.$options[hook] 对应的回调函数数组,然后遍历执行,执行的时候把 vm 作为函数执行的上下文。
1. new Vue(options) :创建一个vm实例;
2. mergeOptions(resolveConstructorOptions(vm.constructor), options, vm) :合并Vue构造函数里options和传入的options或合并父子的options。比如:在mergeOptions函数中会调用mergeHook方法合并生命周期的钩子函数,mergeHook方法原理是只有父时返回父,只有子时返回数组类型的子。父、子都存在时,将子添加在父的后面返回组合而成的数组。这也是父子均有钩子函数的时候,先执行父的后执行子的的原因;
3. initLifecycle(vm)、initEvents(vm)、initRender(vm) :在创建的vm实例上初始化生命周期、事件、渲染相关的属性;
4. callHook(vm, 'beforeCreate') :调用beforeCreate生命周期钩子函数;
5. initInjections(vm)、initState(vm)、initProvide(vm) :初始化数据:inject、state、provide。initState 的作用是初始化 props、data、methods、watch、computed 等属性;
6. callHook(vm, 'created') :调用created生命周期钩子函数;
7. vm.$mount(vm.$options.el) : $mount 方法在多个文件中都有定义,如"src/platform/web/entry-runtime-with-compiler.js"、"src/platform/web/runtime/index.js"、"src/platform/weex/runtime/index.js"。因为 $mount 方法的实现是和平台、构建方式相关的。以"entry-runtime-with-compiler.js"为例,关键步骤是查看 vm.$options 中是否有render方法,如果没有则会根据el和template属性确定最终的template字符串,再调用 compileToFunctions 方法将template字符串转为render方法,最后,调用原先原型上的$mount方法,即开始执行"lifecycle.js"中 mountComponent 方法;
8. callHook(vm, 'beforeMount') :调用beforeMount生命周期钩子函数;
9. vm._render() => vm._update() => vm.__patch__() :先执行vm._render方法,即调用createElement生成虚拟DOM,即VNode ,每个VNode有children ,children 每个元素也是⼀个 VNode,这样就形成了⼀个 VNode Tree;再调用vm._update方法进行首次渲染,vm._update方法核心是调用vm. patch 方法,这个方法跟vm.$mount一样跟平台相关;vm. patch 方法则是根据生成的VNode Tree递归createElm方法创建真实Dom Tree挂载到Dom上;
10. callHook(vm, 'mount') :调用mount生命周期钩子函数:VNode patch 到 Dom 之后会执行 'invokeInsertHook'函数,把 insertedVnodeQueue 中保存的mount钩子函数执行一遍,insertedVnodeQueue队列中的钩子函数是在根据VNode Tree递归createElm方法创建真实Dom Tree过程生成的钩子函数顺序队列,因此mounted钩子函数的执行顺序是先子后父;
11. data changes :数据更新,nextTick中执行 flushSchelerQueue 方法,该方法会执行watcher队列中的watcher;
12. callHook(vm, 'beforeUpdate') :执行watcher时会执行watcher的before方法,即调用beforeUpdate生命周期钩子函数;
13. Virtual DOM re-render and patch :重新render生成新的Virtual DOM,并且patch到DOM上;
14. callHook(vm, 'updated') :调用updated生命周期钩子函数;
15. vm.$destroy() :启动卸销毁过程;
16. callHook(vm, 'beforeDestroy') :调用beforeDestroy生命周期钩子函数;
17. Teardown watchers, childcomponents and event listeners :执行一系列销毁动作,在 $destroy 的执行过程中,它又会执行 vm.__patch__(vm._vnode, null) 触发它子组件的销毁钩子函数,这样一层层的递归调用,所以 destroyed 钩子函数执行顺序是先子后父,和 mounted 过程一样。
18. callHook(vm, 'destroyed ') :调用destroyed 生命周期钩子函数。
Ⅹ 请简述什么是vue
vue指的是vue.js框架。Vue.js是一款友好的、多用途的且高性能的js框架,一款构建用户界面的渐进式框架,它可以帮你创建可维护性和可测试性更强的代码库。
Vue.js是一款流行的JavaScript前端框架,一个用于创建用户界面的开源JavaScript框架,旨在更好地组织与简化Web开发。Vue所关注的核心是MVC模式中的视图层,同时,它也能方便地获取数据更新,并通过组件内部特定的方法实现视图与模型的交互。
Vue.js是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用。
Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
Vue.js 自身不是一个全能框架——它只聚焦于视图层。因此它非常容易学习,非常容易与其它库或已有项目整合。另一方面,在与相关工具和支持库一起使用时 ,Vue.js 也能完美地驱动复杂的单页应用。
Vue.js是前端的主流框架之一,和Angular.js、React.js 一起,并成为前端三大主流框架!