【转】[总结]vue开发常见知识点及问题资料整理(持续更新)
- 1.(webpack)vue-cli构建的项目如何设置每个页面的title
- 2.vue项目中使用axios上传图片等文件
- 3.qs.stringify() 和JSON.stringify()的区别以及在vux中使用post提交表单数据需要qs库序列化
- 4.vue中实现全局的setCookie,getCookie以及delCookie方法笔记
- 5.webpack中alias配置中的“@”是什么意思?
- 6.webpack proxyTable 代理跨域
- 7.如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
- 8.vue和mintui-Loadmore结合实现下拉刷新,上拉加载 (待优化)
- 9.在vue+webpack实际开发中出现两个或多个菜单公用一个组件的解决方案
- 10.vue2.x父子组件以及非父子组件之间的通信
- 11.vue项目中在使用vue-router切换页面的时候滚动条怎样自动滚动到顶部?
- 12.vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
- 13.IE9报vuex requires a Promise polyfill in this browser问题解决
- 14.通过webpack+vue+vueRouter+vuecli的配置文件package.json创建一个新的项目
- 15.在main.js中监听微信返回按钮的操作,让其返回不了
1.(webpack)vue-cli构建的项目如何设置每个页面的title
在路由里每个都添加一个meta
[{
path:'/login',
meta: {
title: '登录页面'
},
component:'login'
}]
钩子函数:
在main.js中添加如下代码
router.beforeEach((to, from, next) => {
window.document.title = to.meta.title;
next()
})
2.vue项目中使用axios上传图片等文件
首先安装axios:
1.利用npm安装npm install axios –save
2.利用bower安装bower install axios –save
3.直接利用cdn引入
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
一般情况上传照片有两种方式:
- 1.本地图片转换成base64,然后通过普通的post请求发送到服务端。操作简单,适合小图,以及如果想兼容低版本的ie没办法用此方法
- 2.通过form表单提交。form表单提交图片会刷新页面,也可以时form绑定到一个隐藏的iframe上,可以实现无刷新提交数据。
这里只讲解一下第二种方式:
html代码:
<input name="file" type="file" accept="image/png,image/gif,image/jpeg" @change="update"/>
js代码:
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)
})
}
3.qs.stringify() 和JSON.stringify()的区别以及在vux中使用post提交表单数据需要qs库序列化
qs库的npm地址:https://www.npmjs.com/package/qs
功能虽然都是序列化。假设我要提交的数据如下
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('登登录出现错误');
})
4.vue中实现全局的setCookie,getCookie以及delCookie方法笔记
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');
}
}
}
})
5.webpack中alias配置中的“@”是什么意思?
如题所示,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')】路径的作用。
6.webpack proxyTable 代理跨域
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/movie
这样便达到了一种跨域请求的方案。
当然我们也可以根据具体的接口的后缀来匹配代理,如后缀为.shtml,代码如下:
proxyTable: {
'**/*.shtml': {
target: 'http://192.168.198.111:8080/abc',
changeOrigin: true
}
}
可参考地址:
webpack 前后端分离开发接口调试解决方案,proxyTable解决方案
http-proxy-middleware
7.如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
使用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')
参考:
vue-cli webpack全局引入jquery
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'
在.vue文件中引入第三方非NPM模块
var Showbo = require("exports?Showbo!./path/to/showbo.js");
参考: exports-loader
vue-cli引入外部文件
在 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
8.vue和mintui-Loadmore结合实现下拉刷新,上拉加载 (待优化)
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》
9.在vue+webpack实际开发中出现两个或多个菜单公用一个组件的解决方案
在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/
10.vue2.x父子组件以及非父子组件之间的通信
1.父组件传递数据给子组件
父组件数据如何传递给子组件呢?可以通过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] //这样可以指定默认的值
}
}
这样呢,就实现了父组件向子组件传递数据.
2.子组件与父组件通信
子组件:
<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;
}
}
3.非父子组件通信
如果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非父子组件怎么进行通信
11.vue项目中在使用vue-router切换页面的时候滚动条怎样自动滚动到顶部?
有时候我们需要页面滚动条滚动到某一固定的位置,一般使用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);
});
12.vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
简介
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)
实例:实现一个children组件
在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调用一个全局组件。
13.IE9报vuex requires a Promise polyfill in this browser问题解决
因为使用了 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"]
}
};
14.通过webpack+vue+vueRouter+vuecli的配置文件package.json创建一个新的项目
如果是简单通过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报错
15.在main.js中监听微信返回按钮的操作,让其返回不了
if(from.name == 'staffInfo' && to.name == 'Login'){
next({path:'/staffInfo',query:{redirect:from.fullPath}});
}else if(from.name == 'acountFill' && to.name == 'Login'){
next({path:'/acount/acountFill',query:{redirect:from.fullPath}});
}
最新更新于2018/02/26
【转】[总结]vue开发常见知识点及问题资料整理(持续更新)的更多相关文章
- [总结]vue开发常见知识点及问题资料整理(持续更新)
package.json中的dependencies与devDependencies之间的区别 –save-dev 和 –save 的区别 我们在使用npm install 安装模块或插件的时候,有两 ...
- Python开发【第二十三篇】:持续更新中...
Python开发[第二十三篇]:持续更新中...
- vue开发常见命令
1.安装脚手架 安装脚手架命令:npm install -global vue-cli 2.升级脚手架 有时候需要把整个脚手架升级一下,这个用到命令npm install --global vue-c ...
- vue 开发常见问题解决大全
vue添加favicon.ico,包含开发环境和生产环境显示. 1.把图标放在下项目的根目录.. 2.修改build文件夹下面的webpack.dev.conf.js(开发环境) 和webpack.p ...
- iOS开发网络资源整理-持续更新
本文记录iOS开发相关的网络社区和博客 1.objc中国 网址:http://objccn.io 简介:onevcat创建,项目的成立源于国内 Objective-C 社区对 objc.io 的翻译活 ...
- BAT笔试试题常见试题总结含答案(持续更新。。。)
(1)试题例如以下: class A { int a; short b; int c; char d; }; class B { double a; short b; int c; char d; } ...
- Android开发经典笔试面试题汇总(持续更新中)
1.我们都知道Handler是线程与Activity通信的桥梁,假设线程处理不当.你的机器就会变得非常慢,那么线程销毁的方法是:(A) A. onDestroy() B. onClear() C. o ...
- Java开发需掌握的常用Linux命令(持续更新)
linux命令是对Linux系统进行管理的命令.对于Linux系统来说,无论是中央处理器.内存.磁盘驱动器.键盘.鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命 ...
- 个人在 laravel 开发中使用到的一些技巧(持续更新)
1.更高效率地查询:使用批量查询代替 foreach 查询(多次 io 操作转换为一次 io操作) 如果想要查看更详尽的介绍,可以看看这篇文章 什么是 N+1 问题,以及如何解决 Laravel 的 ...
随机推荐
- 网络通信 & 初识socket
本节主要内容: 1.客户短\服务端架构 2.网络通信的流程 3.初识socket 一.客户端\服务端架构 客户端\服务端架构: 即Client/Server (C/S) 结构,是大家熟知的软件系统体系 ...
- C#Listview添加数据,选中最后一行,滚屏
this.listView.Items.Add(lvi); this.listView.EnsureVisible(this.listView.Items.Count - 1); this.listV ...
- 算法时间复杂度的表示法O(n²)、O(n)、O(1)、O(nlogn)等是什么意思?
Java中 Set 和 List 集合 的contains()方法,检查数组链表中是否包含某元素检查数组链表中是否包含某元素,使用 Set 而不使用 List 的原因是效率问题, 前者的 set ...
- crontab 定时执行python脚本
每天8点30分运行命令/tmp/run.sh * * * /tmp/run.sh 每两小时运行命令/tmp/run.sh */ * * * /tmp/run.sh
- MYSQL常用函数(时间和日期函数)
CURDATE()或CURRENT_DATE() 返回当前的日期 CURTIME()或CURRENT_TIME() 返回当前的时间 DATE_ADD(date,INTERVAL int keyword ...
- DELPHI各种颜色表达式
颜色样本 十六进制 名称与注释 #ffb3a7 粉红:即浅红色.别称:妃色 杨妃色 湘妃色 妃红色. #ed5736 妃色:妃红色.古同“绯”,粉红色.杨妃色.湘妃色.粉红皆同义. #f0 ...
- 雷林鹏分享: C# 简介
C# 简介 C# 是一个现代的.通用的.面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的. C# 是由 Anders Hejlsberg 和他的团队在 ...
- C#异步的世界(重点:新异步)
http://www.cnblogs.com/zhaopei/p/async_two.html
- Java对MongoDB中的数据查询处理
Java语言标准的数据库时MySQL,但是有些时候也会用到MongoDB,这次Boss交代处理MongoDB,所以讲代码以及思路记录下了 摸索的过程,才发现软件的适用还是很重要的啊!!! 我连接的Mo ...
- loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树
题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...