2019独角兽企业重金招聘Python工程师标准>>>

一、课程介绍

课程地址:https://www.imooc.com/learn/935

1.概要

2.vue-loader+webpack项目配置

安装vs-code和插件

EditorConfig for VS Code
ESLint
gitignore
language-stylus
Nunjucks
One Dark Pro
PostCSS syntax
Vetur
View In Browser
vscode-icons

软件配置

{"window.zoomLevel": 2,"editor.fontSize": 20,"workbench.iconTheme": "vscode-icons","files.autoSave": "onFocusChange","terminal.integrated.fontSize": 20,"editor.tabSize": 2
}

打开命令行:ctrl+~

初始化项目

npm init

安装

npm i webpack@^3.10.0 vue vue-loader@^13.6.0

注意:

A.webpack需要安装到4版本以下

B.vue-loader需要安装15版本以下(参考官方文档 https://vue-loader.vuejs.org/migrating.html#a-plugin-is-now-required . Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的)

安装警告依赖

npm i css-loader vue-template-compiler

初始化好了

新建src/app.vue

<template><div id="test">{{text}}</div>
</template>
<script>
export default {data(){return{text:'abc'}}
}
</script>
<style>
#test{color: red}
</style>

添加脚本

index.js

import Vue from 'vue'
import App from './app.vue'const root = document.createElement('div')document.body.appendChild(root)new Vue({render:(h) => h(App)
}).$mount(root)

webpack.config.js

"build": "webpack --config webpack.config.js"

执行打包命令

npm run build

生成dist文件夹

红色报错,说明没有编译器解释

npm run build

3. webpack配置项目加载各种静态资源及css预处理器

npm i style-loader url-loader file-loader

url-loader是建立在file-loader基础上的,base64,。

limit对文件大小做限制。

use不仅是读取,还包括做的一些处理。

[name]原文件名,[ext]扩展名

如运行还有其他报错,可参考上图给安装依赖版本

npm run build

新建styles/test-stylus.styl样式文件,写法很随意,可以不要大括号和冒号等

npm run build

需要安装stylus-loader

npm i stylus-loader stylus

4.webpack-dev-server的配置使用

安装

npm i webpack-dev-server@^2.9.7

这个版本应该与webpack版本相互兼容,3.1.5版本会报错,推测要在3以下

针对不同平台的依赖

npm i cross-env

说明:mac上不需要用set,windows上需要

配置好dev

引入html的插件

安装

npm i html-webpack-plugin

配置

使用插件,在js中可以直接引用环境判断,vue可以根据不同环境打包,开发环境会有很多错误提示,但是正式环境不需要

npm run dev

打开查看

设置热加载

package.js(部分)

"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "cross-env NODE_ENV=production webpack --config webpack.config.js","dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"},

webpack.config.js

const path = require('path')const HTMLPlugin = require('html-webpack-plugin')
const webpack = require('webpack')const isDev = process.env.NODE_ENV === 'development'const config = {target: 'web',entry:path.join(__dirname,'src/index.js'),output: {filename: 'bundle.js',path: path.join(__dirname, 'dist')},module: {rules: [{test: /\.vue$/,loader: 'vue-loader'},{test: /\.css$/,use: ['style-loader','css-loader']},{test: /\.styl/,use: ['style-loader','css-loader','stylus-loader']},{test: /\.(gif|jpg|jepg|png|svg)$/,use: [{loader: 'url-loader',options: {limit: 1024,name: '[name]-aaa.[ext]'}}]}]},plugins: [new webpack.DefinePlugin({'process.env': {NODE_ENV: isDev ? '"development"' : '"production"'}}),new HTMLPlugin()]
}if (isDev) {config.devtool = '#cheap-module-eval-source-map' // 浏览器打开后,通过映射以编译后我们能看懂方式调整,source-map最完整映射关系,但是编译效率比较低,文件比较大,eval可能看起来会比较乱,出现行对应不齐的问题。而推荐的这个效率比较高config.devServer = {port: 8000,host: '0.0.0.0',overlay: {errors: true,},hot: true // 改了一个组件的代码,只重新渲染这个组件,不贵整个页面渲染// historyFallback: {// }// 入口地址映射,(略)// open: true //启动后自动打开页面},config.plugins.push(new webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin() // 不需要信息展示的问题)
}module.exports = config

二、vue2介绍和项目实践

1.vue2的核心知识介绍

2.配置vue的jsx写法以及postcss

安装插件

npm i postcss-loader autoprefixer babel-loader babel-core

项目文件夹下创建babelrc和postcss.config.js配置文件

postcss是在css文件都编译完之后,通过autoprefixer对其优化,需要加入浏览器前缀支持的

将vue-jsx文件的转化

npm i babel-preset-env babel-plugin-transform-vue-jsx

安装依赖

编译处理

更快一些

npm i babel-helper-vue-jsx-merge-props@^2.0.0 css-loader@^0.28.7 babel-plugin-syntax-jsx
npm run dev

打包没报错即可

3. 实现todo应用的界面

调整assets文件夹到src下

删除之前测试使用的

新建src/todo及其以下文件

新建assets/styles/globel.styl文件

引入

样式内容略,删除app.vue的内容

样式具体内容略。lang指定预处理器,scoped仅仅对本组件作用

(1)基本组件的引用,样式

header.vue

<template><header class="main-header"><h1>Todo</h1></header>
</template>
<style lang = 'stylus' scoped>
.main-header{text-align centerh1{font-size 100pxcolor rgba(175,47,47,0.6)font-weight 500margin 20px}
}
</style>

todo.vue

<template><section class="real-app"><input type="text"class="add-input"autofocus='autofocus'placeholder="接下来要做什么"@keyup.enter="addTodo"><item :todo='todo'></item><!-- @keyup 也就等于 v-on:keyup --><tabs :filter = 'filter'></tabs></section>
</template>
<script>
import Item from './item.vue'
import Tabs from './tabs.vue'
export default {data() {return{todo:{id:0,content:'this is todo',completed: false},filter:'all'}},methods: {addTodo(){}},components: {Item,Tabs}
}
</script>
<style lang=stylus scoped>
.real-app{width 70%min-width 500pxpadding 10pxbackground #ffffffcolor #555555margin 20px autobox-shadow 0 0 10px 5px rgba(0,0,0,0.5).add-input{width 84%font-size 24pxborder nonemargin 0 6%padding 20px 2%outline noneborder-bottom 1px solid #fff}.add-input:hover{color #333border-bottom 1px solid #ccccursor pointer}
}
</style>

tabs.vue

<template><div class="helper"><span class="left">2 items left</span><span class="tabs"><spanv-for="state in states":key="state":class="[state, filter === state ? 'actived' : '']"@click="toggleFilter(state)">{{state}}</span></span><span class="clear" @click="clearAllCompleted" type='button'>Clear Completed</span></div>
</template><script>
export default {props: {filter: {type: String,required: true}},data(){return{states:['all', 'active','completed']}},methods: {clearAllCompleted (){},toggleFilter(){}}
}
</script>
<style lang="stylus" scoped>
.helper{text-align center.left{width:18%;display inline-block}.tabs{width 50%display inline-blockmargin 10px autospan{min-width 33%display inline-block }span:hover{cursor pointercolor orange}span.actived{color red}}.clear{ width 30%display inline-block color:greyborder noneoutline none}.clear:hover{color blackcursor pointer}input[type='button']{border-width 0}
}
</style>

item.vue

<template><div :class="['todo-item',todo.completed ? 'completed' : '']"><input type="checkbox"class="toggle"v-model="todo.completed"><label>{{todo.content}}</label><button class="destory" @click="deleteTodo"></button></div>
</template>
<script>
export default {props:{todo:{type:Object,required:true}},methods:{deleteTodo(){}}
}
</script><style lang=stylus scoped>
.todo-item{vertical-align text-topborder nonepadding 15px 2%width 88%margin 10px 4%border-bottom 1px solid #eeefont-size 28pxinput[type="checkbox"],input[type="checkbox"]:checked{vertical-align text-topwidth 30pxheight 30px}.destory{width 30pxheight 30pxfloat  right}
}
</style>

footer.jsx

import '../assets/styles/footer.styl'
export default {data() {return {author: 'Jhon'}},render(){return (<div id="footer"><span>written by {this.author}</span></div>)}
}

footer.styl

#footerbackground:rgba(0,0,0,0.2)text-align: centermargin-top: 50px

global.styl

bodybackground-image: url('../images/bg.jpg')

4.实现todo应用的业务逻辑

(1)添加和删除操作

父子组件通信

(2)数量统计,tab切换面板,clear清除所选item

至此代码:

tabs.vue

<template><div class="helper"><span class="left">{{unFinishedTodoLength}} items left</span><span class="tabs"><spanv-for="state in states":key="state":class="[state, filter === state ? 'actived' : '']"@click="toggleFilter(state)">{{state}}</span></span><span class="clear" @click="clearAllCompleted">Clear Completed</span></div>
</template><script>
export default {props: {filter: {type: String,required: true},todos: {type: Array,required: true}},data(){return{states:['all', 'active','completed']}},methods: {clearAllCompleted (){this.$emit('clearAllcompleted')},toggleFilter(state){this.$emit('toggle', state)}},computed: {unFinishedTodoLength(){return this.todos.filter(todo => !todo.completed).length}}
}
</script>
<style lang="stylus" scoped>
.helper{text-align center.left{width:18%;display inline-block}.tabs{width 50%display inline-blockmargin 10px autospan{min-width 33%display inline-block }span:hover{cursor pointercolor orange}span.actived{color red}}.clear{ width 30%display inline-block color:greyborder noneoutline none}.clear:hover{color blackcursor pointer}input[type='button']{border-width 0}
}
</style>

todo.vue

<template><section class="real-app"><input type="text"class="add-input"autofocus='autofocus'placeholder="接下来要做什么"@keyup.enter="addTodo"><item :todo='todo'v-for="todo in filterdTodos":key="todo.id"@del="deleteTodo"/><!-- @keyup 也就等于 v-on:keyup --><tabs :filter = 'filter' :todos="todos"@toggle='toggleFilter'@clearAllcompleted="clearAllcompleted"/></section>
</template>
<script>
import Item from './item.vue'
import Tabs from './tabs.vue'
let id = 0
export default {data() {return{todos:[],filter:'all'}},methods: {addTodo(e){this.todos.unshift({id: id++,content: e.target.value.trim(),completed: false})e.target.value =''},deleteTodo(id){this.todos.splice(this.todos.findIndex(todo => todo.id === id), 1)},toggleFilter(state){this.filter = state},clearAllcompleted(){this.todos = this.todos.filter(todo => !todo.completed)}},computed: {filterdTodos(){if (this.filter === 'all'){return this.todos}// 判断const completed = this.filter === 'completed'return this.todos.filter(todo => completed === todo.completed)}},components: {Item,Tabs}
}
</script>
<style lang=stylus scoped>
.real-app{width 70%min-width 500pxpadding 10pxbackground #ffffffcolor #555555margin 20px autobox-shadow 0 0 10px 5px rgba(0,0,0,0.5).add-input{width 84%font-size 24pxborder nonemargin 0 6%padding 20px 2%outline noneborder-bottom 1px solid #fff}.add-input:hover{color #333border-bottom 1px solid #ccccursor pointer}
}
</style>

item.vue

<template><div :class="['todo-item',todo.completed ? 'completed' : '']"><input type="checkbox"class="toggle"v-model="todo.completed"><label>{{todo.content}}</label><button class="destory" @click="deleteTodo"></button></div>
</template>
<script>
export default {props:{todo:{type:Object,required:true}},methods:{deleteTodo(){this.$emit('del', this.todo.id)}}
}
</script><style lang=stylus scoped>
.todo-item{vertical-align text-topborder nonepadding 15px 2%width 88%margin 10px 4%border-bottom 1px solid #eeefont-size 28pxinput[type="checkbox"],input[type="checkbox"]:checked{vertical-align text-topwidth 30pxheight 30px}.destory{width 30pxheight 30pxfloat  right}
}
</style>

三、webpack配置优化

1. 配置css单独分离打包

npm i extract-text-webpack-plugin

添加引入,isDev判断为true,false,同时剪切module-rules-styl的编译

粘贴到dev时候的设置里

增加else里的判断,style-loader可以用fallback,打包后的速度更快

const path = require('path')const HTMLPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const ExtractPlugin = require('extract-text-webpack-plugin')
const isDev = process.env.NODE_ENV === 'development'const config = {target: 'web',entry:path.join(__dirname,'src/index.js'),output: {filename: 'bundle[hash:8].js',path: path.join(__dirname, 'dist')},module: {rules: [{test: /\.vue$/,loader: 'vue-loader'},{test: /\.jsx/,loader: 'babel-loader'},{test: /\.(gif|jpg|jepg|png|svg)$/,use: [{loader: 'url-loader',options: {limit: 1024,name: '[name]-aaa.[ext]'}}]}]},plugins: [new webpack.DefinePlugin({'process.env': {NODE_ENV: isDev ? '"development"' : '"production"'}}),new HTMLPlugin()]
}if (isDev) {config.module.rules.push({test: /\.styl/,use: ['style-loader','css-loader',{loader: 'postcss-loader',options: {sourceMap: true,}},'stylus-loader']})config.devtool = '#cheap-module-eval-source-map' // 浏览器打开后,通过映射以编译后我们能看懂方式调整,source-map最完整映射关系,但是编译效率比较低,文件比较大,eval可能看起来会比较乱,出现行对应不齐的问题。而推荐的这个效率比较高config.devServer = {port: 8000,host: '0.0.0.0',overlay: {errors: true,},hot: true // 改了一个组件的代码,只重新渲染这个组件,不贵整个页面渲染// historyFallback: {// }// 入口地址映射,(略)// open: true //启动后自动打开页面},config.plugins.push(new webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin() // 不需要信息展示的问题)
} else{config.output.filename = '[name][chunkhash:8].js'config.module.rules.push({test: /\.styl/,use: ExtractPlugin.extract({fallback: 'style-loader',use: ['css-loader',{loader: 'postcss-loader',options: {sourceMap: true}},'stylus-loader']})}  ),config.plugins.push(new ExtractPlugin('styles.[contentHash:8].css'))
}module.exports = config
npm run build

打包生成文件名

附带:package.json

{"name": "vue-ssr-tech","version": "1.0.0","description": "","main": "webpack.config.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "cross-env NODE_ENV=production webpack --config webpack.config.js","dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"},"author": "","license": "ISC","dependencies": {"autoprefixer": "^7.2.3","babel-core": "^6.26.3","babel-helper-vue-jsx-merge-props": "^2.0.0","babel-loader": "^7.1.2","babel-plugin-syntax-jsx": "^6.18.0","babel-plugin-transform-vue-jsx": "^3.7.0","babel-preset-env": "^1.7.0","cross-env": "^5.1.3","css-loader": "^0.28.7","extract-text-webpack-plugin": "^3.0.2","file-loader": "^1.1.11","html-webpack-plugin": "^3.2.0","postcss-loader": "^3.0.0","style-loader": "^0.22.1","stylus": "^0.54.5","stylus-loader": "^3.0.2","url-loader": "^1.0.1","vue": "^2.5.17","vue-loader": "^13.7.2","vue-template-compiler": "^2.5.17","webpack": "^3.10.0","webpack-dev-server": "^2.9.7"},"devDependencies": {}
}

如有版本报错,可根据上面替换安装

2.区分打包类库代码及hash优化

让浏览器加载更快

npm run build

hash和chunkhash区别:

chunkhash是每个模块一个hash,hash会有区别,而hash是整个应用一个hash

webpack.config.js

const path = require('path')const HTMLPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
const ExtractPlugin = require('extract-text-webpack-plugin')
const isDev = process.env.NODE_ENV === 'development'const config = {target: 'web',entry:path.join(__dirname,'src/index.js'),output: {filename: 'bundle[hash:8].js',path: path.join(__dirname, 'dist')},module: {rules: [{test: /\.vue$/,loader: 'vue-loader'},{test: /\.jsx/,loader: 'babel-loader'},{test: /\.(gif|jpg|jepg|png|svg)$/,use: [{loader: 'url-loader',options: {limit: 1024,name: '[name]-aaa.[ext]'}}]}]},plugins: [new webpack.DefinePlugin({'process.env': {NODE_ENV: isDev ? '"development"' : '"production"'}}),new HTMLPlugin()]
}if (isDev) {config.module.rules.push({test: /\.styl/,use: ['style-loader','css-loader',{loader: 'postcss-loader',options: {sourceMap: true,}},'stylus-loader']})config.devtool = '#cheap-module-eval-source-map' // 浏览器打开后,通过映射以编译后我们能看懂方式调整,source-map最完整映射关系,但是编译效率比较低,文件比较大,eval可能看起来会比较乱,出现行对应不齐的问题。而推荐的这个效率比较高config.devServer = {port: 8000,host: '0.0.0.0',overlay: {errors: true,},hot: true // 改了一个组件的代码,只重新渲染这个组件,不贵整个页面渲染// historyFallback: {// }// 入口地址映射,(略)// open: true //启动后自动打开页面},config.plugins.push(new webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin() // 不需要信息展示的问题)
} else{config.entry = {app: path.join(__dirname,'src/index.js'),vendor: ['vue']}// config.output.filename = '[name].[hash:8].js'config.output.filename = '[name].[chunkhash:8].js'config.module.rules.push({test: /\.styl/,use: ExtractPlugin.extract({fallback: 'style-loader',use: ['css-loader',{loader: 'postcss-loader',options: {sourceMap: true}},'stylus-loader']})}  ),config.plugins.push(new ExtractPlugin('styles.[contentHash:8].css'),new webpack.optimize.CommonsChunkPlugin({name: 'verdor'}),// 在有新的模块加入的时候,webpack是会给新模块加入id的,插入顺序不同,倒是id会变化,使用浏览器的缓存就是去效果,这种方式可以规避。verdor要放在runtime前面new webpack.optimize.CommonsChunkPlugin({name: 'runtime'}))
}module.exports = config

四、总结

搭建项目-webpack构建(eg:vue-loader,jsx->babel,静态资源,缓存)

webpack中文网:https://www.webpackjs.com/

webapck官网(要翻墙):http://webpack.github.io/

配置很多

vue开发todo应用,.vue文件,数据传递,拆分组建,双向绑定,虚拟DOM,jsx文件-复杂场景(vue2)

错误解答

1.No parser and no filepath given

npm install vue-loader@^13.7.2

2.You may need an appropriate loader to handle this file type

解决:可能有些包的版本不合适,需要更改

转载于:https://my.oschina.net/u/3018050/blog/1924538

Vue+Webpack打造todo应用相关推荐

  1. Vue+Webpack打造todo应用(慕课学习笔记)

    这门课在慕课网是免费的,但有部分包已被弃用需要用其他包代替,详细见官网.我还不想看官网,所以先放着吧. 关于模块打包的课程可以重刷 [仅个人记录,还不完整.暂时没有参考意义哦] 别人的项目源码.我的项 ...

  2. Vue.js 打造酷炫的可视化数据大屏

    可视化技术与 Vue 介绍 实验介绍 在本节实验中,将对可视化技术的应用场景.发展历程进行介绍,让大家对可视化技术有一个基础的概念.随后将介绍如今流行的可视化框架与其之间的优缺点对比.最后介绍 Vue ...

  3. vue做混合式app_Vue Cordova教程-Vue+Cordova打造跨平台可安装的混合APP视频教程(大地)...

    Vue+Cordova打造跨平台可安装的混合APP视频教程 必看说明: 目前购买此教程送Html5+Cordova+Ionic智能电视(TV)应用开发教程视频教程: 购买过Ionic的同学可以直接在( ...

  4. 用vue+webpack搭建的前端项目结构

    上个项目第一次用到vue+webpack,也是我第一次尝试自动化.模块化的开发方式,总的来说就是结构太烂,开发体验差,效率低,难维护.细数的罪状有如下几条 没有servies层,全部ajax接口都和逻 ...

  5. Vue + webpack 项目实践

    最近在内部项目中做了一些基于 vue + webpack 的尝试,在小范围和同事们探讨之后,还是蛮多同学认可和喜欢的,所以通过 blog 分享给更多人. 首先,我会先简单介绍一下 vue 和 webp ...

  6. vue 判断页面加载完成_在Vue+webpack中详细讲解基础配置

    这篇文章主要介绍了Vue+webpack项目基础配置教程,需要的朋友可以参考下. 最近在学习webpack,跟着课程一个单页面应用,在这里记录一下. 这个部分主要讲了如何配置webpack的环境,以及 ...

  7. 从零构建vue+webpack (一)

    写在前面: 给自己看,日常写业务有点儿繁琐,尝试着用vue+webpack 从零开始构建一个项目! 1.新建项目文件夹 运行命令 npm init (一路回车或者-y) 2.打开项目,新建src 文件 ...

  8. 踩坑之旅:springboot+vue+webpack项目实战(一)

    2019独角兽企业重金招聘Python工程师标准>>> 网上关于springboot的小项目很多,node.js+vue的项目也很多,但是好像没有两者合一的项目,最近在想实践下将两者 ...

  9. [vue] webpack打包vue速度太慢怎么办?

    [vue] webpack打包vue速度太慢怎么办? 升级webpack4,支持多进程 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主目录 与歌谣 ...

  10. [vue] 使用vue开发一个todo小应用,谈下你的思路

    [vue] 使用vue开发一个todo小应用,谈下你的思路 结构: 输入部分( input )和输出部分( ul ) 逻辑:用户输入之后,通过事件触发拿到用户输入的数据存起来, 将用户数据集合通过 v ...

最新文章

  1. 数据结构(05)— 线性单链表实战
  2. php 多人游戏_「谁会是下一个王者农药」云服务器如何搭建游戏服务器?
  3. Unity Remote使用方法
  4. poj3279 Fliptile
  5. 求n个数中第k大的数_互联网高频面试题目:「回溯算法」求组合总和
  6. Arithmetic Sequence 三分,货仓选址,nth_element,__int128(济南)
  7. php limit限流,php+redis 限流
  8. seo建设者_SEO建设者,有哪些说不出的苦?
  9. 按钮设置成透明的方法
  10. php的修改数据库语句怎么写,php的数据库修改语句是什么
  11. java 安卓视频播放器_java - 学习做一个安卓视频播放器,有一些小问题!忘大家请教...
  12. 【Linux】【Services】【SaaS】Docker+kubernetes(11. 构建复杂的高可用网络)
  13. java 私有成员方法_Java Reflection 教程(7):类私有成员变量和方法
  14. 谷歌(Google Chrome)插件安装
  15. CCNA配置试验之八 帧中继——点到点子接口(point-to-point)的配置
  16. compute和compute by
  17. C#更新word目录
  18. 有一种友谊可以美的让人心颤——CHANDLER和JOEY 转贴 来自friends论坛
  19. sql中的类型转换---学习
  20. 电脑快捷键快速关机方法,电脑如何快速关机

热门文章

  1. atitit 未来学课程体系.docx
  2. Atitit 软件开发中的艾提拉思想与理念总结 后端优先 手机优先 做好政治动员 高层抽象 一定要出理论结果书籍总结 技术就是艺术 三个软件层次的划分 实现层 规划层 艺术层 无限生
  3. Atitit ftp概念与ftpclient 目录 1. Concept 1 1.1. Tftp(simple ftp) sftp ssh port22 1 1.2. ftp server
  4. Atitit java 原生 客户端 native desktop桌面 javafx 浏览器环境 导入jar jfxrt.jar 17M package com.attilax.ui;
  5. atitit 好的企业文化确实可能降低企业短期效率但是必须的.docx
  6. Atitit 游戏的原理与概论attilax总结
  7. paip.java swt 乱码问题解决
  8. paip.验证码识别---判断图片是否是彩色图片
  9. 朴灵:云计算的开发者视界中,OpenAPI 是绝对主角 | 凌云时刻
  10. 【情感识别】基于matlab GUI SVM语音情感识别(带面板)【含Matlab源码 876期】