vue.js 常见面试题
Looking for a front-end framework to try out, I started with React and then tried Vue.js.
寻找一个前端框架来尝试,我从React开始,然后尝试了Vue.js。
Unfortunately, I encountered a lot of issues with Vue.js at the very beginning. In this article, I’d like to share a few common issues that you may have to deal with when working with Vue.js. Some of these issues may seem obvious, but I figured that sharing my experience might help someone.
不幸的是,一开始我就遇到了很多Vue.js问题。 在本文中,我想分享一些使用Vue.js时可能要处理的常见问题。 其中一些问题似乎很明显,但我认为分享经验可能会对某人有所帮助。
包括模板编译器 (Include template compiler)
My first issue was a pretty basic one. The first thing to do in order to use Vue.js is to import it. If you follow the official guide and use an inline template for your component, you will get a blank page.
我的第一个问题是一个非常基本的问题。 为了使用Vue.js,要做的第一件事就是导入它。 如果您遵循官方指南并为组件使用嵌入式模板,则将获得空白页。
import Vue from 'vue';
var vm = new Vue({
el: '#vm',
template: '<div>Hello World</div>',
});
Note that this issue doesn’t occur when you define templates with the render function or SFC (Single File Component).
请注意,当您使用渲染功能或SFC( 单个文件组件 )定义模板时,不会发生此问题。
Actually, there are many Vue builds. The default build exported by the NPM package is the runtime-only build. It doesn’t bring the template compiler.
实际上,有许多Vue版本 。 NPM软件包导出的默认构建是仅运行时构建 。 它没有带来模板编译器。
For some background information, the template compiler works exactly like JSX for React. It replaces template strings with function calls to create a Virtual DOM node.
有关一些背景信息,模板编译器的工作原理与JSX for React完全相同。 它使用函数调用替换模板字符串,以创建虚拟DOM节点。
// #1: import full build in JavaScript file
import Vue from 'vue/dist/vue.js';
// OR #2: make an alias in webpack configuration
config.resolve: {
alias: { vue: 'vue/dist/vue.js' }
}
// OR #3: use render function directly
var vm = new Vue({
el: '#vm',
render: function(createElement) {
return createElement('div', 'Hello world');
}
});
With SFCs, this issue does not occur. Both vue-loader and vueify are tools used to handle SFCs. They generates plain JavaScript components using the render function to define the template.
使用SFC,不会发生此问题。 vue-loader和vueify都是用于处理SFC的工具。 他们使用render函数生成纯JavaScript组件来定义模板。
To use string templates in components, use a full Vue.js build.
要在组件中使用字符串模板,请使用完整的Vue.js构建。
In summary, to fix this issue, specify the correct build during import, or make an alias for Vue in your bundler configuration.
总之,要解决此问题,请在导入期间指定正确的内部版本,或在捆绑程序配置中为Vue命名。
You should note that using string templates reduces your app performance, because the compilation occurs at runtime.
您应该注意,使用字符串模板会降低应用程序性能,因为编译是在运行时进行的。
There are many more ways to define a component template, so check out this article. Also, I recommend using the render function in Vue instance.
还有许多定义组件模板的方法,因此请查看本文 。 另外,我建议在Vue instance中使用render函数 。
保持物业的React力 (Keep property’s reactivity)
If you use React, you probably know its reactivity relies on calling the setState
function to update the value of properties.
如果使用React,您可能知道它的React性取决于调用setState
函数来更新属性值。
Reactivity with Vue.js is a bit different. It’s based on proxying the component properties. Getter and setter functions will be overridden and will notify updates to the Virtual DOM.
与Vue.js的React性有些不同。 它基于代理组件属性。 Getter和setter函数将被覆盖,并将通知虚拟DOM更新。
var vm = new Vue({
el: '#vm',
template: `<div>{{ item.count }}<input type="button" value="Click" @click="updateCount"/></div>`,
data: {
item: {}
},
beforeMount () {
this.$data.item.count = 0;
},
methods: {
updateCount () {
// JavaScript object is updated but
// the component template is not rendered again
this.$data.item.count++;
}
}
});
In the code snippet above, the Vue instance has a property called item
(defined in data). This property contains an empty literal object.
在上面的代码片段中,Vue实例具有一个称为item
的属性(在数据中定义)。 此属性包含一个空的文字对象。
During the component initialization, Vue creates a proxy under the get
and set
functions attached to the item
property. Thus, the framework will watch value changes and eventually react.
在组件初始化期间,Vue在附加到item
属性的get
和set
函数下创建一个代理。 因此,框架将观察价值变化并最终做出React。
However, the count
property isn’t reactive, because it wasn’t declared at initialization time.
但是, count
属性不是React性的,因为它不是在初始化时声明的。
Actually, proxifying only occurs at component initialization time, and thebeforeMount
lifecycle function triggers later.
实际上,代理仅在组件初始化时发生,而beforeMount
生命周期函数将在稍后触发。
Besides, the item
setter isn’t called during count
definition. So the proxy won’t trigger and the count
property will have no watch.
此外,在count
定义期间不会调用item
设置器。 因此,代理不会触发,并且count
属性将没有监视。
beforeMount () {
// #1: Call parent setter
// item setter is called so proxifying is propaged
this.$data.item = {
count: 0
};
// OR #2: explicitly ask for watching
// item.count got its getter and setter proxyfied
this.$set(this.$data.item, 'count', 0);
// "Short-hand" for:
Vue.set(this.$data.item, 'count', 0);
}
If you keep the item.count
affectation in beforeMount
, calling Vue.set
later won’t create a watch.
如果保持item.count
做作的beforeMount
,呼吁Vue.set
后不会产生手表。
The exact same issue also occurs with arrays when using direct affection on unknown indexes. In such cases, you should prefer array proxifyed functions such as push
and slice
.
当对未知索引使用直接影响时,数组也会发生完全相同的问题。 在这种情况下,您应该更喜欢数组代理函数,例如push
和slice
。
Also, you can read this article from the Vue.js Developer’s website.
另外,您可以从Vue.js开发人员的网站上阅读本文 。
小心证监会出口 (Be careful with SFC exports)
You can use Vue regularly in JavaScript files, but you can also use Single File Components. It helps to gather JavaScript, HTML, and CSS code in a single file.
您可以在JavaScript文件中定期使用Vue,但也可以使用单个文件组件 。 它有助于将JavaScript,HTML和CSS代码收集到一个文件中。
With SFCs, the component code is the script tag of a .vue
file. Still written in JavaScript, it has to export the component.
对于SFC,组件代码是.vue
文件的脚本标记。 仍然使用JavaScript编写,它必须导出组件。
There are many ways to export a variable/component. Often, we use either direct, named, or default exports. Named exports will prevent users from renaming the component. It will also be eligible for tree-shaking.
有很多导出变量/组件的方法。 通常,我们使用直接,命名或默认导出。 命名导出将阻止用户重命名该组件。 它也有资格进行摇树 。
/* File: user.vue */
<template>
<div>{{ user.name }}</div>
</template>
<script>
const User = {
data: () => ({
user: {
name: 'John Doe'
}
})
};
export User; // Not work
export default User; // Works
</script>
/* File: app.js */
import {User} from 'user.vue'; // Not work
import User from 'user.vue'; // Works (".vue" is required)
Using named exports is not compatible with SFCs, be mindful about this!
使用命名的导出与SFC不兼容,请注意这一点!
In summary, exporting a named variable by default might be a good idea. This way, you will get more explicit debug messages.
总之,默认情况下导出命名变量可能是一个好主意。 这样,您将获得更明确的调试消息。
不要混用SFC组件 (Don’t mix SFC components)
Putting code, template, and style together is a good idea. Besides, depending on your constraints and opinions, you may want to keep the separation of concerns.
将代码,模板和样式放在一起是一个好主意。 此外,根据您的约束和意见,您可能希望保持关注点分离 。
As described in the Vue documentation, it’s compatible with SFC.
如Vue文档中所述,它与SFC兼容。
Afterward, one idea came to my mind. Use the same JavaScript code and include it in different templates. You may point it as a bad practice, but it keeps things simple.
之后,我想到一个主意。 使用相同JavaScript代码,并将其包含在不同的模板中。 您可能会指出这是一个不好的做法,但它会使事情变得简单。
For instance, a component can have both read-only and read-write mode and keep the same implementation.
例如,一个组件可以同时具有只读和读写模式,并保持相同的实现。
/* File: user.js */
const User = {
data: () => ({
user: {
name: 'John Doe'
}
})
};
export default User;
/* File: user-read-only.vue */
<template><div>{{ user.name }}</div></template>
<script src="./user.js"></script>
/* File: user-read-write.vue */
<template><input v-model="user.name"/></template>
<script src="./user.js"></script>
In this snippet, both read-only and read-write templates use the same JavaScript user component.
在此片段中,只读和读写模板都使用相同JavaScript用户组件。
Once you import both components, you will figure out that it doesn’t work as expected.
导入两个组件后,您将发现它无法按预期工作。
// The last import wins
import UserReadWrite from './user-read-write.vue';
import UserReadOnly from './user-read-only.vue';
Vue.component('UserReadOnly', UserReadOnly);
Vue.component('UserReadWrite', UserReadWrite);
// Renders two times a UserReadOnly
var vm = new Vue({
el: '#vm',
template: `<div><UserReadOnly/><UserReadWrite/></div>`
});
The component defined in user.js
can only be used in a single SFC. Otherwise, the last imported SFC which uses it will override the previous.
在中定义的组件 user.js
只能在单个SFC中使用。 否则,使用它的最后一个导入的SFC将覆盖前一个。
SFCs allow splitting code in separate files. But you can’t import thoses files in multiple Vue components.
SFC允许将代码拆分为单独的文件。 但是您不能将这些文件导入多个Vue组件中。
To make it simple, don’t reuse JavaScript component code in multiple SFC components. The separate code feature is a handy syntax, not a design pattern.
为简单起见,请勿在多个SFC组件中重用JavaScript组件代码。 单独的代码功能是一种方便的语法,而不是设计模式。
Thanks for reading, hope my experience has been useful to make you avoid the mistakes I made.
感谢您的阅读,希望我的经验对您避免我犯的错误有所帮助。
If it was useful, please click on the ? button a few times to make others find the article and show your support! ?
如果有用,请单击 ? 几次单击以使其他人找到该文章并表示支持! ?
Don’t forget to follow me to get notified about my upcoming articles ?
别忘了跟随我获得有关我即将发表的文章的通知吗?
查看我的其他文章 (Check out my Other Articles)
➥JavaScript (➥ JavaScript)
How to Improve Your JavaScript Skills by Writing Your Own Web Development Framework ?
Stop Painful JavaScript Debug and Embrace Intellij with Source Map
➥React初学者系列 (➥ React for beginners series)
翻译自: https://www.freecodecamp.org/news/common-mistakes-to-avoid-while-working-with-vue-js-10e0b130925b/
vue.js 常见面试题