vue 试题
vue生命周期钩子?

每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。
简而言之:创建(beforeCreate、created),挂载(beforeMount、mounted), 更新(beforeUpdate、updated),销毁(beforeDestroy、destroyed)
此外,vue-router中使用keep-alive会增加两个生命周期,activated,deactivated
指令:
v-on --> @click
// 事件修饰符 <!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修饰符 --> <form v-on:submit.prevent></form> <!-- 添加事件监听器时使用事件捕获模式 --> <!-- 即内部元素触发的事件先在此处处理,然后才交由内部元素自身进行处理 --> <div v-on:click.capture="doThis">...</div> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div> <!-- 点击事件将只会触发一次 --> <a v-on:click.once="doThis"></a> // 按键修饰符 <!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` --> <input v-on:keyup.13="submit"> <!-- 缩写语法 --> <input @keyup.enter="submit"> .enter .tab .delete (捕获“删除”和“退格”键) .esc .space .up .down .left .right // 可以通过全局 config.keyCodes 对象自定义按键修饰符别名: // 可以使用 `v-on:keyup.f1` Vue.config.keyCodes.f1 = 112 // 系统修饰键 <!-- Alt + C --> <input @keyup.alt.67="clear"> <!-- Ctrl + Click --> <div @click.ctrl="doSomething">Do something</div> .ctrl .alt .shift .meta <!-- 即使 Alt 或 Shift 被一同按下时也会触发 --> <button @click.ctrl="onClick">A</button> <!-- 有且只有 Ctrl 被按下的时候才触发 --> <button @click.ctrl.exact="onCtrlClick">A</button> <!-- 没有任何系统修饰符被按下的时候才触发 --> <button @click.exact="onClick">A</button> // 鼠标按钮修饰符 .left .right .middle
v-bind --> : 动态属性绑定
<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>
<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>
<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>
// .camel 修饰符允许在使用 DOM 模板时将 v-bind 属性名称驼峰化,例如 SVG 的 viewBox 属性:
<svg :view-box.camel="viewBox"></svg>
//在使用字符串模板或通过 vue-loader/vueify 编译时,无需使用 .camel。
v-if和v-show的区别。
v-if需要重新渲染节点。 初始性能好,切换成本高。
v-show切换css中的display属性。 初始成本高,切换成本低。
<div v-if="type === 'A'"> A </div> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <div v-else> Not A/B/C </div> // 类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。 <h1 v-show="ok">Hello!</h1> //带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。 v-if vs v-show v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
v-for可以放数组和对象,可以嵌套循环。
// 遍历数组 <ul id="example-2"> <li v-for="(item, index) in items"> {{ parentMessage }} - {{ index }} - {{ item.message }} </li> </ul> var example2 = new Vue({ el: '#example-2', data: { parentMessage: 'Parent', items: [ { message: 'Foo' }, { message: 'Bar' } ] } }) // 遍历对象 <div v-for="(value, key, index) in object"> {{ index }}. {{ key }}: {{ value }} </div> new Vue({ el: '#v-for-object', data: { object: { firstName: 'John', lastName: 'Doe', age: 30 } } }) // 嵌套 <div v-for="outerVal in sheet"> //sheet <div v-for="(middleVal,middleKey) in outerVal"> //List {{middleKey.value}} //title的值 <div v-for="innerVal in middleKey.course"> //Title {{innerVal}} //课程值 </div> </div> </div> ##数组更新检测 Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下: push() pop() shift() unshift() splice() sort() reverse() ##替换数组 //filter(), concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组: example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) }) // Vue.set Vue.set(example1.items, indexOfItem, newValue)
v-html 相当于innerHTML,(react中dangerouslySetInnerHTML,可能会发生xss跨站请求攻击,可通过代码无害化,即去除<括号即可)
<div v-html="html"></div>
v-model 双向数据绑定。绑定的变量必须在data属性中被初始化过。
<input v-model.number="age" type="number"> 限制: <input> <select> <textarea> components 修饰符: .lazy - 取代 input 监听 change 事件 在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change 事件进行同步: .number - 输入字符串转为数字 .trim - 输入首尾空格过滤
计算属性:本质是function
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
计算缓存(computed)与方法(methods)。计算属性会自动监视方法中的所有依赖,如果依赖改变了,会自动重新计算,如果依赖没改变,会把上一次的计算结果(缓存)给返回出去。
跟watch比的优点:watch一次只能监视一个变量,计算属性自动监视方法中用到的所有变量。
计算属性是有setter方法的。
// ... computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } // 现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。
给自定义组件绑定原生事件: <good-abc @click.native />
VUE1.x -- 2迁移
生命周期:废除:
beforeCompile --> created !!
compiled --> mounted !!
attached --> mounted-$nextTick
detached --> destroyed-$nextTick
改名了:
init --> beforeCreate !!
ready --> mounted !!
v-for的index位置调整了。
v-for的下标$index被移除了。
track-by变成了:key
计算属性的cache属性被移除
万能回答方法:使用迁移工具,迁移工具提示的地方都按照文档进行修正了。
vuex:
state
mutations 不能写异步
actions 非必要
getters 非必要
transition动画
过渡的类名
v-enter:定义进入过渡的开始状态。
v-enter-active:定义过渡的状态。
v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。
v-leave: 定义离开过渡的开始状态。
v-leave-active:定义过渡的状态。
v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue"></script>
<style type="text/css">
.good-enter-active {
transition-duration: 1s;
}
.good-enter-to {
margin-left: 0px;
}
.good-enter {
margin-left: -200px;
}
.good-leave-active {
transition-duration: 0.8s;
}
.good-leave-to {
margin-left: 200px;
opacity: 0;
}
.good-leave {
margin-left: 0px;
opacity: 1;
}
</style>
</head>
<body>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="good">
<p v-if="show">hello</p>
</transition>
</div>
</body>
<script type="text/javascript">
var vm = new Vue({
el: "#demo",
data: {
show: false
}
})
</script>
</html>
自定义动画
enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> <div id="example-3"> <button @click="show = !show"> Toggle render </button> <transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight" > <p v-if="show">hello</p> </transition> </div> new Vue({ el: '#example-3', data: { show: true } })
js如何监视一个动画结束? transitionend,animationend
自定义指令:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue"></script>
<style type="text/css">
</style>
</head>
<body>
<div id="demo">
<input type="number" v-model.number="age" />
<input type="text" v-nshow="age > 30" />
</div>
</body>
<script type="text/javascript">
Vue.directive("nshow", {
inserted: function(el, bindings) {
if(bindings.value) {
el.style.display = "";
} else {
el.style.display = "none";
}
},
componentUpdated: function(el, bindings) {
if(bindings.value) {
el.style.display = "";
} else {
el.style.display = "none";
}
}
})
var vm = new Vue({
el: "#demo",
data: {
age: 39
}
})
</script>
</html>
Vue.js 的插件
应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 逻辑... } ... }) // 3. 注入组件 Vue.mixin({ created: function () { // 逻辑... } ... }) // 4. 添加实例方法 Vue.prototype.$myMethod = function (methodOptions) { // 逻辑... } }
事件:框架封装addcar($event,id)

项目中遇到哪些问题?
位置定位,滚动定位(随滚动绑定到谁),购物车动画(bezier曲线),vuex数据持久化(localStorage),左右联动(数据结构)
vue-cli如何配置反向代理?
安装cli:
npm install vue-cli -g
vue init webpack my_project
cd my_project
npm install
在config/index.js文件下:
proxyTable: { '/vip': { target: 'http://localhost:9000/', changeOrigin: true, pathRewrite: { '^/vip': '' } } }
当然也可通过webpack自己实现
如何确认vue列表渲染的结束时间?
全局:Vue.nextTick( [callback, context] ),局部:vm.$nextTick( [callback] )
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
new Vue({ // ... methods: { // ... example: function () { // 修改数据 this.message = 'changed' // DOM 还没有更新 this.$nextTick(function () { // DOM 现在更新了 // `this` 绑定到当前实例 this.doSomethingElse() }) } } })
详见:https://cn.vuejs.org/v2/api/#vm-nextTick
keep-alive的应用场景?
比如有一个列表和一个详情,那么用户就会经常 打开详情=>返回列表=>打开详情… 这样的话列表和详情都是一个频率很高的页面,那么就可以对列表进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染
<keep-alive> <component> <!-- 组件将被缓存 ,每个在keep-alive 内的组件会新增两个生命周期钩子: activated -和 deactivated-> </component> </keep-alive>
缺点:占用内存,
详见:http://www.cnblogs.com/fanlinqiang/p/8028669.html
vue与react的对比,如何选型?从性能,生态圈,数据量,数据的传递上,作比较
1) React和Vue有许多相似之处,它们都有:
使用 Virtual DOM
提供了响应式(Reactive)和组件化(Composable)的视图组件。
将注意力集中保持在核心库,伴随于此,有配套的路由和负责处理全局状态管理的库。
2) 性能:
到目前为止,针对现实情况的测试中,Vue的性能是优于React的。
3) 生态圈
Vue.js: ES6+Webpack+unit/e2e+Vue+vue一router+单文件组件+vuex+iVew
React: ES6+Webpack+Enzyme+React+React一router+Redux
4) 什么时候选择Vue.js
如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue
如果你喜欢简单和”能用就行”的东西,请使用Vue
如果你的应用需要尽可能的小和快,请使用Vue
如果你计划构建一个大型应用程序,请使用React
如果你想要一个同时适用于Web端和原生App的框架,请选择React
如果你想要最大的生态圈,请使用React
详细参考:
http://cn.vuejs.org/v2/guide/comparison.html#React
http://blog.csdn.net/yzh_2017/article/details/54909166
vue slot是做什么的?
简单来说,假如父组件需要在子组件内放一些D〇M,那么这些DOM是显示、不显示、在哪 个地方显示、如何显示,就是slot分发负责的活。
详细参考:http://cn.vueis.orq/v2/quide/comp〇nents.html#使用一Slot一分发内容
vue和angular的优缺点以及适用场合?
参见:《在选择框架的时候要从哪方面入手》一题
vue路甶实现原理?
以官方仓库下examples/basic基础例子来一点点具体分析整个流程。
和流程相关的主要需要关注点的就是components、history目录以及create一matcher.js、 create一route一map.js、index.js,install.js。
从入口,作为插件,实例化VueRouter,实例化History,实例化Vue, defineReactive定 义_route, router一link和router一view组件等几个方面展开分析
必须参见:http://www.tuicool.com/articles/jQRnlrF
你们vue项目是打包了一个js文件,一个css文件, 还是有多个文件?
根据vue一cli脚手架规范,一个js文件,一个CSS文件。
详细参见:
http://blog.csdn.net/lx376693576/article/details/54911340
https://zhuanlan.zhihu.com/p/24322005
vue遇到的坑,如何解决的?
Vue1.0升级2.0有很多坑:生命周期;路由中引入静态js,全局组件,全局变量,全局 function; v一for循环的key, value值互换了位置,还有track一by; filter过滤器;遍历数组时, key值不能做model;父子通信等。
其他坑详见:
http://blog.csdn.net/lemon_zhao/article/details/55510589 https://segmentfault.com/a/1190000008347498 http://www.tuicool.com/articles/aUrmumV
vue的双向绑定的原理,和angular的对比
在不同的MWM框架中,实现双向数据绑定的技术有所不同。
AngulaJS采用‘‘脏值检测”的方式,数据发生变更后,对于所有的数据和视图的绑定关系进 行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改 变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视 图,更新页面展现。如果是手动对ViewModel的数据进行变更,为确保变更同步到视图, 需要手动触发一次‘‘脏值检测”。
VueJS则使用ES5提供的〇bject.defineProperty()方法,监控对数据的操作,从而可以自 动触发数据同步。并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的 视图,而不是对所有的数据都执行一次检测。
详细参见:http://www.jianshu.eom/p/d3a15a1f94a0
vue一cli,脚手架
安装:$ npm install -g vue-cli
使用:$ vue init <template一name> <project一name>
webpack配置详解:https://zhuanlan.zhihu.eom/p/24322005
Vue里面router一link在电脑上有用,在安卓上没反应 怎么解决?
Vue路由在Android机上有问题,babel问题,安装babel polyfill插件解决。
vue-cli使用中遇到的问题?
node-sass,sass-loader
vue性能优化
vue使用过哪些插件:vuex,vue-router,iview,mintui,vue-router(logger)
vue 脚手架使用哪个版本,webpack或simple_webpack
computed与method区别?
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。
动态组件?
<component v-bind:is="currentView"></component>
最明显的就是router-view,应用场景如:table里必须嵌套tr的时候,再如select里的option

浙公网安备 33010602011771号