使用 vue-cli( 脚手架) 搭建项目#
基于vue-cli 创建一个模板项目 通过 npm root -g 可以查看vue全局安装目录,进而知道自己有没有安装vue-cli 如果没有安装的话,使用如下命令全局安装 cnpm install -g vue-cli 创建一个基于webpack的新项目,在这过程中, 会安装依赖 vue init webpack 项目名 启动 cd vue-router-demo npm start
常用的目录结构#
如果我们的项目是通过脚手架搭建的,这已经是一个比较完善的种子项目了
|-- build : webpack 相关的配置文件夹(基本不需要修改) |-- config: webpack 相关的配置文件夹(基本不需要修改) |-- index.js: 指定的后台服务的端口号和静态资源文件夹 |-- node_modules: 在上面安装的依赖,都存放在这个文件夹下 |-- src : 源码文件夹,我们后续开发的组件和js分门别类的放在这里面 |-- main.js: 应用入口 js |-- static: 静态资源文件夹 |-- .babelrc: babel 的配置文件 |-- .editorconfig: 通过编辑器的编码/格式进行一定的配置 |-- .eslintignore: eslint 检查忽略的配置 |-- .eslintrc.js: eslint 检查的配置 |-- .gitignore: git 版本管制忽略的配置 |-- index.html: 主页面文件 |-- package.json: 他就相当于maven的pom.xml, 里面存放着相关的依赖信息和项目的版本信息 |-- README.md: 应用描述说明的 readme 文件
配置config/index.js#
可以在config/index.js中做一下的常用配置
- 添加跨域的配置
- 配置项目的主机名,端口号
- 配置是否打开浏览器
- 代码检查工具eslint
在开发的时候我们主要还是关注src文件, 后来需要的路由,store,ajaxApi,以及其他组件全部在创建在这个文件夹下
const path = require('path') module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: {}, //添加跨域的配置 // Various Dev Server settings host: 'localhost', // can be overwritten by process.env.HOST port: 9528, // 配置是否打开浏览器 autoOpenBrowser: true, //配置是否打开浏览器 errorOverlay: true, notifyOnErrors: false, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- // Use Eslint Loader? // If true, your code will be linted during bundling and // linting errors and warnings will be shown in the console. useEslint: false, // If true, eslint errors and warnings will also be shown in the error overlay // in the browser. showEslintErrorsInOverlay: false,
入口js文件 main.js的主要作用#
- 创建vue实例, 关联index.html中id为app的div代码块
- 添加项目中的路由模块 router
- 添加store模块---vuex
一般做好这不配置之后main就不用再改动了
import App from './App' import router from './router' import store from './store' Vue.use(ElementUI, { locale }) new Vue({ el: '#app', router, store, template: '<App/>', components: { App } })
根组件App.vue#
其实每一个组件都可以完整的拥有下面三部分, 当然如果哪个组件中不需要添加css样式,
可以把最后一个style或者script标签去掉
<template> <div> <!-- 这里存放 --> </div> </template> <//script> export default { name: 'app' } <///script> <style> </style>
组件间的相互调用#
比如根组件想使用hello.vue组件,怎么做呢?
像下面这样,三步走
- 第一步:引入组件
- 第二步:将组件映射成target标签
- 第三步使用标签
<template> <div> <!--第三步使用标签--> <hello/> <div/> <template/> <script> import hello form './XXX/hello.vue' export default{ // 将组件映射成标签 components:{ hello } } <style> </style>
第二步中引入标签时也可以去掉.vue后缀
或者直接这样写,是从@/ 代表的是 src/
import hello form '@/XXX/hello'
打包与发布#
打包#
- 打包的命令:
npm run build
项目经过打包,产出是一个dist文件,里面分别是index.html 和 静态资源文件夹, 这也是前后端分离开发的特色,后端想控制view层,也难了,只有一张index.html
发布方法1-静态服务器工具包#
命令:
npm install -g serve // 安装工具 serve dist
发布方法2-使用tomcat服务器#
注意点,使用tomcat当服务器,要求文件夹的名字和项目的名字要一样,修改的步骤如下:
- 修改
/build/webpack_prod.conf.js
文件
output:{ ... pathPath:'项目名称' }
- 编译重新打包
npm run build
- 把打包得到的dist文件夹改名,改成项目名
- 将改名完事后的文件拷贝到tomcat的webapps目录下,运行tomcat
eslint的编码规范检查#
好的习惯就是使用它,规范自己的代码风格, 但是也得说一下怎么禁用eslint'
- 方法一: 通过如果是webstorm编译器的话,点击file/settings/ , 搜索eslint,可以去掉enable
- 方法二: 编辑.eslintignore文件,添加自己想被忽略的文件
*.js *.vue 一般我们就写这两部分,这一下子全忽略了
因为eslint有个莫名其妙的要求,代码最后一行要求是空行,可以通过下面的方法三取消掉
- 方法三: 编辑.eslintrc.js
rules:{ ... // 添加 'indent':0 }
父子组件之间数据交互#
在差分组件的时候,本着多个组件共享的数据放在根组件的原则, 于是我们把共用的数据放在根组件,于此同时操作这些数据的方法也被我们定义在根组件,子组件想要使用这些数据,想要操作这些数组怎么办呢? 像下面那样,进行组件之间的数据传递
- 在父组件中给子组件传递方法或数据
使用:强制数据绑定的方法, ChildTarget是我们在components模块将子组件映射得来的子组件标签, name可以是vue中data的方法,也可以是属性
<template> <ChildTarget :name="name"/> </template>
- 子组件取出父组件传递过来的值
export default{ props:['name','name2'] }
数据的交互@click
#
最常用的就是使用@click="方法名"
, 或者@click="value = !value"
或者@click="value = true
如果我们向上面那样, 把公共的数据放在父组件中, 那么事件的触发一定是发生在子组件中, 子组件一般通过@click
给模板中的元素绑定上指定的动作,进而调用父组件的传递进来的方法,操作父组件传递进来的值
此外,在所有的组件中,vue的data部分都向下面这样写,是规定
data(){ return{ name:'' } }
- 常用的监视watch模块
watch:{ 监视的data中的对象 name:{ deep:true, // 深度监视 handler: function(value){ // value就是变化后的新的值 // todo } } }
- 缓存模块
从缓存中把去出来的字符串转换成json串
JSON.parse(window.localStorage.getItem('')||'默认值');
把对象,存储进浏览器的缓存
window.localStorage.setItem('自定义的key',JSON.stringfy(value))
消息订阅,打破父子组件信息传递的约束#
像上面那样,如果不存在父子组件的关系,父组件不引入子组件,也就没办法把他映射成标签, 既然映射不成标签也就没法像上面那样,通过 : 冒号 强制进行数据的绑定达到传递值的效果,于是有了消息订阅
组件之间的通信方式: 发布/订阅
绑定监听: 订阅事件
触发事件: 发布事件
借助插件-pubsub.js
安装命令:
npm install --save pubsub-js
场景: 我们给模板上的按钮绑定点击事件,一旦被点解他就发布事件
- 在使用前需要导入PubSub对象
import PubSub from 'pubsub-js'
使用:消息的发布
<button @click="search">Search</botton> export default{ methods:{ search(name){ // search是方法名 // name 是携带的参数,没参数就不用写 Publish.publish('search',name) } } }
消息的订阅:
- 依然是第一步:引入PubSub对象
- 编码实现:
mounted: { PubSub.subscribe("search",(name)=>{ // todo with name });
异步请求#
安装插件axios
npm install axios --save
- 在使用之间同样是需要引入:
import axios from 'axios'
发送一个get请求
axios.get(url) .then(res=>{ // todo with res }) .catch(error){ // todo }