vue常见的开发知识点与问题

文章目录
1.vue双向数据绑定vuex中的state
2.(webpack)vue-cli构建的项目如何设置每个页面的title
3.vue项目中使用axios上传图片等文件
4.qs.stringify() 和JSON.stringify()的区别、vux中使用post提交表单数据需要qs库序列化
5.vue全局实现的setCookie、getCookie、delCookie
6.webpack proxyTable 代理跨域
7.vue和mintui-Loadmore结合实现下拉刷新,上拉加载 (待优化)
8.vue非父子组件通信
9.IE9报vuex requires a Promise polyfill in this browser问题解决
10.启动Vue项目时提示: [BABEL] … max of “500KB”.
11.在main.js中监听微信浏览器返回按钮,让其不能返回
12.pdf.js默认不显示电子签章(数字签名)问题解决
13.pdf.js预览,中文显示乱码解决方法
14.解决Vue引入百度地图JSSDK:BMap is undefined 问题
15.本地启动vue项目,host配置域名访问出现Invalid Host header 服务器域名访问出现的问题
16.vue项目中在使用vue-router切换页面的时候滚动条怎样自动滚动到顶部?
17.tips:webpack中alias配置中的“@”的作用
18.tips:package.json中的dependencies与devDependencies之间的区别
19.tips:package.json设置环境变量
1.vue双向数据绑定vuex中的state
在vue中, 不允许直接绑定vuex的值到组件中, 若是直接使用, 则会报错 have no setter

方法一: 使用get和set

复制代码
// 在从组件的computed中
computed: {
user: {
get() {
return this.KaTeX parse error: Expected 'EOF', got '}' at position 26: …e.user }̲, set(v…store.commit(‘USER’, v)
}
}
}
// 在组件中就可以使用

复制代码
方法二: 使用watch

复制代码
// 在组件中绑定

// 在computed中获取vuex的值
computed: {
…mapState( { user: state => state.user } )
}

// 在组件的watch中观测
watch: {
‘user’: {
deep: true,
handler(value) {
// 使用vuex中的mutations中定义好的方法来改变
this.$store.commit(‘USER’, value)
}
}
}
复制代码
2.(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()
})
3.vue项目中使用axios上传图片等文件
通过form表单提交,html代码如下:

<input name=“file” type=“file” accept=“image/png,image/gif,image/jpeg” @change=“update”/>
JS代码:

复制代码
import axios from ‘axios’

update(e) {
let file = e.target.files[0]
let param = new FormData(); // 创建form对象
param.append(‘file’, file); // 通过append向form对象添加数据
param.append(‘chunk’, ‘0’); // 添加form表单中其他数据
let config = { // 添加请求头
headers: {
‘Content-Type’: ‘multipart/form-data’
}
};
axios.post(‘http://172.19.26.60:8080/user/headurl’, param, config)
.then(response => {
if (response.data.code === 200) {
this.ImgUrl = response.data.data;
}
})
}
复制代码
4.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. h t t p . p o s t ( t h i s . http.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.KaTeX parse error: Expected '}', got 'EOF' at end of input: … 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(‘登登录出现错误’);
})
复制代码
5.vue全局实现的setCookie、getCookie、delCookie
复制代码
//设置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]);
}
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();
}
}
复制代码
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和mintui-Loadmore结合实现下拉刷新,上拉加载 (待优化)
mintui是饿了么团队针对vue开发的移动端组件库,方便实现移动端的一些功能,这里只用了Loadmore功能实现移动端的上拉分页刷新,下拉加载数据.
mintui官网:http://mint-ui.github.io/#!/zh-cn

复制代码

  • 我是小11
    我是小11
复制代码 PS:有个坑一定要注意就是注释里说的iPhone里loadmore和-webkit-overflow-scrolling属性冲突无法上拉问题

可参考另外一个插件,没有使用过,《简单灵活且强大的Vue下拉刷新组件:vue-pull-to》

8.vue非父子组件通信
如果2个组件不是父子组件那么如何通信呢?这时可以通过eventHub来实现通信。所谓eventHub就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。

方式一
组件1触发:

created() {
Hub.$on(‘change’, (msg) => { //Hub接收事件
this.msg = msg;
});
}
可参考:vue非父子组件怎么进行通信

方式二

把中转站数据存放到根实例下面,如下:

复制代码
// 根组件(this.$root)
new Vue({
el: ‘#app’,
router,
render: h => h(App),
data: {
// 空的实例放到根组件下,所有的子组件都能调用
Bus: new Vue()
}
})
复制代码
组件1触发:

created() {
this. r o o t . B u s . root.Bus. root.Bus.on(‘change’, (msg) => { //接收事件
this.msg = msg;
});
}
注:官方推荐的eventbus 解决方案的缺陷在于, 在数据传递过程中,两个组件必须都已经被渲染过。

9.IE9报vuex requires a Promise polyfill in this browser问题解决
因为使用了 ES6 中用来传递异步消息的的Promise,而IE低版本的浏览器不支持。

解决方法
第一步: 安装 babel-polyfill

babel-polyfill可以模拟ES6使用的环境,可以使用ES6的所有新方法

npm install --save-dev babel-polyfill
第二步: 在 Webpack/Browserify/Node中使用

在webpack.config.js文件中把

module.exports = {
entry: {
app: ‘./src/main.js’
}
}
替换为:

module.exports = {
entry: {
app: [“babel-polyfill”, “./src/main.js”]
}
};
当然还有其它两种引入方式:

require(“babel-polyfill”);
import “babel-polyfill”;
10.启动Vue项目时提示: [BABEL] … max of “500KB”.
在项目的根目录下找到 .babelrc 文件,增加 “compact”: false ,如:

复制代码
{
“compact”: false,
“presets”: [“env”, “react”, “stage-0”],
“plugins”: [
“transform-runtime”
]
}
复制代码
如果不存在则手动创建该文件,并填写内容如:

{
“compact”: false
}
11.在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}});
}
12.pdf.js默认不显示电子签章(数字签名)问题解决

  1. pdfjs 旧版本
    pdf.worker.js 找到

if(this.data.fieldType === ‘Sig’) {
warn(‘unimplemented annotation type: Widget signature’);
return false;
}
注解上面代码.
2. pdfjs 新 版本v1.10.88
pdf.worker.js 找到

if(data.fieldType === ‘Sig’) {
_this2.setFlags(_util.AnnotationFlag.HIDDEN);
}
13.pdf.js预览,中文显示乱码解决方法
有可能是有pdf不支持的字体格式,引入pdf.js的字体试试

const CMAP_URL = ‘https://unpkg.com/pdfjs-dist@2.0.489/cmaps/’;
pdfjsLib.getDocument({
data: pdfData,
cMapUrl: CMAP_URL,
cMapPacked: true,
})
14.解决Vue引入百度地图JSSDK:BMap is undefined 问题
复制代码
export default {
init: function (){
//console.log(“初始化百度地图脚本…”);
const AK = “AK密钥”;
const BMap_URL = “https://api.map.baidu.com/api?v=2.0&ak=”+ AK +"&s=1&callback=onBMapCallback";
return new Promise((resolve, reject) => {
// 如果已加载直接返回
if(typeof BMap !== “undefined”) {
resolve(BMap);
return true;
}
// 百度地图异步加载回调处理
window.onBMapCallback = function () {
console.log(“百度地图脚本初始化成功…”);
resolve(BMap);
};

  // 插入script脚本
  let scriptNode = document.createElement("script");
  scriptNode.setAttribute("type", "text/javascript");
  scriptNode.setAttribute("src", BMap_URL);
  document.body.appendChild(scriptNode);
});

}
}
复制代码
说明:

直接使用官网提供的引用地址:http://api.map.baidu.com/api?v=2.0&ak=您的密钥
启用 callback 参数,异步加载必须使用此参数才可以生效
启用 https 配置,通过 s=1 参数实现
API版本为2.0,经测试使用,发现3.0版本在HTTPS环境下是有问题的,脚本内部某些请求固定使用HTTP,无法正常使用。
参考地址:https://segmentfault.com/a/1190000012815739

15.本地启动vue项目,host配置域名访问出现Invalid Host header 服务器域名访问出现的问题
在webpack.dev.config.js中找到 devServer下的hot,再下面添加 disableHostCheck: true,来解决127.0.0.1指向其他域名时出现"Invalid Host header"问题

如图所示:
在这里插入图片描述
16.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: ‘

home
’ }
const Foo = { template: ‘
foo
’ }
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);
});
17.tips: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’)】路径的作用。
复制代码
18.tips:package.json中的dependencies与devDependencies之间的区别
–save-dev 和 –save 的区别

我们在使用npm install 安装模块或插件的时候,有两种命令把他们写入到 package.json 文件里面去,比如:

–save-dev 安装的 插件,被写入到 devDependencies 对象里面去

–save 安装的 插件 ,被写入到 dependencies 对象里面去

devDependencies 是只会在开发环境下依赖的模块,生产环境不会被打入包内。

dependencies 是不仅在开发环境使用,在生成环境也需要。

19.tips:package.json设置环境变量
三种方法可以在package.json设置环境变量。

先安装cross-env:

npm install --save-dev cross-env
package.json设置:

复制代码
{
“scripts”: {
“dev1”: “export WEBPACK_ENV=production && npx webpack -p”, ## mac
“dev1”: “set WEBPACK_ENV=production && npx webpack -p”, ## windows
“dev2”: “cross-env CURRENT_ENV=development webpack-dev-server --inline --progress”, ## 兼容所有平台
}
}
复制代码
设置环境变量的作用:

在项目的js脚本中,通过process.env这个对象就可以访问到设置的环境变量结合打包软件webpack等等,实现不同的代码逻辑:

console.log(process.env.WEBPACK_ENV)
console.log(process.env.CURRENT_ENV)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值