走在前端的大道上javascript
新建目录 ss 和 test.js 文件:css
mkdir ss cd ss touch test.js
初始化目录生成 package.jsonhtml
npm init
npm set
用来设置项目初始化时默认值前端
$ npm set init-author-name 'your name' $ npm set init-author-email 'your email' $ npm set init-author-url 'your name' $ npm set init-license 'MIT'
首先nodejs默认已经安装vue
1.1 若是你的电脑是没有安装过vue-cli
,那么须要全局安装执行npm install vue-cli -g
,用vue -V
查看版本,用vue list
查看可选工具java
1.2 执行vue init webpack vuedemo3
在当前目录下建立vuedemo3的项目
安装选项能够参照下图node
而后就能够在目录中看到生成vuedemo3文件夹webpack
1.3 切换到vuedemo3文件夹
执行npm install
,就下载了项目所须要的包依赖ios
new Vue({ el:'#app', router, template:<App/>, components:{App} }) 或 new Vue({ router, template:<App/>, components:{App} }).$mount("#app");
new Vue({ router, render: h=>h(App) }).$mount("#app"); 或 new Vue({ router, render: function(h){ return h(App); ) }).$mount("#app");
在子组件<hello>里git
<slot name='world'></slot>
父组件使用
<hello> <span slot='world'> .... </span> </hello>
在项目中须要使用vue-resource
来与后台进行数据交互,项目前期使用本地json数据来模仿后台获取数据的流程
说明:查看版本vue -V
操做方法:
a、项目结构:本地的json文件放在最外层和index.html同级,叫作db.json。
b、在build的dev-server.js进行加入代码,位置如截图:
var apiServer = express() var bodyParser = require('body-parser') apiServer.use(bodyParser.urlencoded({ extended: true })) apiServer.use(bodyParser.json()) var apiRouter = express.Router() var fs = require('fs') apiRouter.route('/:apiName') .all(function (req, res) { fs.readFile('./db.json', 'utf8', function (err, data) { if (err) throw err var data = JSON.parse(data) if (data[req.params.apiName]) { res.json(data[req.params.apiName]) } else { res.send('no such api name') } }) }) apiServer.use('/api', apiRouter); apiServer.listen(port + 1, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:' + (port + 1) + '\n') })
在浏览器中查看(我安装了chrome游览器插件‘jsonView jsonViewer json formatter’,因此页面上的格式是美化过的)
vue使用element-ui的el-input监听不了回车事件,固然其余组件也有不能监听原生事件的
<el-input v-model="taskSeachText" @keyup.enter="handleClick"></el-input>
须要在事件后面加上.native
<el-input v-model="taskSeachText" @keyup.enter.native="handleClick"></el-input>
总结:写在一个封装好的组件上,有些标签的原生事件要.native 修饰符才能生效 #vue给组件绑定原生事件
咱们平时本地前端开发环境dev地址大可能是 localhost:8080,然后台服务器的访问地址就有不少种状况了,好比 127.0.0.1:8889,当前端与后台进行数据交互时,天然就出现跨域问题(后台服务没作处理状况下)。
如今经过在前端修改 vue-cli 的配置可解决:
vue-cli中的 client/config/index.js 下配置 dev选项的 {proxyTable}:
proxyTable: { // proxy all requests starting with /api to jsonplaceholder '/api': { target: 'http://127.0.0.1:8889/api', changeOrigin: true, onProxyReq (proxyReq, req, res) { } } }
实际上这是由于脚手架使用了中间件 http-proxy-middleware
源地址 | 转发地址 |
---|---|
localhost:8080/api | api.example.com/api |
localhost:8080/api/notifications | api.example.com/api/notifications |
若是咱们要去掉 api.example.com的api路径?
设置 pathRewrite
proxyTable: { '/api': { target: 'http://api.example.com', changeOrigin: true, pathRewrite: '^/api' : '', onProxyReq (proxyReq, req, res) { } } }
源地址 | 转发地址 |
---|---|
localhost:8080/api | api.example.com |
localhost:8080/api/notifications | api.example.com/notifications |
代理的好处 | 代理的问题 |
---|---|
解决开发时跨域问题 | 代码须要设置环境变量,prod环境下不存在 http-proxy-middleware 中间件 |
新建 ajax.js
import axios from 'axios' import store from '../store' // 超时设置 const http = axios.create({ timeout: 5000, baseURL: process.env.API_URL }) 或 // axios.defaults.baseURL = 'https://api.github.com'; // http request 拦截器 // 每次请求都为http头增长Authorization字段,其内容为token http.interceptors.request.use( config => { if (store.state.user.token) { config.headers.Authorization = `token ${store.state.user.token}`; } return config }, err => { return Promise.reject(err) } ); export default http
在入口文件 main.js 引入 ajax.js,并将其挂在到 Vue 全局方法下,即注册到Vue原型上。这样在.vue文件中直接使用this.$axios便可。固然你也能够在每一个须要用到axios的文件中单独引入。
import axios from './ajax' ... Vue.prototype.$axios = axios
*.vue
methods: { // 请求到数据并赋值给data里声明的变量 getData () { this.$axios.get('../../static/data/index.json').then((response) => { this.data = response.data }, (response) => { // error }) } }
一些经常使用的库也能够挂载到 Vue 的原型上,避免在每一个.vue单页面频繁import引入
非父子间的组件通讯官方的叫法 global bus。
// one.vue <template> <div> 这是one组件 <button @click="commit">给two组件发送信息</button> <p> {{ message }}</p> </div> </template> <script type="text/javascript"> import { bus } from './bus' export default { name: 'one', data () { return { message: '', } }, methods:{ commit () { bus.$emit('sendMsg',{ msg: '这条信息来自于one' }) } }, mounted () { bus.$on('backMsg', (data) => { this.message = data.msg; }) } }
// two.vue <template> <div @click="commit"> <p>这是two组件<button @click="commit">给one组件发送信息</button></p> <p>{{ message }}</p> </div> </template> <script type="text/javascript"> import { bus } from './bus' export default { name: 'two', data () { return { message: '' } }, methods:{ commit () { bus.$emit('backMsg',{ msg: '这条信息来自于two' }) } }, mounted () { bus.$on('sendMsg', (data) => { this.message = data.msg; }) } } </script>
最关键的bus,倒是最简单的
// bus.vue <script> import Vue from 'vue' export default { bus: new Vue(), } </script>
routes:[ { path:'/cart', name:'cart' component:Cart }, { path:'/goods/:goodId/post/:name', name:'goods' component:goodsList } ] html: <span>{{$route.params.goodId}}</span> <span>{{$route.params.name}}</span>
routes:[ { path:'/goods', name:'goods' component:goodsList, children:[ { path:'title', // 这里title不能加 / name:'title', compoent: Title }, { path:'img', name:'img', compoent: Image } ] } ] html: <router-link to="/goods/title">显示标题</router-link> <router-link to="/goods/img">显示图片</router-link> <router-view></router-view>
备注:
<router-view></router-view> 标签是盛放一级路由的 <router-link to="/goods/title"></router-link> 是路由跳转
$router.push("name") // name=/title $router.push({path:"name"}) $router.push({path:"name?goodId=123"}) 或者 $router.push({path:"name",query:{goodId:123}}) $router.go(1)
html获取参数 <span>{{$route.query.goodId}}</span>
备注:
获取页面跳转(js $router.push("name") )的参数 $route.query
获取路由的参数$route.params
命名的路由
<router-link :to="{name:'cart'}"></router-link> <router-link :to="{name:'goods',params:{goodId:123}}"></router-link>
命名的视图
<router-view></router-view> <router-view name="title"></router-view> <router-view name="img"></router-view> routes:[ { path:'/goods', name:'goods' components:{ default:GoodsList, title:Title, img:Image } },{ path:'/cart', name:'cart' component:Cart }]
vue-Resource 和 axios区别:resource是挂载到vue实例里面的
,axios是暴露了axios全局变量;axios的失败回调经过catch捕获
公用地址配置
http:{ //和methods 一级(并列) root: "http://" }
拦截器interceptors
munted:function(){ Vue.http.interceptors.push(function(request,next){ console.log("request init") next(function(response){ console.log("response init") return response }) }) }, methods:{ }
REST风格,7种API
methods: //同Vue.http.get this.$http.get('package.json',{ //http://www.imooc.com/course/AjaxCourseMembers?ids=796 params:{ userId:"101" }, headers:{ token:"abcd" } }).then(res => { this.msg = res.data; },error =>{ this.msg = error })
methods: this.$http.jsonp('http://www.imooc.com/course/AjaxCourseMembers?ids=796',{ this.msg = res.data; })
methods: this.$http.post('package.json',{ userId:"102" },{ headers:{ access_token:"abc" } }).then(res => { this.msg = res.data; },error =>{ this.msg = error })
methods: http:function(){ this.$http({ url:'package.json', methods:'GET', params:{ userId:'103' }, header:{ token:'123' }, timeout:50, before:function(){ console.log("before init") } }).then(function(res){ this.msg = res.data }) }
vue-Resource 和 axios区别:resource是挂载到vue实例里面的
,axios是暴露了axios全局变量;axios的失败回调经过catch捕获
公用地址配置
axios.defaults.baseURL = 'https://112...Server'
拦截器interceptors
munted:function(){ axios.interceptors.request.use(function(request){ console.log("request init") return request }) axios.interceptors.response.use(function(response){ console.log("request init") return response }) }, methods:{ }
axios.get('package.json',{ //http://www.imooc.com/course/AjaxCourseMembers?ids=796 params:{ userId:"999" }, headers:{ token:"jack" } }).then(res => { this.msg = res.data; }).catch(error =>{ console.log('error init') })
axios.post('package.json',{ //http://www.imooc.com/course/AjaxCourseMembers?ids=796 userId:"888" },{ headers:{ token:"tom" } }).then(res => { this.msg = res.data; }).catch(error =>{ console.log('error init') })
methods: http:function(){ axios({ url:'package.json', methods:'post', params:{ // get方式传参 userId:'111' }, data:{ // post方式传参 userId:'666' }, header:{ token:'http-test' } }).then(function(res){ this.msg = res.data }) }
同时须要stylus-loader
1.在项目根目录下安装
cnpm install --save js-base64
2.在项目文件中引入
let Base64 = require('js-base64').Base64;
3.在项目文件中使用
Base64.encode('dankogai'); // ZGFua29nYWk= Base64.encode('小飼弾'); // 5bCP6aO85by+ Base64.encodeURI('小飼弾'); // 5bCP6aO85by- Base64.decode('ZGFua29nYWk='); // dankogai Base64.decode('5bCP6aO85by+'); // 小飼弾 // note .decodeURI() is unnecessary since it accepts both flavors Base64.decode('5bCP6aO85by-'); // 小飼弾
1.在项目根目录下安装
cnpm install --save js-md5
2.在项目文件中引入
import md5 from 'js-md5';
3.在项目文件中使用
md5(''); // d41d8cd98f00b204e9800998ecf8427e md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6 md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0 // It also supports UTF-8 encoding md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07 // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer` md5([]); // d41d8cd98f00b204e9800998ecf8427e md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e // Different output md5(''); // d41d8cd98f00b204e9800998ecf8427e md5.hex(''); // d41d8cd98f00b204e9800998ecf8427e md5.array(''); // [212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126] md5.digest(''); // [212, 29, 140, 217, 143, 0, 178, 4, 233, 128, 9, 152, 236, 248, 66, 126] md5.arrayBuffer(''); // ArrayBuffer md5.buffer(''); // ArrayBuffer, deprecated, This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.
本节参考文章:vue中使用base64和md5
解决本地和服务器上资源url解析的问题
问题描述:
1.在img中的图片是彻底正确的, 但css中background-image: url()
的图片怎么都找不到.
2.最尴尬的是: 在npm run dev的时候一切正常
解决方法:
在 config/index.js 中修改 assetsPublicPath 为 ./ 在 build/utils.js 中的 ExtractTextPlugin.extract 传入参数 publicPath: '../../'
axios
的 post 请求后台接受不到!axios默认是 json 格式提交,确认后台是否作了对应的支持;
如果只能接受传统的表单序列化,就须要本身写一个转义的方法...
固然还有一个更加省事的方案,装一个小模块qs
npm install qs -S // 而后在对应的地方转就好了..单一请求也行,拦截器也行...我是写在拦截器的. // 具体能够看看我 axios 封装那篇文章 //POST传参序列化(添加请求拦截器) Axios.interceptors.request.use( config => { // 在发送请求以前作某件事 if ( config.method === "post" ) { // 序列化 config.data = qs.stringify(config.data); // ***** 这里转义 } // 如果有作鉴权token , 就给头部带上token if (localStorage.token) { config.headers.Authorization = localStorage.token; } return config; }, error => { Message({ // 饿了么的消息弹窗组件,相似toast showClose: true, message: error, type: "error.data.error.message" }); return Promise.reject(error.data.error.message); } );
element-ui 2.0 表单或者input组件 验证输入的数字检测出来是string
数字类型的验证须要在 v-model
处加上 .number
的修饰符,这是 Vue 自身提供的用于将绑定值转化为 number 类型的修饰符。el-input 的 type 属性设置为 "number"
<el-form-item label="年龄" prop="age"> <el-input type="number" v-model.number="ruleForm2.age"></el-input> </el-form-item>
解决方法:
.el-table__body-wrapper, .el-table__footer-wrapper, .el-table__header-wrapper{ width: 101%; }
更多问题总结: