Vue2.x回顾

Vue2.X回顾

写在前面

子曰: “温故而知新”;所以我经常在自己的学习生涯中进行阶段性回顾,方便以后复习.2019年准备入手学习React,在这之前对自己已经掌握的Vue进行一下回顾.

开始之前

工欲善其事必先利其器,最好先掌握Webpack,Babel,ES6,npm;
我几乎没用过vue-cli提供的脚手架,除了快速开发否则我都是自己撘脚手架,这只是为了我可以接触更多的技术,学习到新的知识.下面附上我常用的配置:


// webpack.config.js  
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const Autoprefixer = require('autoprefixer');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const LessFunc = require('less-plugin-functions');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const isProduction = process.env.NODE_ENV === 'production';

const DevServer = require('./webpack.server.js');

module.exports = {
	entry: {
		main: path.resolve(__dirname + '/src/index.ts'),
		lib: ['vue', 'vue-class-component']
	},
	output: {
		path: path.resolve(__dirname + '/build/'),
		filename: isProduction ? 'js/[name].min.js' : 'js/[name].js'
	},
	module: {
		rules: [
			{
                test: /\.tsx?$/,
                exclude: /node_modules/,
                loader: 'ts-loader',
                options: {
                    appendTsSuffixTo: [/\.vue$/]
                }
            },
			{
                test: /\.js$/,
                exclude: path.resolve(__dirname, '/node_modules'),
                loader: 'babel-loader',
                options: {
                    "presets": ["@babel/preset-env"]
                }
            },
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [
                                require('autoprefixer')({
                                    browsers: ['last 5 versions']
                                })
                            ]
                        }
                    }, {
                        loader: 'less-loader',
                        options: {
                            plugins: [ new LessFunc() ]
                        }
                    }, {
                        loader: 'style-resources-loader',
                        options: {
                            patterns: path.resolve(__dirname, './src/style/common.less')
                        }
                    }]
                })
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader']
                })
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.jpg|\.png|\.jpeg|\.svg|\.ttf|\.woff$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputpath: './img',
                        publicpath: './img'
                    }
                }]
            }
		]
	},
	plugins: [
        new HtmlWebpackPlugin({
            title: '主页',
            filename: 'index.html',
            template: './index.html',
            inject: 'body',
            hash: true,
            chunks: ['main', 'lib'],
            minify: {
                removeComments: true, //移除HTML中的注释
                collapseWhitespace: true, //移除空白字符
                minifyJS: true, 
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true
            }
        }),
        Autoprefixer,
        new ExtractTextPlugin('[name].css'),
        new VueLoaderPlugin(),
        new CopyWebpackPlugin([{
            from: path.resolve(__dirname, './src/config.js'),
            toType: 'file'
        }])
    ],
    devServer: isProduction ? '' : DevServer,
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'src')
        },
        extensions: ['.js', '.ts', '.json', '.less', '.css']
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    name: 'lib',
                    chunks: 'all',
                    minChunks: 2
                }   
            }
        }
    }
}

Webpack常用配置说明:

插件说明:
html-webpack-plugin: 用于处理html模板可以自动引入打包后的文件;
extract-text-webpack-plugin: 将css文件从js中分离;
style-resources-loader: 引入全局less文件;
less-plugin-functions: 自定义less函数;
autoprefixer: 配合postcss-loader实现自动添加css前缀; babel-loader: 处理ES6语法;
ts-loader: 处理TypeScript;
vue-loader: 处理.vue文件(webpack4.0之后处理vue需要引入插件vue-loader/lib/plugin);
copy-webpack-plugin: 用于拷贝文件;

目录结构

下面是我经常用的项目结构:

├── build 打包后目录
├── src
│   ├── assets/  静态文件目录
│   ├── components/  公共组件目录
│   ├── route/  `vue-router`路由
│   ├── store/ `vuex`目录
│   ├── style/  样式所在目录
│   ├── utils/ 工具函数目录
│   ├── views/  页面文件目录
│   ├── index.js 入口文件
│   ├── app.vue  
│   ├── config.js  全局配置文件
├── index.html
├── package.json
├── webpack.config.js
├── webpack.server.js
├── README.md

可以根据个人习惯进行更改;

开始使用

index.js即入口文件中引入vue,vue-router,vuex或者其他使用的框架,插件.
实例化一个vue实例,并挂载到页面之上.

import Vue from 'vue';
import App from './app'; // 主页面

const vm = new Vue({
	render: h => h(App) // 使用`render`函数渲染
}).$mount('#app') // 挂载到`html`页面上`id`为`app`的元素上;

流程: 入口文件(index.js) -> 页面文件(app.vue) -> 渲染并挂载($mount(el));

其他页面的展示都是在app.vue上,可以把app.vue当成是画板,我们实现的其他组件都是在此画板上作画;

路由

vue-router让我们可以在不同的路由地址显示不同的组件,使用也很简单;


// index.js
import Vue from 'vue';
import route from './route/index'; // 引入路由配置文件
import App from './app';

new Vue({
	el: '#app', // 与调用`$mount`一样  
	route,
	render: h => h(App);
})  

路由配置

// ./route/index.js  

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

export default new VueRouter({
	mode: hash / history (默认hash),
	route: [
		{
		path: '/', // 路由
		name: 'test', // 名称  
		component:  // 模板
	}
	]
})
// app.vue  

<template>
	<div>
		<router-view>/*路由模板显示的窗口*/</router-view>
	</div>
</template>

更多的配置翻阅vue-router官方文档;