vue 笔记一

工作中总结或记录的一些记录。

非主父子传值
https://juejin.im/entry/59b0b36d6fb9a0247a611115
调试 vconsole
npm install vconsole

import VConsole from 'vconsole'
const vConsole = new VConsole()

Vue.use(VConsole)
物理键“ 返回 ” 监听
使用 cordova 时,如果不同的页面都调用了,都会默认调用该方法的。

遇到的问题:
如果是 安卓机只有一个 HOME 按键时,解决跳出页面?
使用计数器 count = 2 是 退出程序。
document.addEventListener("backbutton", onBackKeyDown, false);

监听软键盘 安卓手机也是 13

https://blog.csdn.net/wangjuhi/article/details/80112305
refs 的使用

使用说明:拿到对应的 标签。

 
// 焦点 this.$refs.input1.focus();
怎么给返回的值设置值
this.$set(item, 'suppementary', this.canSuppementary)
解决 ios 输入框跟着键盘顶上去
position: fixed; // 如果不想跟着顶上去,可以使用 flex布局 或绝对定位
overflow-y: scroll; // 某个方向 滚动
reduce 使用

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

给为添加的或赋值的 数组添加内容
// accumulator 累计数器
// currentValue 数组中正在处理的当前值
var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);
// 和为 6

怎么修改对象的值
 dealWithArr(arr){
            // let arr = [
            //     {barcode: "957373",
            //     entorgid: 401,
            //     itemId: 632502,
            //     itemName: "P10 柜式洗碗机 220V,1Ph <55dB E5 WQP12-W5302D-CN-A",
            //     modelManageId: 3537995,
            //     modelType: 1,
            //     organizationId: "17",
            //     stat: 1,
            //     terminalId: 88008
            //     }
            // ]
            let temArr = [], obj = {}

            arr.forEach(vv => {
                if(vv.itemName) {
                    obj.barcode = vv.barcode
                obj.entorgid = vv.entorgid
                obj.itemId = vv.entorgid
                obj.modelManageId = vv.modelManageId
                obj.modelType = vv.modelType
                obj.organizationId = vv.organizationId
                obj.stat = vv.stat
                obj.terminalId = vv.terminalId
                }
                temArr.push(obj)
            })
            return temArr;
        },
懒加载 v-lazy

使用场景: H5中 加图片

在main.js 

import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload)

// 测试 图片 --- 多张图片时 循环一遍 第一张 丢失的问题!!!!

常见错误
ERROR in ./src/mixins/vouchersMixin.js
Module not found: Error: Can't resolve 'moment' in 'D:\MyData\ex_hech\meidi
 @ ./src/mixins/vouchersMixin.js 11:14-31
 @ ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.jue

解决:
下载新的 moment 组件, npm i -moment
创建一个 公共的utilit.js

使用场景:公共方法 + mixin

1、创建一个 utilit.js 
let myMixin =  {
   
    hello: function() {
        console.log('这是测试。。。。调用mixin 方法')
    },           
}
export default  myMixin

2、在vue 里面 引入
    
    import myMixin from '../../js/mixin'
	// 调用 js的方法
	myMixin.hello(); // 这是测试。。。。调用mixin 方法

混入Vue https://cn.vuejs.org/v2/guide/mixins.html

它和上面的 公共的 .js 的区别是,它的方法是直接 使用!!! ,而不是 xxx.方法()

建立一个公共组件,然后对该组件进行混入继承.
注意会走两个生命周期,谨慎使用
mixins混入,相当于生成new 组件;组件引用,相当与在父组件内开辟了一块单独的空间
mixins适用于,两个有非常相似的组件,他们基本功能是一样的,但他们之间又存在这足够的差异性。(发票识别:增值税、黑白发票、红色发票)

1、写个 xxx.js
export default {
    methods:{
        // 处理发票, 给外面调用的方法(直接使用即可!!!)
        handleInvoice() {
            console.log('测试 mixin 调用方法');
        },
        //识别发票
        readInvoice() {
            let hasCommissionSale = this.storage.get('hasCommissionSale')
            if(hasCommissionSale) return this.$toast('旗舰店已标注无须上报')
            this.showDialog = true;
        },
    }
};

2、在vue 里引入
// 引入 mixin
import  listenerMixin  from '../../minxin/invoiceMixin.js'

在 export default {
	// 混合  
	mixins:[listenerMixin],    
}里写入。

3、调用 (直接使用 this.xxxx)
this.handleInvoice(123);
this.readInvoice();


点击跳转的写法之一
全部订单 查看全部订单
调用: goPage(url, param) { this.$router.push({ name: url, query: { param: param } }) }, ---------------------- path (路径) ------------------------- /** 跳到 业绩详情*/ orderDetail:function(item) { this.$router.$push({ // name: 'orderDetail', // 名字 params path: "/orderDetail", // 路径 query:{ // 路由参数 orderId:item.orderId, engineerCode:this.engineerCode } }); },

记忆:

path + query | name + params

记:path 是查询路径的的 (如有参数,在地址栏显示), name 是 参数的

--------------------------------------router- start -------------------------------------------------

路由跳转传值

router.push(location)

这个方法会向 history 栈添加一个新的记录,当用户点击浏览器后退按钮时,则回到之前的 URL。

// 字符串
router.push('home')

// 对象
this.$router.push({path: '/login?url=' + this.$route.path});

// 带查询参数,变成 /backend/order?selected=2
this.$router.push({path: '/backend/order', query: {selected: "2"}});

// 命名的路由 ---  路由的名称
router.push({ name: 'user', params: { userId: 123 }})

router.replace(location)

设置 replace 属性(默认值: false)的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录。即使点击返回按钮也不会回到这个页面。

加上replace: true后,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

//声明式:

// 编程式:
router.replace(...)
//push方法也可以传replace
this.$router.push({path: '/home', replace: true})

两者都可以传递参数,区别是什么?

query 传参配置的是path,而params传参配置的是name,在params中配置path无效
query在路由配置不需要设置参数,而params必须设置
query传递的参数会显示在地址栏中
params传参刷新会无效,但是query会保存传递过来的值,刷新不变 ;

5.路由配置:
传参两种方式
使用query:
this.$router.push({
  path: '/home',
  query: {
    site: [],
    bu: []
}
})
复制代码使用params:
this.$router.push({
  name: 'Home',  // 路由的名称
  params: {
    site: [],
    bu: []
}
})

获取路由参数 (是this. r o u t e . x x x , 不 是 t h i s . route.xxx , 不是 this. route.xxx,this.router.)

 let site = this.$route.query.site
  let bu = this.$route.query.bu
  // 如果是params 传参,那就是this.$route.params.site
  上面就可以获取到传递的参数了

获取路由上面的参数,用的是$route,后面没有 " r "。

总结

params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系。
params一旦设置在路由,params就是路由的一部分,如果这个路由有params传参,但是在跳转的时候没有传这个参数,会导致跳转失败或者页面会没有内容。
params、query不设置也可以传参,但是params不设置的时候,刷新页面或者返回参数会丢失,query并不会出现这种情况.

1.命名路由搭配params,刷新页面参数会丢失

2.查询参数搭配query,刷新页面数据不会丢失

3.接受参数使用this.$router后面就是搭配路由的名称就能获取到参数的值

------------------ query 和 params END --------------------------------

封装h5和ios修改导航栏颜色

 /**
 * 改变状态栏颜色-仅IOS
 * @param p {array} 参数 [r, g, b]
 * @return {*|promise}
 */
changeColor: function (p) {
        return functions.callApi(_MIDEA_COMMON, 'statusBarColor', p);
    },

-------------------------- 使用 ----------------------------
 platform.changeColor([255,255,255]);

解决iphoneX 遮罩层全屏

 mounted() {
        this.getBookId();
        platform.changeColor([255,255,255])
        if(this.isIOS){
            platform.setViewControllerBackGroundColor([{r: 247, g: 249, b: 250, a: 0.95}])
        }
    },
    activated() {
        this.reportProList = this.storage.get('reportProList') ? this.storage.get('reportProList') : [];
        platform.changeColor([255,255,255])
        if(this.isIOS){
            platform.setViewControllerBackGroundColor([{r: 247, g: 249, b: 250, a: 0.95}])
        }
        this.downLoading();
        this.addBurialPoint('FUC00052');
    },

前端监听手机进入后台pause 、恢复到前台运行 resume

 mounted() {                
            // 这里判断 --- 进入手机后台操作什么的。。。
            document.addEventListener('resume', ()=> {
                console.log('进入后台',this.myAddr);
                this.myAddr = {}; // 清空(如果不清空的话,故意不定位,点击拍照后才知道没有开启定位)                
                // 再次定位
                this.getCurrentAddr();               
            })               
        },

------------------------ deviceready --------------------------当cordova被完全加载时会触发deviceready事件,这是每个cordova应用程序都会用到的重要事件。

document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {

    // Now safe to use device APIs

}
------------------------ pause ---------------------------------
document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {

    document.addEventListener("pause", onPause, false);

}

function onPause() {

    // Handle the pause event

}

------------------------ resume -------------------------------
document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {

    document.addEventListener("resume", onResume, false);

}

function onResume() {

    // Handle the resume event

}

  

cordova 的使用!!! HTML+原生

-------------------------------- Vuex start --------------------------------------------------------

官网api https://vuex.vuejs.org/zh/api/#state

vuex

export default {
    state,// 唯一根实例(根状态,只读)
    actions, 
    getters, // 暴露出注册的 getter,只读。
    mutations // 唯一更改值 (和 actions 非常像. mutation 必须是同步函数)
}

使用:
0.import { mapState } from 'vuex'

1、
mutations:在组件中使用就是:
this.$store.commit('xxx') 或者 ...mapMutations (['xxx'])

2、
 ...mapMutations({
      add: 'increment' // 将 `this.add()` 映射(相当于)为 `this.$store.commit('increment')`
    })
就是 可以直接使用 this.add(xxx) 其中 add 不是data声明的属性(vuex里的)。
3、
const mutations ={
    'Increment':(state,data)=>{
        state.increment = data
    },   
    'ENTER_REFRESH':(state ,data)=> {
        state.enterRefresh = data
    }
};
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
Action 通过 store.dispatch 方法触发:
Vue.use(Vuex); // 全局(注册)
:就是在根实例(state)注册后,就可以通过 this.$store 访问了。
this.$store.state.count

Vuex.Store 实例方法

commit

import {mapState, mapActions, mapMutations} from 'vuex';

commit(type: string, payload?: any, options?: Object)
commit(mutation: Object, options?: Object)
提交 mutation 时。options 里可以有 root: true,它允许在命名空间模块里提交根的 mutation。

使用:
	 this.$store.commit('NEW_TERMINAL_ARR', this.terminaArr);
     this.$store.commit('DATE_IS_RESET', false);

dispatch

import {mapState, mapActions, mapMutations} from 'vuex';

dispatch(type: string, payload?: any, options?: Object)
dispatch(action: Object, options?: Object)
分发 action。options 里可以有 root: true,它允许在命名空间模块里分发根的 action。返回一个解析所有被触发的 action 处理器的 Promise。

使用:
this.$store.dispatch('getPromotionActivityDetail', params).then(data => { }

replaceState

replaceState(state: Object)
替换 store 的根状态,仅用状态合并或时光旅行调试。

watch

watch(fn: Function, callback: Function, options?: Object): Function
响应式地侦听 fn 的返回值,当值改变时调用回调函数。fn 接收 store 的 state 作为第一个参数,其 getter 作为第二个参数。最后接收一个可选的对象参数表示 Vue 的 vm.$watch 方法的参数。
要停止侦听,调用此方法返回的函数即可停止侦听。

使用:
 watch: {
            keyword(newVal, oldVal) {
                // 防抖动
                var timer = setTimeout(() => {
                    clearTimeout(timer);
                    this.downLoading();
                }, 1000)
            }
        }

subscribe

通常用于插件

辅助函数

mapState

为组件创建计算属性以返回 Vuex store 中的状态.

mapState(namespace?: string, map: Array | Object): Object

mapState

https://juejin.im/post/5ae433ab518825671a6388d5

import { mapState, mapAction } from 'vuex'
  computed: {
        ...mapState({
            todoList: state => state.demo.todoList
        })
    },

mutatuions.js

// 使用:例如:…mapState({nearbyAddress: state => state.xxx.nearbyAddress,//选择的附近位置信息})

const mutations = {        
	 // 附近的位置
     'NEARBY_ADDRESS': (state, list) => {
         state.nearbyAddress = list;
     },
     // 当前地址
    'SETCUR_ADDR': (state, curAddr) => {
        state.curAddr = curAddr
    },
}
export default mutations;

mapState

  // mapState辅助函数:计算多个状态值
  computed: mapState({
    cc: state => state.workReport.cc,
    userInfo: state => state.com.userInfo,
    bookId: state => state.activity.bookId,
    defaultCC: state => state.workReport.defaultCC,
  }),

mapActions

创建组件方法分发 action

mapActions(namespace?: string, map: Array | Object): Object


mapMutations

mapMutations(namespace?: string, map: Array | Object): Object

创建组件方法提交 mutation。

vuex

与商店有关的使用(注册后可使用): this.$store

1、同步提交
this.$store.commit('SETCUR_ADDR',addr); 
2、清空提交
this.$store.('SETCUR_ADDR',{}); 

3、state 创建那么多属性对象,怎么使用?
通过 mapState助手 来使用。(作用是:计算多个对象、属性)

computed: mapState({})
或者: 
computed: {  // 作用是:计算多个对象、属性
    ...mapState({
        shopList: state => state.shop.clientListSearch,
        orgId: state => state.shop.orgId,//产品中心id
        userInfo: state => state.com.userInfo,            
    })
},
-------------------- 实现 ----------------------
1、创建 store.js
action(dispatch、commit)\mutations(mutate)\state (render)

引入:   import {api} from '../api';
		import ajax from '../ajax';
state: (存放对象或属性的。供 action 或 mutation 调用它定义的属性 )
const state = {
    companyList: [],//产品中心列表
    shopList: [],//门店列表
    terminalName: '',//门店名
    shopDetail: {},
}
getter:
const getters = {};

const actions = {
	getShopList({commit, dispathc, state}, param) {
        return ajax.post(api.getMktInspectionTerminal, param)
    },
    getClientList({commit, dispathc, state}, param) {
        return ajax.post(api.getMktInspectionCustomer, param)
    },
};

mutations:
const mutations = {
	// 方法名
    'GET_COMPANY_LIST': (state, list) => {
        state.companyList = [];
        list.map((v, i, t) => {
            v.active = false;
            state.companyList.push(v);
        });
    },
    'SETCUR_ADDR': (state, curAddr) => {
        state.curAddr = curAddr
    },
};

export default {
    state,
    getters,
    actions,
    mutations
}
mutatuons: --------------- 使用
// 设置当前定位 (使用方法:state.currentLocation)
 ...mapState({
     currentLocation: state => state.sign.currentLocation,
 })

// 定位的对象
'SET_LOCATION_CURRENT': (state, data) => {
    state.currentLocation = data;
},
this.$store.commit 到哪里?
this.$store.commit 的值实际上就是 mutations 。

怎么使用?:
computed: {
    ...mapState({
         currentLocation: state => state.sign.currentLocation,
     })
 }

---------------------------------------------------- Vuex end -----------------------------------

this 闭包了。

const self = this
处理参数带“反斜杠”
 let tempString = JSON.stringify(config.data).replace(/\\/g, "%")
   
 项目打印显示是被转成了 "%",如果是其它的话,根据项目的打印替换。
在移动端的点击返回按钮的 "返回"形式

场景:返回时,动画效果是不一样的。

加上 $ 和去掉 $ 是有区别的。(右往左,和左往右)
prototype 原型
prototype 属性使您有能力向对象添加属性和方法。
语法:
object.prototype.name=value

怎么使用某个组件

1、引入路径
import DatePicker from "../../components/public/datePickerV2/date-picker.vue";
2、引入组件
components: {
    DatePicker
  },
3、使用组件

4、@ 代表: 方法 ,: 代表属性

安装某个版本插件

npm uninstall better-scroll
npm i better-scroll@1.13.4

// 默认 前面有个箭头 (手动去掉 package.json)
 "better-scroll": "^1.13.4",

时间选择器

滴滴内部组件: https://didi.github.io/cube-ui/#/zh-CN/docs/date-picker

// ---------- 解决日期选择滑动 卡死 --------------
npm uninstall better-scroll
npm i better-scroll@1.13.4	

旧版的toast

main.js

import Toast from './components/toast'
Vue.use(Toast)

响应式

 this.$set(item, 'checked',false)
监听真机物理返回键
 /** 监听物理返回按钮 */
  beforeRouteLeave (to, from , next) {
      // next(false)//可以通过在这里写逻辑来处理用户点了物理返回之后的操作
      // console.log('监听物理返回按钮'); // replace    
      // 清空图片选择相册 记录
      localStorage.removeItem('limitThree');  
        // 清空
        // if(to.name == "cleanseHome"){
          // localStorage.setItem('noRef',true);
          // this.$router.push({name:"createMenu"});
        // }else{
          // localStorage.setItem('noRef',true);
          next();
        // }
  }
怎么拿到当前月的最后一天
 var year = date.getFullYear();
      var month = date.getMonth() + 1;
      var day = date.getDate();
      var lastDate = new Date(year, month, 0).getDate();
      this.endDate = year + '-' + (month>9?month:'0'+month) + '-' + lastDate;
      console.log('当前时间是:',this.endDate , this.maxTime);
没有数据占位符:样式
.no_data{
        position: absolute;
        top:58%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
        overflow: hidden;   
        .no_data_img {
            width: 138px;
            height: 83px;
        }
        .no_data_content {
            margin-top: 20px;
            font-family: PingFangSC-Regular;
            font-size: 16px;
            color: #999999;
            text-align: center;
        }
    }
解决安卓机键盘把元素顶上去

场景: 点击搜索时,下面的或底部的 “提交按钮” 被键盘顶上去了。

// 父元素添加 最小高度,子元素 使用 abstrolute
min-height: 500px;
height: 100%;
去掉滚动的细线:
xxxx::-webkit-scrollbar {
            display: none;
            height: 0;
        }
兼容(解析值)
消息推送:
使用 JSON.parse 解析,才有值。
  console.log('消息id:',data.extra.showWidgetKey.workAttendanceId); // undefind
                        console.log('兼容id:',JSON.parse(data.extra.showWidgetKey).workAttendanceId); // 有值
                        
 this.$router.$replace({
                                path: "/leaveRecord",
                                query: {
                                    workAttendanceID: JSON.parse(data.extra.showWidgetKey).workAttendanceId,
                                }
                            });
-----------------------------------------------

document.addEventListener("deviceready", () => {
                platform.getExtra(["com.midea.msd.guideCommunity"]).then((data) => {
                    let extraData = data.extra
                    if(!data.extra){
                        this.getDefaultData(this.employeeType);
                        return false;
                    }
                    ajax.setDefault(this.employeeType);
                    this.getBaseDataNew();

                    // //设置消息
                    let tempData = data;

                    console.log('date........' , data);

                    console.log('JSON.parse(data.extra.showWidgetKey).....' , JSON.parse(data.extra.showWidgetKey));

                    console.log('data.extra.showWidgetKey.....' , data.extra.showWidgetKey);

                    if(data.extra.action){
                        data.extra = data.extra;
                    }else if(data.extra.showWidgetKey.action){
                        data.extra = data.extra.showWidgetKey;
                    }else if(JSON.parse(data.extra.showWidgetKey).action){
                        data.extra = JSON.parse(data.extra.showWidgetKey);
                    }


                    switch (data.extra.action || data.extra.showWidgetKey.action || JSON.parse(data.extra.showWidgetKey).action) {

                        case 'interactiveForumAdoption': //回答被采纳 --- 回答详情
                            this.$router.$replace({ // 参数replyId
                                name: "answersDetail",
                                query: {
                                    replyId: data.extra.id,
                                    comFrom: data.extra.comFrom,
                                    bookId: data.extra.bookId
                                }
                            });
                            break;
                        case 'interactiveForumReply': //回复有了新评论 -- 全部评论
                            this.$router.$replace({ // 参数replyId
                                name: "allCommont",
                                query: {
                                    // commentId: data.extra.commentId,
                                    replyId: data.extra.id,
                                    comFrom: data.extra.comFrom,
                                    bookId: data.extra.bookId
                                }
                            });
                            break;
                        case 'interactiveForumQuestion':  //问题有了新回复--- 问题详情
                            this.$router.$replace({ // 参数replyId
                                name: "answersDetail",
                                query: {
                                    replyId: data.extra.id,
                                    comFrom: data.extra.comFrom,
                                    bookId: data.extra.bookId
                                }
                            });
                            break;
                        case 'interactiveForumAskQuestion':  //跳问题详情
                            this.$router.$replace({ // 参数replyId
                                name: "problemDetails",
                                query: {
                                    questionId: data.extra.id,
                                    comFrom: data.extra.comFrom,
                                    bookId: data.extra.bookId
                                }
                            });
                            break;
                        case 'toMyfans':  //跳我的粉丝
                            this.$router.$replace({
                                name: "myFans",
                                query: {
                                    comFrom: 1,
                                }
                            });
                            break;
                        case 'toMycontent':  //跳我的关注
                            this.$router.$replace({
                                name: "myAttention",
                                query: {
                                    comFrom: 1,
                                }
                            });
                            break;
                        case 'toMyAnswer':  //跳我的回答
                            this.$router.$replace({
                                name: "myAnswers",
                                query: {
                                    comFrom: 1,
                                }
                            });
                            break;
                        case 'fromAssitant':
                            let tempData = {};
                            let defaultData = {};
                            tempData = data.extra.showWidgetKey;
                            if (this.judgeClient() == "Android") {
                                defaultData = JSON.parse(tempData);
                            } else {
                                defaultData = tempData
                            }
                            this.employeeType = defaultData.employeeType
                            this.bookId = defaultData.bookId
                            this.$store.commit('SET_BOOKIS', this.bookId);
                            this.getDefaultData(this.employeeType);
                            break;
                        default:
                            this.getDefaultData(this.employeeType);
                    }
                })
            })
怎么修改input的默认颜色
input默认颜色是:#999999

input::-webkit-input-placeholder{
    color: #999999;
}

样式写法

{{currentPerson.praiseNum?currentPerson.praiseNum:'0'}}
// -------------- 样式写法 (有 “ - ” 号的使用 & )-------------- .ranking_information_item{ flex: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; &-desc{ // font-family: PingFangSC-Semibold; font-family: DINAlternate-Bold; font-size: 20px; color: #333333; text-align: center; line-height: 26px; } &-descNum{ font-family: DINAlternate-Bold; font-size: 20px; color: #00B9FF; text-align: center; line-height: 26px; } &-cate{ font-family: PingFangSC-Regular; font-size: 14px; color: #999999; text-align: center; line-height: 11px; margin-top: 6px; } }
激活按钮颜色: isActivity 是属性, submitButton是样式!!!

提交
// -------- 方法 ------------ confirmGift() { this.addOutSide(); }, //新增用户接口 addOutSide() { if (this.limitSub) return false; if (!this.checkoutAll()) return; this.limitSub = true; let params = { } --------------------------------------------------- // div
测试
// 样式 .praiseDetails_content { margin-top: 45px; padding: 0 15px; font-family: PingFangSC-Regular; font-size: 14px; color: @col-333; display: flex; flex-direction: column; justify-content: center; .mar{ margin-right: 0; } &-preview{ display: flex; justify-content: flex-start; } } // ------------------------- 写法 -------------------------------
// 样式 --- 层层累加 .content { &-items { &-title { &::before {} } &-test {} } } // --------------------- 使用 &: 链接 -------- 5n :表示5的倍数 奇数:“odd”、 偶数:“even” &:nth-of-type(8){ margin-right: 0; } // ---------------------------- ---------------------------------------- // --- 样式 .dialog-footer{ &-control{ &-item{ padding: 15px 0; width: 100%; text-align: center; font-family: PingFangSC-Regular; font-size: 14px; color: #333333; } } } //-------------- 字体 间距------------------------- letter-spacing: 0.58px; // --------------- 搜索 ---------------------------
// --------------- 样式 ----------------- margin-top: 45px; // s 不使用公共的样式 .search-boxs{ margin-top: 60px; background: #fff; .inputBox{ width: 100%; padding: 0px 15px 15px 15px; display: flex; position: relative; form{ flex: 1; display: flex } input{ flex: 1; height: 28px; border: 1px solid #f5f5f5; border-radius: 16px; outline: none; background: #f5f5f5; text-indent: 30px; font-size: 14px; padding-right: 33px; } .col-333{ color: #333; } // 去掉默认的 叉 input::-webkit-search-cancel-button { display: none; } .icon-chaxunx{ position: absolute; top: 8px; right: 32px; color: #999999; font-size: 13px; } .icon-chax{ position: absolute; top: 7px; right: 31px; color: #d8d8d8; font-size: 15px; } } }
怎么自定义组件
 "calendar"
          @select="selectDate"
          :attendanceList="attendanceList"
          :selMonth="curMonth"
          @preMon="preMon"
          @selectMon="showDatePicker"
          @nexttMon="nexttMon">

// ----- @xxx 表示是 自定义组件的 方法, :xxx 表示是自定义组件 的属性(  props: {})
总结:他们是一 一 对应的!!!

例如:
	  props: {
	  	// 是否显示农历
         lunar: {
                type: Boolean,
                default: false
         },
	    // 自定义月份名称
        months: {
            type: Array,
            default: function () {
                return window.navigator.language.toLowerCase() == "zh-cn" ? ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
            }
        },
          selMonth: {
                type: String,
                default: ''
            },
          attendanceList: {
            type: Array,
            default() {
                return []
            }
        }
	  }
      min-height: 44px; // 50 一定要给高 (否则低端安卓机不会显示)
      transform: translateY(2px); // 向上偏移 2个像素(比定位好多了)
伪类的使用:
class="content-items-title"
    {
    position: relative;
    font-family: PingFangSC-Medium;
    font-size: 16px;
    }
    
    --------------------- 文字前面显示一个 颜色点 ------------------------
     &-items {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px 0;

            &-title {
                position: relative;
                font-family: PingFangSC-Medium;
                font-size: 16px;

                &::before {
                    content: '';
                    width: 4px;
                    height: 12px;
                    position: absolute;
                    left: -15px;
                    top: 5px;
                    background: @skyBlue;
                }
            }
       }
    ---------------------------------------------------
    0、::before{}
    1、 content: '';
    2、大小、宽高、定位什么的

选择左右:

 
1.请选择本次上门清洗人员的服务内容 *
{'service-item-click': item.choose}" @click="choiceServiceList(index)" >{{item.name}}
强制刷新
 // 强制刷新
 // this.$forceUpdate();
地图标记
引入样式 map.less

自定义组件

头部组件






ios怎么和HTML建立通信(混合开发)?
vue 里需要引入 





    "utf-8">
    "viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    h5-dev-mobile-funny-sign
    



    
"app">

vue 创建一个 platform 文件夹

里面创建一个 index.js

http://dy.163.com/v2/article/detail/DQSGL5PK05492JTS.html

例如:通知(ios 和 网页的使用) ---- Cordova嵌入webview使用(iOS)

https://www.jianshu.com/p/c629b820f914
http://www.pianshen.com/article/5731242536/
https://rensanning.iteye.com/blog/2019289 (必看)
---------------------- 强大的 Cordova 框架 (原生开发和VUE(H5)混合开发)----------------------
Cordova前身是phonegap,而PhoneGap是Nitobi软件公司2008年推出的一个框架,旨在弥补web和iOS之间的不足,使得web和iPhone SDK之间的交互更容易。https://www.jianshu.com/p/c629b820f914

JiaCordova是为了让项目对于Cordova引入更加方便快捷的一个封装式插件,插件中已经集成的关于Cordova跟其一些常用的第三库,对于Cordova的配置模板也进行整理,且封装从服务端下载ZIP包进行解压到沙盒文件夹中,利用Cordova进行请求的功能;最大程度上简化关于Cordova的运用跟学习成本;(https://www.cnblogs.com/wujy/p/6908454.html)

 
https://blog.csdn.net/u011042316/article/details/83828371

Cordova框架中第一个应该掌握的就是这个 deviceready 事件。

Cordova提供的通过HTML5调用Native功能并不是立即就能使用的,Cordova框架在读入HTML5代码之后,要进行HTML5和Native建立桥接,在未能完成这个桥接的初始的情况下,是不能调用Native功能的。在Cordova框架中,当这个桥接的初始化完成后,会调用他自身特有的事件,即deviceready事件。 

js 代码:
document.addEventListener('deviceready', function () {  
  console.log('Device is Ready!');  
  // ....your code  
}, false);  


Promise


子父组件传值

https://blog.csdn.net/wy6250000/article/details/83793400
https://segmentfault.com/a/1190000014381699
https://www.cnblogs.com/sichaoyun/p/6690322.html

https://segmentfault.com/a/1190000010530600?utm_source=tag-newest

vue的父子组件间通信可以总结成一句话:
父组件通过 prop 给子组件下发数据,子组件通过$emit触发事件给父组件发送消息,即 prop 向下传递,事件向上传递。

Prop (常用)

单选
 //单选
        getChecked(item,idx) {
            this.activityColor = true;

           this.list[idx].checked = !this.list[idx].checked
           this.tempArr = this.list.filter(v => v.checked)
            
           if(this.list.length == this.tempArr.length && this.tempArr.length != 0) {
               this.isAll = true
           } else {
               this.isAll = false;               
           }
            // 置灰色
           if (this.tempArr.length == 0 ) {
               this.activityColor = false;
           }
          console.log('6666',this.tempArr.length);
            
                     
        },
全选
 //全选
        allChecked(type) {
             this.activityColor = true;

            if(!type){
                this.list.forEach((item, index)=> {
                    item.checked = true
                    this.tempArr.push(item);

                })
                this.isAll = true
            } else {
                this.list.forEach((item, index)=> {
                    item.checked = false
                })
            }

            this.tempArr = this.list.filter(v => v.checked)

            if(this.list.length == this.tempArr.length && this.tempArr.length != 0) {
               this.isAll = true
           } else {
               this.isAll = false;
               this.activityColor = false;
           }
        },
=号的区别

简单来说就是使用“”时,如果两边类型不同,js引擎会把它们转换成相同类型然后在进行比较,而“=”则不会进行类型转换,因此当两边不是属于同一个类型,肯定不相等。

var a = 0, b = '0';

alert((a == b) + '--' + (a === b))

此时看到的结果为“true–false”
垂直居中
"" class="mask">
// 样式 position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 201; background: #000; opacity: 0.5;
"" class="popover-body">
"" class="list">
"" class="item bd-bottom "> 写日报
"" class="item bd-bottom">写周计划
"" class="item bd-bottom">写月报
// 样式 position: absolute; top: 50%; left: 50%; width: 242px; height: 150px; -webkit-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); background: #fff; border-radius: 5px; z-index: 202;

闭包


js去重


使用过滤和数组的区别

this.tempArr = this.list.filter(v => v.checked)
// 效果一样(代码长度可不一样!!!) 

this.list.forEach(item => {
  // 保存在一个临时数组里
  if(item.checked ){
      this.tempArr.push(item);                  
  }
})
左右结构 (左边给个固定宽度,右边给个自适应flex)
.prototypeSampling_page .prototypeSampling_content .space[data-v-3893e4d5] {
    -webkit-box-pack: justify;
    -webkit-justify-content: space-between;
    justify-content: space-between;
}
.block .left {
    -webkit-flex-basis: 100px;
    flex-basis: 100px;
}
.right {   
    display: -webkit-flex;
    display: flex;
}
防抖功能 (示例:搜索)
 // 确认搜索
searchWord() {
    //防抖
    clearTimeout(this.timeId);

    this.timeId = setTimeout(() => {
        this.getConditionModelList();
    }, 300);
},

搜索框(样式)




----------------- 搜索 ----------------------------
 margin-top: 45px;
        // s 不使用公共的样式
        .search-boxs{
            margin-top: 60px;
            background: #fff;
            .inputBox{
                width: 100%;
                padding: 0px 15px 15px 15px;
                display: flex;
                position: relative;

                form{
                    flex: 1;
                    display: flex
                }
                input{
                    flex: 1;
                    height: 28px;
                    border: 1px solid #f5f5f5;
                    border-radius: 16px;
                    outline: none;
                    background: #f5f5f5;
                    text-indent: 30px;
                    font-size: 14px;
                    padding-right: 33px;
                }
                .col-333{
                    color: #333;
                }
                input::-webkit-search-cancel-button {
                    display: none;
                }
                .icon-chaxunx{
                    position: absolute;
                    top: 8px;
                    right: 32px;
                    color: #999999;
                    font-size: 13px;
                }
                .icon-chax{
                    position: absolute;
                    top: 7px;
                    right: 31px;
                    color: #d8d8d8;
                    font-size: 15px;
                }
            }
        }

只要某个item有下划线,其它的没有。应该怎么处理?
分开使用,制定一个公共的 样式,有的就赋值上去。 或使用h5 的样式,指定某个的样式
触摸事件(百度的)
支持vue2.0的面向指令的touch指令,基于touchjs(原百度实现的移动端手势库)
vue2.0之后的要使用next分支才行,之前的使用master分支即可

npm install vue-touch@next --save

import VueTouch from 'vue-touch'

Vue.use(VueTouch,{name:'v-touch'});

其中tap是模拟点击事件,pinch 模拟双指缩放,rorate是模拟旋转手势,swipe模拟快速滑动,drap模拟拖拽,hold表示长按,doubletap模拟双击。

侧滑删除:
https://blog.csdn.net/qq_33026699/article/details/82733574

https://segmentfault.com/a/1190000011062124
js 字符串 json 间的转化
JSON.stringify(this.backObj);
JSON.parse(this.paramsValue));
防止返回多次调用
this.$router.replace({path:'./prototypeSampling'});
搜索-- 防抖动 节流
 
    
 // --------------------- js --------------------
 searchWord(e,val) {
      console.log('val',val);
      
      if (this.condition || e.keyCode === 13) {
        this.condition = val;
        // --- 防抖 
        let timer = setInterval(() => {
            clearInterval(timer);
            // 发送请求 
            this.downLoading();
          }, 500);       
      }
    },
    
    或者 (性能没那么好)
    
    watch: {
    condition (oldVal, newVal){
      if (newVal != oldVal) {
          let timer = setInterval(() => {
            clearInterval(timer);
            this.downLoading();
          }, 500);
      }
    }
  }

flex

div:nth-of-type(2) {flex-basis: 80px;} 设置第二个弹性盒元素的初始长度为 80 像素:

async

/*** 获取用户消息 */
​  async initPlatform(){
​  }

js some的使用

var hasWasher =  rep[12].some(item=>{
    if(item.baseDataId=='12'){
        return true
    }
})
过滤器的使用

 filters: {
	// 时间显示1位数时前面要加0
    getLocalTime: function(timestamp) {
      var d = new Date(timestamp);
      var date =
        d.getFullYear() + "-" +
        (d.getMonth() + 1 < 10 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1 )+ "-" +
        (d.getDate() <10 ? '0' + d.getDate() : '' + d.getDate() )+ " " +
        (d.getHours() <10 ? '0' +d.getHours() : d.getHours()) +
        ":" +
        (d.getMinutes() <10 ? '0'+d.getMinutes(): d.getMinutes()) +
        ":" +
        (d.getSeconds() < 10 ? '0'+d.getSeconds() : d.getSeconds());
      return date;
    }
  },
  
------------------- 使用 -----------------------
{{item.subReportDate | getLocalTime}}
发送请求
api:
	const api = {    
    	addWeekWorkPlan:     'addWeekWorkPlan',//周计划上报
	}
actions:
    const actions = {
		//周计划上报
      addWeekWorkPlan({commit}, param) {
        return ajax.post(api.addWeekWorkPlan, param);
      },
   }
-------------------------使用场景-----------------------------
this.$store.dispatch('getPromotionActivityDetail', params).then(data => {}

或者 (使用辅助函数)
 methods: {
      ...mapActions([        
        'addWeekWorkPlan'
      ]),
	this.addWeekWorkPlan(param).then(data => {}
}
怎么适配android、ios 0.5像素边框

在移动端有时候,设置 border 0.5 上是有兼容问题的,有些安卓机就是不显示。那么可以:

使用伪类

.item_btn{
    display: inline-block;
    margin-right: 7px;
    width: 86px;
    height: 32px;
    line-height: 32px;
    font-size: 13px;
    text-align: center;
    color: #00b9ff;
    position: relative;
    &::after{
        content: " ";
        position: absolute;
        left: 0;
        right: 0;
        z-index: 2;
        border-radius: 8px;
        width: 200%;
        height: 200%;
        border: 1px solid #00B9FF;
        transform-origin: 0 0;
        transform: scale(0.5, 0.5);
    }
}

使用 高德、百度地图 之间的转化

(坐标转换:https://lbs.amap.com/api/javascript-api/reference/lnglat-to-address#m_AMap.convertFrom)
1、项目里面使用的是 高得地图。
有的模块提使用百度提交, 需要转 百度。(现在优化的 是硬件GPS 转 高德 提交!!!)
2、省略 再转百度,然后提交的步骤。

// 高德转百度后 
tranBaidu(addr, type) {
    console.log('百度转化前的经纬度是:',addr,type);
    var newShopStr = addr.longitude + ',' + addr.latitude;
    console.log('百度转换接口的值:',newShopStr);

    var url = 'http://api.map.baidu.com/geoconv/v1/?' + 'coords=' + newShopStr + '&from=1&to=5&ak=YcbD6LjauYE0HLSwmejmOzTrshR5uAR3';
    var tranBaidu = axios.create();
    tranBaidu.get(url).then(rep => {
        if (rep.status === 200 && rep.data) {

            addr.longitude = rep.data.result[0].x;
            addr.latitude = rep.data.result[0].y;

        } else {
            let errMsg = rep.msg || '转换失败'
            console.log('转换失败' + errMsg)
        }
    }).catch(err => {
        console.log('百度转换接口出错')
        err = err || '百度转换接口出错'
        console.error(err)
        throw(err)
    })
},

2、其它(GPS)经纬度转高德(拿到 经纬度)
// gps坐标转换高德
tranGaode(myAddr) {
    // var myAddr = storage.get('curAddr')
    var gps = [myAddr.longitude, myAddr.latitude]
    AMap.convertFrom(gps, 'gps', (status, result) => {
        if (result.info === 'ok') {
            console.log('先是百度转高德:',gps);

            myAddr.longitude = result.locations[0].M;
            myAddr.latitude = result.locations[0].O;
            this.$store.commit('SETCUR_ADDR', myAddr);
            this.initMap(myAddr)
        }
    });
},

百度地图的 红色标注

需要在自己的样式里面引入的.

例如:
	 .amap-marker-content{
    .icon-map-marker{
      background-image: url("../images/local.svg") ;
      background-position: center center;
      background-repeat: no-repeat;
      color: @white;
      background-size: 26px;
      width: 27px;
      height: 37px;
      text-align: center;
    }
  }

对输入的文字(有特殊字符什么的)处理 – 正则

util.decode(str)

// 封装
 /*
  * 转换特殊字符*/
  /*编码*/
  encode:function(str) {
    var patt=/[\ud800-\udbff][\udc00-\udfff]/g; // 检测utf16字符正则
    str = str.replace(patt, function(char){
      var H, L, code;
      if (char.length===2) {
        H = char.charCodeAt(0); // 取出高位
        L = char.charCodeAt(1); // 取出低位
        code = (H - 0xD800) * 0x400 + 0x10000 + L - 0xDC00; // 转换算法
        return "&#" + code + ";";
      } else {
        return char;
      }
    });
    var entityMap = {
      "&": "&",
      "<": "<",
      ">": ">",
      '"': '\"',
      // "'": ''',
      "/": '/',
      "$":'$',
      // "\\":"\\"
    };
    // encodeURIComponent该方法是为了兼容后端不兼容\的问题
    // return encodeURIComponent(String(str).replace(/[&<>"\/$]/g, function (s) {
    //   return entityMap[s];
    // }));
      var delStr =  String(str).replace(/[&<>"\/$]/g, function (s) {
          return entityMap[s];
      });
      // 
      return delStr.replace(/\n/g,'\\n').replace(/\\u00a0|\s+/ig, '');
  },
  /*解码*/
  decode:function (s) {
      // return decodeURIComponent(s);
    if(!s){
      return '';
    }
    var entityMap = {
      "&":"&" ,
      "<":"<" ,
      ">":">" ,
      '"':'"' ,
      // ''': "'" ,
      '/':"/",
      '$':'$',
      // "\":"\\"
    };
    // return String(s).replace(/("&"|"<")/g, function (s) {
    //   return entityMap[s];
    // });
    for(let i in entityMap){
      s = s.replace(new RegExp(i,'g'),entityMap[i]);
    }
    var patt =/&#(\w{6}|\d{6});/g;
    s = s.replace(patt,function (code) {
      var char,H,L;
      char =code.replace(/&#/g,'');
      char =char.replace(/;/g,'');
      H = Math.floor((char-0x10000) / 0x400)+0xD800; // 高位
      L = (char - 0x10000) % 0x400 + 0xDC00; // 低位
      return String.fromCharCode(H,L);
    });
    // return decodeURIComponent(s);
      return s;
  },
input 文字缩进
padding-left: 0.5em;
使用rem 和 %
链接:http://caibaojian.com/rem-vs-em.html

rem 和 em 单位是由浏览器基于你的设计中的字体大小计算得到的像素值。
em 单位基于使用他们的元素的字体大小。
rem 单位基于 html 元素的字体大小。
em 单位可能受任何继承的父元素字体大小影响
rem 单位可以从浏览器字体设置中继承字体大小。
使用 em 单位应根据组件的字体大小而不是根元素的字体大小。
在不需要使用em单位,并且需要根据浏览器的字体大小设置缩放的情况下使用rem。
使用rem单位,除非你确定你需要 em 单位,包括对字体大小。
媒体查询中使用 rem 单位
不要在多列布局中使用 em 或 rem -改用 %。
不要使用 em 或 rem,如果缩放会不可避免地导致要打破布局元素
路由守卫
场景: 路由跳转前做一些验证,比如登录验证,是网站中的普遍需求等。

vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫。


  beforeRouteLeave(to, from, next) {
	to: Route: 即将要进入的目标 路由对象
	from: Route: 当前导航正要离开的路由
	next(); 
	next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
  },

闭包:或者说”闭包函数“ — 很多高级的应用都是通过闭包才能实现的。

1、它是一个函数。
2、它可以访问 一个函数内部的局部变量。
原理:js中只有函数内部的”子函数“ 才能读取局部变量。
需求:
	怎么从外部读取局部变量?(闭包:就是在一个函数里面再定义一个函数)。
优点:
	1、可以读取函数内部的变量。
	2、让那些变量始终保持在内存中。
注意:(缺点)
	1、保存在内存中。不会被释放,导致性能问题。需要手动释放。
	2、
let 形成了一个块级作用域。
这就是为什么,for 循环的时候定义 for(let i=0;xxx;xxx)的原因了。或post 传参数的时候。
let params = {
    dayDate: this.currentDate,
    sysId: 'mmp',
};
 this.$store.dispatch('getWorkDayDetails', params).then(data => { }).catch(e=>{
    this.$hideLoading();
    this.$toast(e || 'getWorkDayDetails接口出错');
})

block、异步、promise 的使用?


promise

 return Promise.resolve(rep.List);
解构
import { XTextarea, Group, Actionsheet, Popup } from "vux";

slot的使用: 具名插槽、插槽
自定义组件使用

另外slot 插槽还可以定义默认值,如果父组件没有对应的插槽标签,那么deom上显示的是 标签里的内容.
//  具名插槽
 
// 这个 444 是不会显示的(因为有了 具名插槽的存在)
444 // 如果 right 没有对应的值,就显示 555 555

路由传参数 https://blog.csdn.net/qq_40851816/article/details/80695124

区别:
传递参数会拼接在路由后面,出现在地址栏
this.$router.push({path: ' 路由 ', query: {key: value}});   参数取值  -- this.$route.query.key

使用这种方式,参数不会拼接在路由后面,地址栏上看不到参数
this.$router.push({name: ' 路由的name ', params: {key: value}})  参数取值  -- this.$route.params.key

监听物理键返回
/** 监听物理返回按钮 */
  beforeRouteLeave (to, from , next) {
      // next(false)//可以通过在这里写逻辑来处理用户点了物理返回之后的操作
      console.log('监听物理返回按钮'); // replace    
      // 清空图片选择相册 记录
      localStorage.removeItem('limitThree');  
        // 清空
        // if(to.name == "cleanseHome"){
          // localStorage.setItem('noRef',true);
          // this.$router.push({name:"createMenu"});
        // }else{
          // localStorage.setItem('noRef',true);
          next();
        // }
  }
过滤器 – 就是筛选掉不想要的,或转化成想要的值。
// 写一个文件或 定义一个过滤方法。
const vFilters = {
    orgFilter: (val) => {
        let returnName = ''
        switch (val) {
            case '10':
                return returnName= '家用空调'
            case '11':
                return returnName = '冰箱'
            case '12':
                return returnName = '洗衣机'
            case '13':
                return returnName = '中央空调'
            case '14':
                return returnName = '环境电器'
            case '15':
                return returnName = '生活电器'
            case '16':
                return returnName = '微清'
            case '17':
                return returnName = '厨房和热水'
            default:
                break;
        }
    }
}
使用过滤器
{{item.organizationId | orgFilter}}
// 显示的ui是 对应的值。

vuex状态管理

1、项目创建后,然后安装vuex,使用命令:npm install vuex --save
2、然后我们执行npm run dev 启动项目。
3、然后我们在项目的src目录下新建一个目录store。
4、必须 引入import vue 和 vuex ,然后 Vue.use(xxx)

说明:

1、state 数据源
2、getter 相当于 vue中的computed 计算属性。(getter可以用于监听、state中的值,并返回计算后的结果)

使用:

import { mapGetters, mapActions } from "vuex";
 methods: {
    ...mapActions([
      "getCustomerInfoList", // 查询用户列表信息
      "seizeCustomer", // 抢占客户成功
      "getCustomerInfo", // 清洗活动状态
    ]),
    }
    // 调用
    var param = {
        customerId: id
      };
    this.seizeCustomer(param)
    .then(rep => {

    }).catch(e => {          
      this.$toast(e || "网络出小差,请稍后重试!");
    }); 
    // -------------- 相当于 ----------------------
     this.$store.dispatch('seizeCustomer', params).then(rep => {
         
     }).catch(e => {
        this.$toast(e || '网络出小差,请稍后重试!')
     })

vuex

this.$store.commit('SET_TERMINAL_ID', id);  // 异步

components

import searchPage from "../searchPage";
import cancelCauseVue from "../../components/pages/cancelCause";

components: {
    searchPage,
    cancelCauseVue
  },
监听搜索(watch)
variable.less 文件(设置全局的变量)

// 变量文件
@border-base: #e8e8e8;
@bd-base: #f2f2f2;
// iconfont 字体
@import '../icon/iconfont.css';

@border-base: #e1e1e1; 
@col-666: #666666; 
@col-e1: #e1e1e1; 
@col-333: #333333; 
@col-999: #999999; 
@skyBlue: #11BFF4; 
@white: #ffffff; 
@col-f5: #f5f5f5; 
@col-pink: #FF7EA9; 
@col-d8: #D8D8D8;
// -------------- less 文件 -------------
@import "./variable.less";
// 设置
.col-333{ 
  color: @col-333; 
} 
// 传 关键字
search: this.condition, // 搜索 (获取搜索框的)
// ----------------------------------

// -----------------------------------                       
 watch: {
    keyword(oldVal, newVal) {
      if (newVal != oldVal) {
        let timer = setInterval(() => {
          clearInterval(timer);
          this.downLoading();
        }, 500);
      }
    }
  }
生命周期
 // 点击后拿到数据返回给下单地址
  beforeRouteLeave (to, from, next) {
    if (to.name === 'home') {
      to.query.temp = '这里是参数,选中后的地址'
    }
    console.log(to)
    console.log(from)
    next()//一定不要忘记写
  },

图层:

 
注意: 设置 层级 z-index: 999;
图片:(动态加载)需要 :src
:class="{'col-333': condition}"
-----------------------------------------------------

// 引入 图片(防止在打包的时候没有加载进来)
import noImgdata from '../assets/image/no_imgdata.png'
// 或者 定义一个属性 xxx,使用 require ,再绑定。
addCusImg:require("../../assets/image/新增潜在客户@2x.png"),

  或者:
  
// 使用
// 如果有多张图片返回选第一张(门店)
showimg(userImgString){
  if(userImgString&&userImgString.split(",").length>0){
    return userImgString = userImgString.split(",")[0];
  } else {
    return userImgString;
  }

},

转化(数字转文字)

// 请假类型转换
    changeStatus(val) {
      switch (val) {
        case "轮休":
          return "0";
          break;
        case "闭店装修":
          return "5";
          break;
        case "产假":
          return "6";
          break;
        default:
          break;
        }
    }
   使用:
  this.changeStatus(this.typeLeave),

路由跳转和传值的几种方式。


谷歌(window)跨域

右击 --> 属性(空格)--> 添加下面的
--disable-web-security --user-data-dir=C:\MyChromeDevUserData,--user-data-dir
在C盘: 创建一个文件夹 MyChromeDevUserData

防抖和节流 (https://juejin.im/post/5cce5380f265da03826129bf?utm_source=gold_browser_extension)

Debounce 防抖
 原理:当连续触发某个方法的时候,该方法就不执行。(触发结束后再执行)

$nextTick

对于 Vue 来说,从数据变化到执行 DOM 更新,这个过程是异步的,发生在下一个 tick 里。
Vue.nextTick()
    .then(function () {
    	// DOM 更新了
	})
分割(split)、拼接
subjectValue.split(/.jpgmideaMmp2016/g);
splice 删除

字体 (em)em相对于父元素,rem相对于根元素。

em 指字体高,任意浏览器的默认字体高都是16px。
所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。
换算:
	为了简化font-size的换算,需要在css中的body选择器中声明Font-size=62.5%,这就使em值变为 16px*62.5%=10px。
    这样12px=1.2em, 10px=1em。
总结:
	只需要将你的原来的px数值除以10,然后换上em作为单位就行了。
需要注意:
	1. em的值并不是固定的;
	2. em会继承父级元素的字体大小。
重写步骤:
1. body选择器中声明Font-size=62.5%;
2. 将你的原来的px数值除以10,然后换上em作为单位;
	
像素(px):用于元素的边框或定位。

em/rem:用于做响应式页面,不过我更倾向于rem,因为em不同元素的参照物不一样(都是该元素父元素),所以在计算的时候不方便,相比之下rem就只有一个参照物(html元素),这样计算起来更清晰。

分页

console.log("提交参数:。。。。", params);
      this.showLoading();
      this.$store.dispatch("getPossibleCustList", params).then(data => {
        console.log("潜在客户列表查询结果:", data);
        this.hideLoading();
        if(data.retcode == "SUCC"){
          if(data.custList.length <=0){
                 this.$toast("暂时没有数据哦!");
                   // 清空
                   this.userList = [];
              }
              // 分页 
              if (this.page.pageNum === 1) {
                  this.userList = [];
              }
              if (data.custList && data.custList.length < this.page.pageSize) {
                  this.page.isMore = false;
              } else {
                  this.page.isMore = true;
                  this.page.pageNum++;
              }
             this.userList = this.userList.concat(data.custList);
        } else {
          this.userList = [];
          this.$toast(data.errmsg || "查询不到相关信息");
        }
      }).catch(err => {
        this.Toast(err.msg || "接口出错!");
        this.hideLoading();
      });

打电话

   {{item.respondentPhone}}
手机校验
// 手机号码、电话号码校验
  checkPhone(mobile) {
                // var tel = /^0\d{2,3}-?\d{7,8}$/;
                var tel = /^([0-9]{3,4}-)?[0-9]{7,8}$/;
                // var phone = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
                var phone = /^1[3456789][0-9]{9}$/;
                if (phone.test(mobile) || tel.test(mobile)) {
                    return true;
                } else {
                    this.Toast('请输入有效的手机号码!');
                    return false;
                }
   },
去掉 input 禁止后的背景颜色
background:transparent;

scroller 组件

独立的 样式
.my-scroller{
    background-color: @white;
    position: absolute;
    top: 146px;
    right: 0;
    left: 0;
    bottom: 0;
    overflow: hidden;
 }

scroller

 // 一定要设置,否则出错
            .my-scroller {
                position: absolute;
                top: 10px;
                bottom: 0px;
                left: 0;
                right: 0;
                overflow: hidden;
            }
修改后台返回顺序
{{item.subjectValue}}
{{item.subjectValue}}
地址选择 (使用 静态.js)





使用

import selectAddress from "../../components/pages/selAddress";
 components: {
    showTackPic,  
    selectAddress,
    autoInput
  
  },


 /** 选择地区完成 调用(这里的id 会和 地址关联) */
    selFinishAddr(showData, reportData) {
      this.addr = showData;
      this.provinceId = reportData[0].regionId;
      this.cityId = reportData[1].regionId;
      this.districtId = reportData[2].regionId;
      this.townId = reportData[3].regionId;
      this.provinceName = reportData[0].regionName;
      this.cityName = reportData[1].regionName;
      this.districtName = reportData[2].regionName;
      this.townName = reportData[3].regionName;
      this.cancelAddr();
    },

 // 取消选择 地址
    cancelAddr() {
      this.isRest = true;
      this.showAddr = false;
    },

搜索vue






简书:光明程辉

你可能感兴趣的:(前端)