前兩天接到一個面試官問我vue什么程度才算作可以用於開發,以前從沒遇到過類似問題。只能大致說了一些,事后覺得也應該總結一下,前端vue這么火熱那究竟什么才算做入門什么才算做熟練,只是我個人觀點,不代表所有人,每個人理解可能有所不同,本次不說精通級,在我看來除了那些參與框架開發維護以及那些能對vue提出有價值意義的人之外都不能說自己精通,當然如果能自己手寫一套和vue差不多甚至更勝vue的那不算精通vue了,那算精通js的大神。本次博文僅對職場中入門與熟練
入門級需要掌握
1、生命周期
beforeCreate、created(*)、beforeUpdate、updated、beforeMount、mounted(*)、beforeDestory(*)、destoryed八個常用以及actived、deactived、errorCaptured三個不常用
2、指令
v-on(簡寫@ *)、v-if/v-show(*)、v-else/v-else-if、v-bind(簡寫:*)、v-text/v-html/v-pre、v-slot、v-clock、v-model(*)、v-once、v-for(*)
3、全局api
extend、nextTick、set、delete、directive(*)、filter、component(*)、use(*)、mixin、compile、observable、version
4、單頁面常用方法和屬性(*)
data、methods、props、computed、watch、directive、filter、components、name等
5、實例常用方法和屬性(*)
$set、$props、$el、$parent、$emit、$on、$off、$slots、$children、$refs、$attrs、$listeners、$once、$delete、$forceUpdate、$nextTick等
6、特殊特性
key、ref、slot等
7、會用兩到三個ui庫並且能對一些簡單業務組件進行二次封裝
emmm、、、大概就這么多吧,我這里所說的入門級不是說你自己私下搗鼓倆頁面就算入門了,那樣子的話用來找工作說實話,不會有公司用你的,如果是用於基礎開發的入門級以上帶星號的是必須要知道怎么用的,其余沒有星號的也要了解,至少遇到場景時候知道應該怎么去查。下面再說說熟練級別吧
熟練級別應該掌握的東西
1、能夠正確的認知vue雙向數據綁定原理(是能夠認知而不是百度背一遍答案的)
在這我只粘貼一個入門級的簡單demo,因為年底了暫時沒時間去實現一套完整的,請諒解
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="userName">
<br>
<span id ="uName"></span>
<script>
var obj={
pwd:"1234"
};
//主要使用到了get和set方法,最為關鍵
Object.defineProperty(obj,"userName",{
get:function(){
console.log('get init');
},
set:function(val){
console.log("set init");
document.getElementById("uName").innerText=val;
document.getElementById("userName").value=val;
}
});
document.getElementById("userName").addEventListener("keyup",function(event){
obj.userName=event.target.value;
}
)
</script>
</body>
</html>
年后我會抽時間單獨的針對這里進行一次代碼codeing,現在先分享一個我覺得講的很棒的文章 https://www.cnblogs.com/songyao666/p/11494923.html 來自於逐夢song
2、能夠正確認知何為單向數據流、雙向數據綁定
這里可能會有一些歧義,因為有些人認為既然要單向數據流為什么不直接用react,每個團隊每個人所理解的思想大概是不同的吧,在我看來單向數據流雖然會讓你的codeing更多一些時間,但是后續的維護中成本會小很多,我們團隊曾經用單向數據流實現過完整的一套ui框架,線上跑了很久沒有任何問題,即使出問題,我們能夠掌握數據流向,排查也是很快很迅速,而且我們很有信心哪怕哪天我們技術框架換成react或者換成angular只要本着這個思想我們只是改一下基本的語法即可,實現一套一摸一樣的ui庫只是語法不同而已。如果有大佬不認同還請留情,因為每個人認定的思想不同,這里我也是糾結了一些時間,決定還是說出去,至少可以給其他人一些開發的思路
3、能夠去正確認知何為mv*思想
mv*的思想就是將其中的View 的狀態和行為抽象化,讓我們將視圖 UI 和業務邏輯分開,其實這種編程思路不管是用不用vue對你都會有很大意義,我現在基本不會用jq一頓亂懟,吃虧過才會理解數據和view為什么要分開。
4、能夠自己去讀一遍到三遍vue源碼
為什么要定在1-3這個區間呢,因為我覺得第一次讀可能會有很多的不可理解,等你讀到第二次之后你會更加深入,等到第三遍的時候我相信你已經能大致理解了vue的整體思路,至於再多讀 ,對你的提升還會有,但是遠遠不如前三次
5、能夠實現對vue項目的優化
這其中包含vue打包速度的優化、seo的優化、運行性能的優化、代碼可控性優化、安全性優化。之前出過一篇文章專門講各種優化,雖然不是講vue的。不過相信你認真讀過后並且和vue結合起來。會讓你能夠更好的優化自己的項目(https://www.cnblogs.com/jinzhenzong/p/11777065.html)
6、能夠自己去實現或者參與一套基礎框架的開發
當我們團隊在沒有開發我們這一套基礎組件時候,我們也可以熟練的去完成業務,但是真正有一些很棘手的問題比如form驗證怎么寫什么的等一系列問題,我們不甚了解。當我們寫完這一套框架時候,我深深可以感覺到自己參與其中是有多么大的提高,當我們穩穩運行了接近一年的時間后我現在深深感覺自己可以算作熟練vue了。很少會有vue中我會很難能夠定位到問題bug,大致都能猜到問題在哪,再去細致排查即可。可以提供一下我們框架包含的組件給大家參考:
localTable、asynctable、alert、comfirm、dialog、button、form、input、select、checkbox、radio、datepicker、datetimepicker、timepicker、localTree、asyncTree、upload、editor、transfer以及輔助的loading,其實每一項我之前都沒有想過我要自己去實現,當我們實現並且穩定運行的時候,真的很開心,這不光是提升技術更是讓自己更開心的時刻
7、能夠手寫vue腳手架
這是個考驗自己webpack的時刻,雖然vue推薦cli自動生成的,但是我更傾向於還是要自己去寫,因為這樣你才能知道vue打包的流程,出現問題不至於排查很久不得果。下面分享下我自己寫的,我webpack不是很熟練,如果有不妥的地方,還請大佬們指點出來
先來webpack.config:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require("path");
const argv = require('yargs-parser')(process.argv.slice(2));
const _mode = argv.mode || 'development';
const _mergeConfig = require(`./config/webpack.${_mode}`);
const merge = require('webpack-merge');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');
let webpackConfig = {
entry: ['./src/main.js'],
output: {
path: path.resolve(__dirname, './dist'),//輸出結果
filename: 'scripts/[name].js',
chunkFilename: 'scripts/[id].chunk.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
},
presets: ['es2015'],
plugins: ['transform-runtime', 'transform-object-rest-spread']
},
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
},
]
},
plugins: [
new VueLoaderPlugin(),
// new CopyWebpackPlugin([{
// from: './src/static',
// to: 'static'
// }]),
new webpack.ProvidePlugin({
"_global_object": [path.resolve(__dirname, "./src/static/js/event.js"), 'default']
}),
new HtmlWebpackPlugin(
{
filename:"./index.html",
template: './src/index.html'
}
)
],
resolve: {
extensions: ['.vue', '.js', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
"@CoreUILib":path.resolve(__dirname,"./src/core/le-components"),
"@util":path.resolve(__dirname,"./src/core/tool/commonUtil.js"),
"@service":path.resolve(__dirname,"./src/service"),
"@store":path.resolve(__dirname,"./src/store"),
"@api":path.resolve(__dirname,"./src/api")
}
},
};
module.exports = merge(webpackConfig, _mergeConfig);
再來dev
const path = require("path");
const SSICompileWebpackPlugin = require('ssi-webpack-plugin');
module.exports = {
mode:'development',
output:{
publicPath:'/'
},
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
]
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]',
limit: 8192,
outputPath: 'static/images'
}
},
]
},
devServer: {
inline: true, //檢測文件變化,實時構建並刷新瀏覽器
port: "9918",
proxy: {
'': {
target: '',
pathRewrite: {
},
secure: false,
changeOrigin: true
}
},
//404 頁面返回 index.html
historyApiFallback: true,
},
plugins:[
new SSICompileWebpackPlugin({
localBaseDir: path.resolve(__dirname, '../src'),
publicPath: ''
})
],
devtool:'eval-source-map'
}
最后product
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const webpack = require("webpack");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
mode: 'production',
output: {
publicPath: './'
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
}
},
{
loader: 'css-loader',
}
]
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]',
limit: 8192,
outputPath: 'images',
}
},
]
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "css/[name].[chunkhash:8].css",
chunkFilename: "css/[id].css"
}),
// new BundleAnalyzerPlugin()
],
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
jquery: {
name: 'jquery',
test: /[\\/]node_modules[\\/]jquery/,
chunks: 'all'
},
venders: {
name: 'vender',
test: /[\\/]node_modules[\\/]/,
chunks: 'all'
},
// 這里定義的是在分離前被引用過兩次的文件,將其一同打包到common.js中,最小為30K
common: {
name: "common",
test: /[\\/]src[\\/]/,
minChunks: 2,
minSize: 30000
}
}
},
runtimeChunk: {
name: 'runtime'
}
},
devtool: 'none'
}
不是很多,但是夠我用了
8、熟練掌握vue全家桶
emmm、、、怎么說呢本次只對vue進行了總結,沒有總結其余的,其實入門級就要知道router、vuex、axios等的基本使用。但是我放到了熟練級別,因為在我看來這部分對熟練掌握的來說更為重要,這是一定要知道的,包含但不局限於這三個周邊。
9、知道怎么服務端渲染
10、能夠真正的去把握vue的運行、渲染過程
大概就是這么多了吧,感覺還是不少的,年前最后一天,沒有什么干貨,大概可以給大家當一個目錄吧,替大家去掉了一些不是很常用的部分,歡迎各位大佬在補充補充,最后祝大家新年快樂
