🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
第一讲 Webpack+Vue快速入门 === [TOC] ## 安装Vue 在用 Vue.js 构建大型应用时推荐使用 NPM 安装, NPM 能很好地和诸如 [Webpack](http://webpack.github.io/) 模块打包器配合使用。 1、 首先下载安装Node.js开发环境 [Node.js](http://nodejs.cn/) 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 > *Node*是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。*Node*对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好。 2、 全局安装vue和客户端命令行工具集合vue-cli ~~~ npm install -g @vue/cli ~~~ ## 创建基于Webpack+Vue2的hello-vue项目 > 由于项目实践中极少使用原生的Vue语法,所以教程不再介绍。Uni-app采用类似的Webpack+Vue架构, 所以本教程主要介绍Webpack+Vue架构的项目解构 创建项目 ``` $vue init webpack hello-vue ``` > hello-vue是创建的项目名称,创建过程需要回答一系列的问题,全部选择默认值和Yes ## 运行项目 首先安装依赖的nodejs 模块 ``` $cd hello-vue $npm install ``` 运行程序,启动服务器,默认是打开8080端口 ``` $npm run dev ``` 执行在package.json中定义的脚本`dev` 也可以执行脚本 ``` $npm run dev ``` ``` "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "unit": "jest --config test/unit/jest.conf.js --coverage", "e2e": "node test/e2e/runner.js", "test": "npm run unit && npm run e2e", "lint": "eslint --ext .js,.vue src test/unit test/e2e/specs", "build": "node build/build.js" }, ``` 生成的package.json文件 ``` { "name": "hello-vue", "version": "1.0.0", "description": "A Vue.js project", "author": "zengqs <pypzengqs@126.com>", "private": true, "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "unit": "jest --config test/unit/jest.conf.js --coverage", "e2e": "node test/e2e/runner.js", "test": "npm run unit && npm run e2e", "lint": "eslint --ext .js,.vue src test/unit test/e2e/specs", "build": "node build/build.js" }, "dependencies": { "vue": "^2.5.2", "vue-router": "^3.0.1" }, "devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-eslint": "^8.2.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-jest": "^21.0.2", "babel-loader": "^7.1.1", "babel-plugin-dynamic-import-node": "^1.2.0", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", "babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-vue-jsx": "^3.5.0", "babel-preset-env": "^1.3.2", "babel-preset-stage-2": "^6.22.0", "babel-register": "^6.22.0", "chalk": "^2.0.1", "chromedriver": "^2.27.2", "copy-webpack-plugin": "^4.0.1", "cross-spawn": "^5.0.1", "css-loader": "^0.28.0", "eslint": "^4.15.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.7.1", "eslint-plugin-import": "^2.7.0", "eslint-plugin-node": "^5.2.0", "eslint-plugin-promise": "^3.4.0", "eslint-plugin-standard": "^3.0.1", "eslint-plugin-vue": "^4.0.0", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^1.1.4", "friendly-errors-webpack-plugin": "^1.6.1", "html-webpack-plugin": "^2.30.1", "jest": "^22.0.4", "jest-serializer-vue": "^0.3.0", "nightwatch": "^0.9.12", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", "portfinder": "^1.0.13", "postcss-import": "^11.0.0", "postcss-loader": "^2.0.8", "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "selenium-server": "^3.0.1", "semver": "^5.3.0", "shelljs": "^0.7.6", "uglifyjs-webpack-plugin": "^1.1.1", "url-loader": "^0.5.8", "vue-jest": "^1.0.2", "vue-loader": "^13.3.0", "vue-style-loader": "^3.0.1", "vue-template-compiler": "^2.5.2", "webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] } ``` ## 运行 ``` http://127.0.0.1:8080/#/ ``` ## 项目的目录结构 ![](https://box.kancloud.cn/7033521c9beefc507464e3a76aada497_1024x725.png) ## 安装Vue.js devtools工具调试Vuejs项目 ![](https://box.kancloud.cn/425de715f6020477d39eafdd09b8c1fb_1125x352.png) ## 代码分析 ### 定义组件component > 在Webpack+Vue模式下,所有的页面都可以理解一个组件,以`.vue`后缀的文件 ``` src/component/HelloWorld.vue ``` ```html <template> <div> <h1>{{ msg }}</h1> </div> </template> <script> export default { name: "HelloWorld", data() { return { msg: "Welcome to Your Vue.js App" }; } }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h1 { font-weight: normal; } </style> ``` ### 路由 路由定义文件 ``` /src/router/index.js ``` ```javascript import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld } ] }) ``` 通过import命令导入定义好的组件 ``` import HelloWorld from '@/components/HelloWorld' ``` 然后定义路由的路径path,路由的名称name和对应的组件component。 > 如果增加新的路由,可以加到routes数组中。 ### 测试 ``` http://127.0.0.1:8080/#/ ``` ## 单文件组件 .vue 文件是一个自定义的文件类型,用类 HTML 语法描述一个 Vue 组件。每个 .vue 文件包含三种类型的顶级语言块`<template>`、`<script>` 和` <style>`。 ```html <template> </template> <script> </script> <style> </style> ``` * template语言块用于编写页面的定义代码 * script语言块编写页面的模块Javascript代码 * style语言块用于编写样式定义脚本 > 在 .vue 文件中, template 中都是html 代码,它定义了在页面中显示的内容,由于里面还有变量,也可以说定义了一个模版;script中都是js 代码,它定义这个组件中所需要的数据和及其操作,style 里面是css 样式,定义这个组件的样式,scoped 表明这里写的css 样式只适用于该组件,可以限定样式的作用域。 **script 标签中 export defalut 后面的对象的理解** 在不使用.vue 单文件时,我们是通过 Vue 构造函数创建一个 Vue 根实例来启动vuejs 项目,Vue 构造函数接受一个对象,这个对象有一些配置属性 el, data, component, template 等,从而对整个应用提供支持。 ~~~ new Vue({ el: '#app', data: { msg: "hello Vue" } }) ~~~ 在.vue文件中,export default 后面的对象 就相当于 new Vue() 构造函数中的接受的对象,它们都是定义组件所需要的数据(data), 以及操作数 据的方法等, 更为全面的一个 export default 对象,有methods, data, computed, 这时可以看到, 这个对象和new Vue() 构造函数中接受的对象是一模一样的。但要注意data 的书写方式不同。在 .vue 组件, data 必须是一个函数,它return(返回一个对象),这个返回的对象的数据,供组件实现。 ## 添加一个组件 ### 定义组件 ``` /src/components/SayHi.vue ``` 代码如下 ``` <template> <div> <input type="text" v-model="message" placeholder="消息"> <div class="message">{{ reversedMessage }}</div> </div> </template> <script> export default { data() { return { message: "Hello world!" }; }, computed: { reversedMessage: function() { // `this` 指向 vm 实例 return this.message .split("") .reverse() .join(""); } } }; </script> <style> .message { font-size: 20px; } </style> ``` ### 修改路由定义文件 ``` /src/router/index.js ``` ``` import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' //新增加的组件的导入 import SayHi from '@/components/SayHi' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/say_hi', //新增组件的路由 name: 'SayHi', component: SayHi } ] }) ``` ### 测试 ``` http://127.0.0.1:8080/#/say_hi ```