在路由里每一个都添加一个metajavascript
[{
path:'/login', meta: { title: '登陆页面' }, component:'login' }]
钩子函数:php
在main.js中添加以下代码css
router.beforeEach((to, from, next) => { window.document.title = to.meta.title; next() })
首先安装axios:
1.利用npm安装npm install axios –save
2.利用bower安装bower install axios –save
3.直接利用cdn引入html
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
通常状况上传照片有两种方式:前端
操做简单,适合小图,以及若是想兼容低版本的ie没办法用此方法vue
form表单提交图片会刷新页面,也能够时form绑定到一个隐藏的iframe上,能够实现无刷新提交数据。html5
这里只讲解一下第二种方式:
html代码:java
<input name="file" type="file" accept="image/png,image/gif,image/jpeg" @change="update"/>
js代码:node
import axios from 'axios' // 添加请求头 update (e) { // 上传照片 var self = this let file = e.target.files[0] /* eslint-disable no-undef */ let param = new FormData() // 建立form对象 param.append('file', file) // 经过append向form对象添加数据 param.append('chunk', '0') // 添加form表单中其余数据 console.log(param.get('file')) // FormData私有类对象,访问不到,能够经过get判断值是否传进去 let config = { headers: {'Content-Type': 'multipart/form-data'} } // 添加请求头 axios.post('http://172.19.26.60:8081/rest/user/headurl', param, config) .then(response => { if (response.data.code === 0) { self.ImgUrl = response.data.data } console.log(response.data) }) }
qs库的npm地址:https://www.npmjs.com/package/qsreact
功能虽然都是序列化。假设我要提交的数据以下
var a = {name:'hehe',age:10};
qs.stringify序列化结果以下name=hehe&age=10
而JSON.stringify序列化结果以下:"{"a":"hehe","age":10}"
vux中使用post提交表单数据:
this.$http.post(this.$sign.config.url.loginUrl,this.$qs.stringify({ "phone":this.phoneNumber, "vCode":this.loginCode, "smsCode":this.phoneCode }) ) .then(response=>{ console.log(response.data); if(response.data.httpCode == 200){ }else{ } })
在firebug中能够看到传递的参数:phone=15210275239&vCode=8vsd&smsCode=1534
在vue中使用axios:
this.$axios.post(loginUrl, { "email": this.email, "password": this.password }, { transformRequest: (data) => { return this.$qs.stringify(data) }, }).then(res => { if(res.data.resultCode == RESULT_CODE_SUCCESS){ console.log('登陆成功'); this.$router.push({name:"home"}) }else{ console.log('登陆失败'); } }).catch(err => { console.log('登登陆出现错误'); })
import Vue from 'vue' import Vuex from 'vuex' import VueRouter from 'vue-router' import App from '../component/App.vue' import Login from '../component/Login.vue' import UserInfo from '../component/UserInfo.vue' //状态管理 Vue.use(Vuex) //路由 Vue.use(VueRouter) //路由配置 //若是须要加菜单,就在这里添加路由,并在UserMenu.vue添加入口router-link const router = new VueRouter({ routes: [{ path: '/login', component: Login }, { path: '/user_info', component: UserInfo }] }) //Vuex配置 const store = new Vuex.Store({ state: { domain:'http://test.example.com', //保存后台请求的地址,修改时方便(比方说从测试服改为正式服域名) userInfo: { //保存用户信息 nick: null, ulevel: null, uid: null, portrait: null } }, mutations: { //更新用户信息 updateUserInfo(state, newUserInfo) { state.userInfo = newUserInfo; } } }) //设置cookie,增长到vue实例方便全局调用 Vue.prototype.setCookie = (c_name, value, expiredays) => { var exdate = new Date(); exdate.setDate(exdate.getDate() + expiredays); document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString()); } //获取cookie Vue.prototype.getCookie = (name) => { var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); if (arr = document.cookie.match(reg)) return (arr[2]); else return null; } //删除cookie Vue.prototype.delCookie =(name) => { var exp = new Date(); exp.setTime(exp.getTime() - 1); var cval = this.getCookie(name); if (cval != null) document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString(); } //vue实例 var app = new Vue({ data: {}, el: '#app', render: h => h(App), router, store, watch:{ "$route" : 'checkLogin' }, created() { this.checkLogin(); }, methods:{ checkLogin(){ //检查是否存在session if(!this.getCookie('session')){ this.$router.push('/login'); }else{ this.$router.push('/user_info'); } } } })
如题所示,build文件夹下的webpack.base.conf.js
resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } }
其中的@的意思是:
只是一个别名而已。这里设置别名是为了让后续引用的地方减小路径的复杂度。
//例如 src - components - a.vue - router - home - index.vue index.vue 里,正常引用 A 组件: import A from '../../components/a.vue' 若是设置了 alias 后。 alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } 引用的地方路径就能够这样了 import A from '@/components/a.vue' 这里的 @ 就起到了【resolve('src')】路径的做用。
webpack 开发环境可使用proxyTable 来代理跨域,生产环境的话能够根据各自的服务器进行配置代理跨域就好了。在咱们的项目config/index.js 文件下能够看到有一个proxyTable的属性,咱们对其简单的改写
proxyTable: { '/api': { target: 'http://api.douban.com/v2', changeOrigin: true, pathRewrite: { '^/api': '' } } }
这样当咱们访问localhost:8080/api/movie的时候 其实咱们访问的是http://api.douban.com/v2/movi...。
固然咱们也能够根据具体的接口的后缀来匹配代理,如后缀为.shtml,代码以下:
proxyTable: { '**/*.shtml': { target: 'http://192.168.198.111:8080/abc', changeOrigin: true } }
可参考地址:
webpack 先后端分离开发接口调试解决方案,proxyTable解决方案
http-proxy-middleware
使用vue-cli
构建的vue项目,webpack
的配置文件是分散在不少地方的,而咱们须要修改的是build/webpack.base.conf.js
,修改两处的代码
// 在开头引入webpack,后面的plugins那里须要 var webpack = require('webpack') // resolve module.exports = { // 其余代码... resolve: { extensions: ['', '.js', '.vue'], fallback: [path.join(__dirname, '../node_modules')], alias: { 'src': path.resolve(__dirname, '../src'), 'assets': path.resolve(__dirname, '../src/assets'), 'components': path.resolve(__dirname, '../src/components'), // webpack 使用 jQuery,若是是自行下载的 // 'jquery': path.resolve(__dirname, '../src/assets/libs/jquery/jquery.min'), // 若是使用NPM安装的jQuery 'jquery': 'jquery' } }, // 增长一个plugins plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery" }) ], // 其余代码... }
这样就能够正确的使用jQuery
了,好比我要引入Bootstrap
,咱们在vue的入口js文件src/main.js
开头加入
// 使用Bootstrap import './assets/libs/bootstrap/css/bootstrap.min.css' import './assets/libs/bootstrap/js/bootstrap.min'
这样Bootstrap
就正确的被引用并构建。
在好比使用toastr
组件,只须要在须要的地方import
进来,或者全局引入css在须要的地方引用js,而后直接使用
// 使用toastr import 'assets/libs/toastr/toastr.min.css' import toastr from 'assets/libs/toastr/toastr.min' toastr.success('Hello')
参考:Managing Jquery plugin dependency in webpack
1.首先在package.json里加入,
dependencies:{ "jquery" : "^2.2.3" }
而后 npm install
2.在webpack.base.conf.js里加入
var webpack = require("webpack")
3.在module.exports的最后加入
plugins: [ new webpack.optimize.CommonsChunkPlugin('common.js'), new webpack.ProvidePlugin({ jQuery: "jquery", $: "jquery" }) ]
4.而后必定要从新 run dev
5.在main.js 引入就ok了
import $ from 'jquery'
var Showbo = require("exports?Showbo!./path/to/showbo.js");
参考: exports-loader
在 webpack.base.conf.js
中添加externals
externals 中 swiper 是键,对应的值必定的是插件 swiper.js 所定义的变量 Swiper :
以后再在根目录下的index.html
文件里引入文件:<script src="static/lib/swiper.js"></script>
这样子就能够在须要用到swiper.js
的文件里加入这行代码:import Swiper from 'swiper'
,这样就能正常使用了。
参考: https://segmentfault.com/q/1010000005169531?_ea=806312
mintui是饿了么团队针对vue开发的移动端组件库,方便实现移动端的一些功能,这里只用了Loadmore功能实现移动端的上拉分页刷新,下拉加载数据.
mintui官网:http://mint-ui.github.io/#!/zh-cn
<template> <div class="main-body" :style="{'-webkit-overflow-scrolling': scrollMode}"> <v-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" :auto-fill="false" ref="loadmore"> <ul class="list" v-for="(val, key) in pageList"> <li> <div>我是小11</div> <div>我是小11</div> </li> </ul> </v-loadmore> </div> </template> <script> import {Loadmore} from 'mint-ui'; export default { data:function() { return { searchCondition:{ //分页属性 pageNo:"1", pageSize:"10" }, pageList:[], allLoaded: false, //是否能够上拉属性,false能够上拉,true为禁止上拉,就是不让往上划加载数据了 scrollMode:"auto" //移动端弹性滚动效果,touch为弹性滚动,auto是非弹性滚动 } }, components: { 'v-loadmore':Loadmore // 为组件起别名,vue转换template标签时不会区分大小写,例如:loadMore这种标签转换完就会变成loadmore,容易出现一些匹配问题 // 推荐应用组件时用a-b形式起名 }, mounted(){ this.loadPageList(); //初次访问查询列表 }, methods: { loadTop:function() { //组件提供的下拉触发方法 //下拉加载 this.loadPageList(); this.$refs.loadmore.onTopLoaded();// 固定方法,查询完要调用一次,用于从新定位 }, loadBottom:function() { // 上拉加载 this.more();// 上拉触发的分页查询 this.$refs.loadmore.onBottomLoaded();// 固定方法,查询完要调用一次,用于从新定位 }, loadPageList:function (){ // 查询数据 this.api.PageList(this.searchCondition).then(data =>{ // 是否还有下一页,加个方法判断,没有下一页要禁止上拉 this.isHaveMore(data.result.haveMore); this.pageList = data.result.pageList; this.$nextTick(function () { // 原意是DOM更新循环结束时调用延迟回调函数,大意就是DOM元素在由于某些缘由要进行修改就在这里写,要在修改某些数据后才能写, // 这里之因此加是由于有个坑,iphone在使用-webkit-overflow-scrolling属性,就是移动端弹性滚动效果时会屏蔽loadmore的上拉加载效果, // 花了很久才解决这个问题,就是用这个函数,意思就是先设置属性为auto,正常滑动,加载完数据后改为弹性滑动,安卓没有这个问题,移动端弹性滑动体验会更好 this.scrollMode = "touch"; }); }); }, more:function (){ // 分页查询 this.searchCondition.pageNo = parseInt(this.searchCondition.pageNo) + 1; this.api.loadPageList(this.searchCondition).then(data=>{ this.pageList = this.pageList.concat(data.result.pageList); this.isHaveMore(data.result.haveMore); }); }, isHaveMore:function(isHaveMore){ // 是否还有下一页,若是没有就禁止上拉刷新 this.allLoaded = true; //true是禁止上拉加载 if(isHaveMore){ this.allLoaded = false; } } } } </script>
PS:有个坑必定要注意就是注释里说的iPhone里loadmore和-webkit-overflow-scrolling属性冲突没法上拉问题
可参考另一个插件,没有使用过,《简单灵活且强大的Vue下拉刷新组件:vue-pull-to》
在vue的实际开发中每每会遇到公用一个组件的问题,好比有一个菜单中的两个按钮,点击每一个按钮调用的是同一个组件,其内容是根据路由的参数的不一样来请求不一样的内容。
第一步,首先新建一个vue+webpack+vuecli的demo,以下操做:
全局安装vue-cli
,vue-cil
是vue的脚手架工具,安装命令:
npm install -g vue-cli
第二步,进入到工程目录中,建立一个vuedemo
的文件夹工程,以下两步操做:
cd vue_test_project //进入vue_test_project目录下 vue init webpack vuedemo //在vue_test_project目录下建立一个vuedemo工程
输入这个命令以后,会出现一些提示,是什么不用管,一直按回车便可。
第三步,以下操做:
cd vuedemo npm install
执行npm install
须要一点时间,由于会从服务器上下载代码啦之类的。而且在执行过程当中会有一些警告信息。不用管,等着就是了。若是长时间没有响应,就ctrl+c
中止掉,而后再执行一次便可。
最后一步,操做以下:
npm run dev
在运行了npm run dev
以后,会自动打开一个浏览器窗口,就能够看到实际的效果了。这个demo就建立好了。如今就在这个demo
中添加一些内容,修改为以下:
修改HelloWorld.vue
的内容为以下:
<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <div class="btn"> <router-link :to="{name:'content',params:{differId:'con1'}}">内容按钮1</router-link> <router-link :to="{name:'content',params:{differId:'con2'}}">内容按钮2</router-link> </div> <router-view></router-view> </div> </template> <script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script> <style scoped> h1, h2 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>
路由router
下的index.html
的修改成以下:
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import content from '@/components/conDetail' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld, children:[ {name:'content',path:'content/:differId',component:content} ] } ] })
如今建立一个conDetail.vue
了,以下:
<template> <div class="same"> 这个是相同的内容 <div class="conlist"> <template v-for="item in items"> <p>{{item.con}}</p> </template> </div> </div> </template> <script> export default { name: 'conDetail', data () { return { msg: '', differIdType:'', conlist:[ {'con':'这是第一个内容按钮的内容1'}, {'con':'这是第一个内容按钮的内容2'} ], items:[], } }, mounted(){ this.differIdType = this.$route.params.differId == 'con1' ? '0' : '1'; if(this.differIdType == 0){ this.items = this.conlist; }else{ this.items = []; } }, watch:{ $route:function(to,from){ this.differIdType = to.params.differId == 'con1' ? '0' : '1'; if(this.differIdType == 0){ this.items = this.conlist; }else{ this.items = []; } } } } </script> <style> </style>
结果就是,当点击内容按钮1,出现了对象的内容,点击内容按钮2,出现相应的内容。固然我这儿写的是点击按钮2的时候,其items的内容为空数组。这儿也使用了$route
的监听。
复用组件时,想对路由参数的变化做出响应的话,你能够简单地 watch
(监测变化) $route
对象:
const User = { template: '...', watch: { '$route' (to, from) { // 对路由变化做出响应... } } }
或者使用 2.2 中引入的 beforeRouteUpdate
守卫:
const User = { template: '...', beforeRouteUpdate (to, from, next) { // react to route changes... // don't forget to call next() } }
详细了解路由相关的内容,查看官网:https://router.vuejs.org/zh-cn/
父组件数据如何传递给子组件呢?能够经过props
属性来实现
父组件:
<parent> <child :child-msg="msg"></child>//这里必需要用 - 代替驼峰 </parent> data(){ return { msg: [1,2,3] }; }
子组件经过props
来接收数据:
方式1:
props: ['childMsg']
方式2 :
props: { childMsg: Array //这样能够指定传入的类型,若是类型不对,会警告 }
方式3:
props: { childMsg: { type: Array, default: [0,0,0] //这样能够指定默认的值 } }
这样呢,就实现了父组件向子组件传递数据.
子组件:
<template> <div @click="up"></div> </template> methods: { up() { this.$emit('fun','这是一段内容'); //主动触发fun方法,'这是一段内容'为向父组件传递的数据 } }
父组件:
<div> <child @fun="change" :msg="msg"></child> //监听子组件触发的fun事件,而后调用change方法 </div> methods: { change(msg) { this.msg = msg; } }
若是2个组件不是父子组件那么如何通讯呢?这时能够经过eventHub
来实现通讯.
所谓eventHub就是建立一个事件中心,至关于中转站,能够用它来传递事件和接收事件.
let Hub = new Vue(); //建立事件中心
组件1触发:
<div @click="eve"></div> methods: { eve() { Hub.$emit('change','hehe'); //Hub触发事件 } }
组件2接收:
<div></div>
created() {
Hub.$on('change', () => { //Hub接收事件 this.msg = 'hehe'; }); }
可参考:vue非父子组件怎么进行通讯
有时候咱们须要页面滚动条滚动到某一固定的位置,通常使用Window scrollTo()
方法。
语法就是:scrollTo(xpos,ypos)
xpos
:必需。要在窗口文档显示区左上角显示的文档的 x 坐标。
ypos
:必需。要在窗口文档显示区左上角显示的文档的 y 坐标。
例如滚动内容的坐标位置100,500:
window.scrollTo(100,500);
好了,这个scrollTop
这儿只是简单介绍一下,下面咱们介绍下veu-router
中的滚动行为。
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像从新加载页面那样。 vue-router
能作到,并且更好,它让你能够自定义路由切换时页面如何滚动。
注意: 这个功能只在
HTML5 history
模式下可用。
当建立一个 Router 实例,你能够提供一个 scrollBehavior 方法:
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 指望滚动到哪一个的位置 } })
scrollBehavior
方法接收 to
和 from
路由对象。第三个参数 savedPosition
当且仅当 popstate
导航 (经过浏览器的 前进/后退 按钮触发) 时才可用。
这个方法返回滚动位置的对象信息,长这样:
{ x: number, y: number }
{ selector: string, offset? : { x: number, y: number }}
(offset 只在 2.6.0+ 支持)若是返回一个 falsy (译者注:falsy 不是 false
,参考这里)的值,或者是一个空对象,那么不会发生滚动。
举例:
scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } }
对于全部路由导航,简单地让页面滚动到顶部。
返回 savedPosition
,在按下 后退/前进 按钮时,就会像浏览器的原生表现那样:
scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } }
若是你要模拟『滚动到锚点』的行为:
scrollBehavior (to, from, savedPosition) { if (to.hash) { return { selector: to.hash } } }
咱们还能够利用路由元信息更细颗粒度地控制滚动。
routes: [ { path: '/', component: Home, meta: { scrollToTop: true }}, { path: '/foo', component: Foo }, { path: '/bar', component: Bar, meta: { scrollToTop: true }} ]
完整的例子:
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const Home = { template: '<div>home</div>' } const Foo = { template: '<div>foo</div>' } const Bar = { template: ` <div> bar <div style="height:500px"></div> <p id="anchor">Anchor</p> </div> ` } // scrollBehavior: // - only available in html5 history mode // - defaults to no scroll behavior // - return false to prevent scroll const scrollBehavior = (to, from, savedPosition) => { if (savedPosition) { // savedPosition is only available for popstate navigations. return savedPosition } else { const position = {} // new navigation. // scroll to anchor by returning the selector if (to.hash) { position.selector = to.hash } // check if any matched route config has meta that requires scrolling to top if (to.matched.some(m => m.meta.scrollToTop)) { // cords will be used if no selector is provided, // or if the selector didn't match any element. position.x = 0 position.y = 0 } // if the returned position is falsy or an empty object, // will retain current scroll position. return position } } const router = new VueRouter({ mode: 'history', base: __dirname, scrollBehavior, routes: [ { path: '/', component: Home, meta: { scrollToTop: true }}, { path: '/foo', component: Foo }, { path: '/bar', component: Bar, meta: { scrollToTop: true }} ] }) new Vue({ router, template: ` <div id="app"> <h1>Scroll Behavior</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/foo">/foo</router-link></li> <li><router-link to="/bar">/bar</router-link></li> <li><router-link to="/bar#anchor">/bar#anchor</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')
在网上查了一下,网友说还能够试试在main.js入口文件配合vue-router写这个
router.afterEach((to,from,next) => { window.scrollTo(0,0); });
Vue.use( plugin )
:安装 Vue.js 插件。若是插件是一个对象,必须提供 install
方法。若是插件是一个函数,它会被做为 install
方法。install 方法将被做为 Vue 的参数调用。
当 install 方法被同一个插件屡次调用,插件将只会被安装一次。
Vue.js 的插件应当有一个公开方法 install
。这个方法的第一个参数是 Vue
构造器,第二个参数是一个可选的选项对象:
MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue.myGlobalMethod = function () { // 逻辑... } // 2. 添加全局资源 Vue.directive('my-directive', { bind (el, binding, vnode, oldVnode) { // 逻辑... } ... }) // 3. 注入组件 Vue.mixin({ created: function () { // 逻辑... } ... }) // 4. 添加实例方法 Vue.prototype.$myMethod = function (methodOptions) { // 逻辑... } }
经过全局方法 Vue.use()
使用插件:
// 调用 `MyPlugin.install(Vue)` Vue.use(MyPlugin)
也能够传入一个选项对象:
Vue.use(MyPlugin, { someOption: true })
Vue.use 会自动阻止屡次注册相同插件,届时只会注册一次该插件。
Vue.js
官方提供的一些插件 (例如 vue-router
) 在检测到 Vue 是可访问的全局变量时会自动调用 Vue.use()
。然而在例如 CommonJS
的模块环境中,你应该始终显式地调用 Vue.use()
:
// 用 Browserify 或 webpack 提供的 CommonJS 模块环境时 var Vue = require('vue') var VueRouter = require('vue-router') // 不要忘了调用此方法 Vue.use(VueRouter)
在main.js
中使用该组件的方法:
import childModule from './components/children' Vue.use(childModule)
组件文件夹的目录结构以下:
|-components |-children |-index.js 导出组件,而且install |-children.vue (定义本身的组件模板)
children.vue
代码以下:
import childrencomponent from './children.vue' const childrenMo = { install:function(Vue){ Vue.component('childModule',childrencomponent) } } export default childrenMo
这样就实现了一个经过vue.use
调用一个全局组件。
由于使用了 ES6 中用来传递异步消息的的Promise,而IE低版本的浏览器不支持。
如图所示:
解决方法
第一步: 安装 babel-polyfill 。 babel-polyfill能够模拟ES6使用的环境,可使用ES6的全部新方法
npm install --save babel-polyfill
第二步: 在 Webpack/Browserify/Node中使用
在webpack.config.js文件中
把
module.exports = { entry: { app: './src/main.js' } }
替换为:
module.exports = {
entry: { app: ["babel-polyfill", "./src/main.js"] } };
若是是简单经过package.json来建立一个项目,只须要执行npm install
首先,咱们本身得手动建立一个webpack+vue+vueRouter+vuecli工程,执行下面:
如:
新建一个vue项目,建立一个基于"webpack"的项目,项目名为vuedemo:
$ vue init webpack vuedemo
安装完成后进入工程名称再根据原来项目的配置文件初始化
$ cd vuedemo $ npm install
可是因为在新建的时候对eslint的选择中选择了Yes,因此后面根据配置package.json的时候,发现没有eslint-friendly-formatter
模块,因为原来的工程应该没有配置这个,因此这儿须要安装下,以下代码:
npm i -D eslint eslint-friendly-formatter
模块地址:https://www.npmjs.com/package/eslint-friendly-formatter
安装后执行:npm run dev
发现运行起来的页面没有启动起来,缘由是仍是这个eslint引发的。
出错信息为:
These relative modules were not found:
*/build/dev-client in multi ./build/dev-client ./src/main.js, *./src/main.js in multi ./build/dev-client ./src/main.js
缘由以下:
webpack.base.conf.js里面,脚手架原本就有 js的编译模块,
{
test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test')] }
咱们须要注释掉这段代码:
// { // test: /\.(js|vue)$/, // loader: 'eslint-loader', // enforce: 'pre', // include: [resolve('src'), resolve('test')], // options: { // formatter: require('eslint-friendly-formatter') // } // },
缘由就是致使重复编译,因此应该就有两个main.js文件。因此不要重复出现匹配规则就能够。
而后运行npm run dev
能够了。
类似问题:vue-cli安装完成以后,命令行npm run dev没有问题,但webstorm报错
首先,咱们分别找到下面的文件:
/config/dev.env.js /config/prod.env.js
其实,这两个文件就是针对生产环境和发布环境设置不一样参数的文件。咱们打开dev.en.js
文件。代码以下:
var merge = require('webpack-merge') var prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"' })
咱们在NODE_ENV下面增长一项,代码以下:
var merge = require('webpack-merge') var prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', API_ROOT: '"//192.168.1.8/api"' })
prod.env.js文件修改成:
module.exports = { NODE_ENV: '"production"', API_ROOT: '"//www.baidu.com/api"' }
以咱们以前的演示代码为例。你本身的项目请根据你本身的状况调整。如下文件和代码仅供参考。
咱们打开src/config/api.js
文件,将原来开头的代码
// 配置API接口地址 var root = 'https://cnodejs.org/api/v1'
修改成:
// 配置API接口地址 var root = process.env.API_ROOT
而后就完成了咱们的配置工做。最后,重启项目,就能使新配置的接口地址生效了。
npm run dev npm run build
process.env.NODE_ENV == 'production'; //生产环境 process.env.NODE_ENV == 'development'; //开发环境
参考地址:http://blog.csdn.net/fungleo/article/details/54574049
申请百度统计后,会获得一段JS代码,须要插入到每一个网页中去,在Vue.js项目首先想到的可能就是,把统计代码插入到index.html入口文件中,这样就全局插入,每一个页面就都有了;这样作就涉及到一个问题,Vue.js项目是单页应用,每次用户浏览网站时,访问内页时页面是不会刷新的,也就意味着不会触发百度统计代码;因此最终在百度统计后台看到的效果就是只统计到了网页入口的流量,却没法统计到内页的访问流量。
在main.js
文件中调用vue-router
的afterEach
方法,将统计代码加入到这个方法里面,这样每次router
发生改变的时候都会执行一下统计代码,这样就达到了目的,代码以下:
router.afterEach( ( to, from, next ) => { setTimeout(()=>{ var _hmt = _hmt || []; (function() { //每次执行前,先移除上次插入的代码 document.getElementById('baidu_tj') && document.getElementById('baidu_tj').remove(); var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?xxxx"; hm.id = "baidu_tj" var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); },0); } );