原因:点击vue文件不能直接识别vue文件(右下角一直是纯文字提示,应该是vue)
方案:安装插件: vue, VueHelper 和 vetur 。任选其一
Ctrl + P 然后输入 ext install vetur 然后回车点安装即可。
这时可以打开一个vue文件试试,注意下右下角状态栏是否正确识别为 vue 类型:
{{item.spans}}
data(){
return{
cons:0,
lis:[
{
imgs:require('../assets/deal_yunzhifu.png'),
spans:'云闪付'
},
{
imgs:require('../assets/deal_weixin.png'),
spans:'微信'
},
{
imgs:require('../assets/deal_zhifubao.png'),
spans:'支付宝'
},
{
imgs:require('../assets/fukuan_quick.png'),
spans:'快捷支付'
},
]
}
},
methods:{
onShow(index){
this.cons=index
}
}
.select{
display: block;
}
let idCardNumber = cardList.map(item=>{
item.xing = "**** **** *** " + item.idCardNumber.substr(item.idCardNumber.length-4)
return item
})
console.log(idCardNumber)
参考链接:https://www.jianshu.com/p/6d21a54fbfbd
data(){
return{
img:'https://img.alicdn.com/bao/uploaded/TB1qimQIpXXXXXbXFXXSutbFXXX.jpg',
}
},
getBase64Image(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
var dataURL = canvas.toDataURL("image/"+ext);
return dataURL;
},
mounted(){
var image = new Image();
image.crossOrigin = '';
image.src = this.img;
var base64 = this.getBase64Image(image);
}
1.安装插件vue-qr
npm install vue-qr --save
2.插件地址上面有各种属性
https://www.npmjs.com/package/vue-qr
3.以下链接是搜索到封装好了的组件
http://www.mamicode.com/info-detail-2566029.html
4.当当当第四条是我应用到项目中截取的小demo
//logoSrc中间logo地址,text二维码地址链接,size二维码大小单位px,logoMargin中间logo距离边上的margin,
margin二维码的边框,logoScale中间logo的大小取值0.1-1,dotScale数据区域点缩小比例,默认为0.35,
logoBackgroundColor背景色,需要设置 logoMargin
//引入组件,注册组件,data设置初始值
import VueQr from 'vue-qr'
export default {
components:{
VueQr
},
data(){
return{
config: {
value: 'https://www.npmjs.com/package/vue-qr',//显示的值、跳转的地址
imagePath: require('../assets/code_yunshanfu.png')//中间logo的地址
}
}
}
}
//先把二维码大小设置大出容器,之后再缩放,这样做是让二维码不失真更清晰
#qrcode{
img{
transform:scale(0.58);
transform-origin:0 0;
}
}
此处为本文参考链接点击查看
1.在main.js下百度统计代码添加
import router from "./router";
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?你的ak";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
router.afterEach( function( to, from, next ) {
var topath = to.path
var fullpath = to.fullPath
if (_hmt) {
setTimeout(() => {
if (topath) {
_hmt.push(['_trackPageview', '/'+process.env.VUE_APP_PROJECTNAME+'/#' + fullpath]);
}
}, 0);
}
} );
// 这里因为我的路由mode是history,所以 _hmt.push(['_trackPageview', to.fullPath]),但是如果是hash的话,后面的路径要修改一下,改成
// _hmt.push(['_trackPageview', '/#' + to.fullPath]);
应用场景:公众号嵌套h5页面,支付类必须有用户经纬度才能生成订单
申请百度地图ak
ak会在引入百度js的时候用到,你可以点击这里申请一个唯一ak
引入百度地图js
在public/index.html里面添加下面代码,注意把“你的ak”替换成你申请的ak
module.exports = {
configureWebpack: {
externals: {
"BMap": "BMap"
}
}
}
使用场景:公众号嵌套H5项目
1.公众号中有公司之前开发的项目A产品,此次在增加其实是增加了新的项目B产品,但是要让用户感觉是之前项目的一个新功能(让B成为A的一个新功能)
2.B产品开发的时候打包的APP没有考虑到之后的h5,所以刚开始采用的是账号密码登入方式,如果是这样的话给用户感知一个项目之中需要登入俩次,很不和谐体验也很不好,后来改用授权方式登入
3.后台新增俩个接口
3.1微信网页授权接口----同步历史数据(手机号和openid),授权后如果已经绑定手机号,直接去是home
3.2绑定手机号接口-----授权后如果没有经绑定手机号去绑定,之前是注册接口只针对B项目,现在新增接口为了是俩个项目同步数据(通过token、和openid判断是否登录)
router.beforeEach((to, from, next) => {
//判断登录逻辑
var topath = to.path
var realtopath = '' //真实跳转路径(去除参数)
if (topath.indexOf('/', 2) != -1) {
realtopath = topath.substring(0, topath.indexOf('/', 2))
} else {
realtopath = topath
}
if (realtopath.indexOf('/') != -1) {
realtopath = realtopath.replace('/', '')
}
if(whiteList.indexOf(realtopath) != -1){
//白名单,免登录
next();
}else if(checkLocalStorage('Token') && realtopath != 'shouquan'){
//已经登录
next();
}else{
//去登录
Toast.clear()
next({name: 'shouquan'})
}
})
// response 拦截器
service.interceptors.response.use(
response => {
Toast.clear()
console.log(response)
//登录已过期,重新登录
if(response.data.return_code == '10450' || response.data.return_code == '10451'){
Toast('登录过期,请重新登录');
removeLocalStorage('Token');
router.push({name:'shouquan'})
}else {
return response
}
},
error => {
if(navigator.onLine){
Toast('服务器繁忙,请稍后再试');
}else{
Toast('当前网络不可用,请检查您的网络连接');
}
return Promise.reject(error)
}
)
新增授权页面
点击授权从定向到授权接口(此处是后端调取微信授权,我请求的是后端接口。)
methods:{
goauthorize(){
window.location.href = '授权地址,后台回调的是绑定手机号页面'
}
},
mounted(){
//拿缓存判断,如果第一次授权或者用户点击的退出,不自动授权需要用户点击授权按钮
//如果token过期,(有效期20分钟)自动授权用户无感知
document.title = '网页授权'
if(checkLocalStorage('logined')){
this.goauthorize();
}
}
mounted(){
用户输入手机号页面,点击绑定会跳转到验证码页面
document.title = '绑定手机号'
//接收的是回调地址的参数,后台授权接口携带的
this.openid = this.$route.query.openid
token = this.$route.query.token
if(token != ''){
setLocalStorage('Token', token);
setLocalStorage('logined');
this.$router.push({name:'home'})
}else {
if(this.openid != ''){
// 没有绑定手机号,还在当前页面
}else{
this.$router.push({name:'shouquan'})
}
}
}
获取验证码,绑定成功
onInput(key) {
//绑定事件
if(this.code.length==4){
// 绑定手机号
var param = {action:'user_bind_phone',
phone:this.phone,openid:this.openid,code:this.code,client_type :'h5'};
linkapi(param).then(res=> {
if (res.return_code == '000000') {
var token = res.token;
setLocalStorage('Token', token);
setLocalStorage('logined');
this.$router.replace({name:'home'})
}else {
Toast(res.return_msg);
}
});
},
mounted(){
document.title = '注册'
if(this.$route.params.phone) {
this.phone = this.$route.params.phone
this.openid = this.$route.params.openid
}
用户点击退出登入
linkapi(param).then(res=> {
if (res.return_code == '000000') {
removeLocalStorage('token')
removeLocalStorage('logined')
this.$router.replace('shouquan')
}else {
Toast(res.return_msg);
}
});
使用场景:在同一个页面菜单切换页面不变切换类目
解决方法:1.二级路由
2.动态路由
配置好了路由懒得换成二级路由所以采用动态路由:
router的path后面变成:type
{
path: "/article/:type",
name: "article",
component: () => import("./views/article.vue")
},
//article页面用watch监听
watch: {
'$route.path': function (newVal, oldVal) {
document.title = '木棉情感 - 首页 - 干货分享 - '+ this.sort
}
}
//vue单页面用less写的样式
.content{
/deep/ img{
width:100% !important;
height:auto !important;
}
}
1.封装成一个方法,并直接挂载在Vue实例上:
// 放在main.js里面
//MessageBox 弹框
Vue.prototype.$alertMsgBox = function alert(msg = '确认要删除该数据?', title = '提示', settings = {}) {
Object.assign(settings, { //合并对象
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true //允许确认框内容为html格式
})
return this.$confirm(`${msg}
`, title, settings)
}
//Message 消息提示
Vue.prototype.$messageOK = function alert(msg, title) {
return this.$message({type: msg, message: title});
}
//无需引入直接使用
this.$alertMsgBox('确认删除此条信息吗', '操作')
.then(() => {
this.$messageOK("success", "已成功");
console.log('确认')
})
.catch(() => {
this.$messageOK("info", "已取消");
console.log('取消')
})
2.封装在js文件里面(以下是Message 消息提示demo):
创建一个js文件
这两个参数就是消息提示中的状态和内容
export function alertOK(msg, title) {
this.$message({
type: msg,
message: title
});
}
export default alertOK;
函数名随便起,完成操作后倒出去
在main.js引入设置全局
import message from "./common/message/inedx.js";
给它的原型加一个属性为$messageOK可以直接使用了
Vue.prototype.$messageOK = message;
页面中使用:
this.$messageOK("info", "已取消");
this.$messageOK("success", "已成功");
vue组件传值是单向数据绑定,如果子组件直接将父组件传过来的props进行修改操作,会报一个警告
这时候需要在子组件data()重新定义一个值去接收报错的这个depByOrgList,下面是我项目中的代码
props: {
depByOrgList:{
type:Array,
}
},
data() {
return {
thedepByOrgList: this.depByOrgList
}
},
使用一个变量thedepByOrgList去接收,子组件就可以满足对父组件传过来的值进行操作了.
但是这样还是会存在一个问题,thedepByOrgList这个属性只会在组件被创建的时候赋一次值,后续如果depByOrgList这个props值有变化,thedepByOrgList并不会自动同步,这时候就需要引入vue的一个属性监听函数
watch:{
depByOrgList:function(val){
this.thedepByOrgList=val
}
}
第一种方法
let obj ={"name":"tom","age":16}
let key = "id";
let value = 2
obj[key] = value;
console.log(obj)
第二种方法,利用扩展运算符,简单又实用
var obj1={"vue":300,"jquery":200};
var obj2={"react":500};
var obj3={
...obj1,
...obj2
}
console.log(obj3)
第三种办法
let obj4 = {a:"1"};
let obj5 = {b:"2"};
let obj6 = {c:"3"};
Object.assign(obj4,obj5,obj6);
console.log(obj4)
var json = {颜色: "1708480395608103", 蓝色: "1708742016288631"};
var keyArr = Object.keys(json);
var val = json[keyArr[0]];
等同于以下:
打印Object.keys(json)出来是一个数组里面是key,用索引0来选取key在用获取对象方法 object[key]来获取值
json[Object.keys(json)[0]]
//创建formData对象
var formData = new FormData();
formData.append("excelFile",file.raw) //名字,file文件
this.fileTemp = formData
//创建请求,配置请求头类型
const importInstance = axios.create()
importInstance.defaults.baseURL= process.env.VUE_APP_BASE_API
importInstance.defaults.headers = {
'Content-Type' : 'multipart/form-data'
}
importInstance.defaults.timeout = 50000
importInstance({
method:'post',
url:'/uploadTwbDeviceList',
data:this.fileTemp //此处传formData对象
})