1. computed created beforeCreate 执行顺序
首先看 Vue 初始化的源码:
vue/src/core/instance/init.js:
// 首先是合并参数
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
vm._self = vm
initLifecycle(vm) // 初始化生命周期
initEvents(vm) // 初始化事件中心
initRender(vm) // 初始化渲染
callHook(vm, 'beforeCreate') // 调用生命周期钩子函数 beforeCreate
initInjections(vm)
initState(vm) // 初始化data、props、computed、watcher 等等
initProvide(vm)
callHook(vm, 'created') // 调用生命周期钩子函数 created
Vue 中通常在created钩子函数里执行访问数据库的方法,然后返回数据给前端,前端data中定义全局变量接收数据。
一般可以在created函数中调用ajax获取页面初始化所需的数据。
created: 往模板渲染成html或者模板编译进路由前调用created。
mounted: 已完成模板已经渲染或el对应html渲染后。
我们从图中看两个节点:
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
1.1 参考
Vue进阶(三十六):vue.js中created方法的使用详解
2. img :src 绑定问题
先渲染了页面,然后执行了两次接口的方法。
解决方案:
加上 v-if="QPAY_First_Bank_Code"
如果有值, 才让它显示
<img :src="('/images/bank-logo-map/' + QPAY_First_Bank_Code + '.png')"
v-if="QPAY_First_Bank_Code" />
<!-- <img :src="('/images/bank-logo-map/' + item.bankCode + '.png')" /> -->
<!-- 对数据,进行截取 -->
<img :src="('/images/bank-logo-map/' + (item.unionpayBankCode).slice(0, (item.unionpayBankCode).length-2) + '.png')" />
Vue 利用 通道,时间格式化
// html里:
<div id="app" v-cloak>
<p>{{ timeDate | formatDate }} </p>
</div>
// index.js
let padDate = function (val) {
val = val < 10 ? '0' + val:val;
return val;
}
//
var app = new Vue({
el: '#app',
data: {
timeDate: new Date()
},
filters: {
formatDate: function (val) {
let value = new Date(val);
let year = value.getFullYear();
let month = padDate(value.getMonth()+1);
let day = padDate(value.getDate());
let hour = padDate(value.getHours());
let minutes = padDate(value.getMinutes());
let seconds = padDate(value.getSeconds());
return year + '-' + month + '-' + day +' '+hour+':'+minutes+':'+seconds;
}
}
})
3. v-if / v-else
用来切换图标:
<span class="quick-payment-sign-A"
v-if="item.cardType == 1">储蓄卡</span>
<span class="quick-payment-sign-B"
v-else>信用卡</span>
4. 可以用 v-show="" 来控制 哪个 li 显示
可以用 v-show="payWayCodeValue == 'B2C_C'" 来控制 哪个 li 显示
用 v-show="payWayCodeValue == 'B2C_C'" 控制 哪个 a 显示
三个 li,每次只显示,一个
<pax-row>
<pax-col :span="4">选择银行:</pax-col>
<pax-col :span="20">
<div class="choose-bank">
<ul>
<!-- 个人用户 - 储蓄卡 -->
<li v-for="(item, index) in bankList_B2C_C_Filter"
@click="chooseBank($event, index, item)"
:key="'B2C_C' + index"
:class="{' choose-bank-selected': chooseBankFlag == index}"
v-show="payWayCodeValue=='B2C_C'" >
<img :src="('/images/bank-logo-map/' + item.bankCode + '.png')" />
<span>{{item.bankName}}</span>
<i></i>
</li>
<!-- 个人用户 - 信用卡/储蓄卡 -->
<li v-for="(item, index) in bankList_B2C_D_Filter"
@click="chooseBank($event, index, item)"
:key="'B2C_D' + index"
:class="{'choose-bank-selected': chooseBankFlag == index}"
v-show="payWayCodeValue == 'B2C_D'" >
<span>{{item.bankName}}</span>
<i></i>
</li>
<!-- 企业用户 -->
<li v-for="(item, index) in bankList_B2B_Filter"
@click="chooseBank($event, index, item)"
:key="'B2B' + index"
:class="{' choose-bank-selected': chooseBankFlag == index}"
v-show="payWayCodeValue == 'B2B'" >
<img :src="('/images/bank-logo-map/' + item.bankCode + '.png')" />
<span>{{item.bankName}}</span>
<i></i>
</li>
</ul>
</div>
<a class="expand-choose-bank"
href="javascript:;"
@click="chooseBankExpand"
v-show="payWayCodeValue == 'B2C_C'" >
查看更多银行1
<pax-icon :type="chooseBankIcon_B2C_C" />
</a>
<a class="expand-choose-bank"
href="javascript:;"
@click="chooseBankExpand"
v-show="payWayCodeValue == 'B2C_D'" >
查看更多银行2
<pax-icon :type="chooseBankIcon_B2C_D" />
</a>
<a class="expand-choose-bank"
href="javascript:;"
@click="chooseBankExpand"
v-show="payWayCodeValue == 'B2B'" >
查看更多银行3
<pax-icon :type="chooseBankIcon_B2B" />
</a>
</pax-col>
</pax-row>
5. 通过 this.$emit 自组件 向父组件,传递值
子组件:
<!-- 添加银行卡 -->
<p class="item card-add-A"
@click="bindCard()" >
<span class="item_icon">
<img src="/images/add-bank.png" alt="">
</span>
<span class="item_name">添加银行卡</span>
<!-- 图标 -->
<i></i>
</p>
methods:{
// 绑卡
bindCard(){
// 触发父组件的v-on:bind="bindCardFunc"方法
this.$emit('bind');
}
}
父组件:
<!-- 自己封装的 actionsheet 全局插件 -->
<VActionsheet :open="openActionsheet" v-on:show="func"
v-on:bind="bindCardFunc"
:tradesBanksData="tradesBankInfoObj" >
</VActionsheet>
methods: {
//子组件, 触发的 bindCardFunc 方法
bindCardFunc (){
alert(1);
this.$router.push('/my_form/my_form')
}
}
6. eventBus
当页面之间,没有引用关系的时候,可以用 eventBus 来传值。
7. xxx
8. 一个页面自动提交表单的例子
在 views 目录下,新建 my_form/my_form.vue
在其他组件,跳转到 my_form.vue 页面:
bindCard(){
this.$router.push('/my_form/my_form')
}
在 my_form.vue 页面,通过 auth_token 去请求数据,然后拼接数据,页面自动提交表单。
my_form.vue:
<template>
<div>
<form name="autoJumpForm" method="post" :action="bindCardObj.requestFrontUrl"
v-if="bindCardObj" >
<input type="hidden" name="version" id="version" :value="bindCardObj.version" />
<input type="hidden" name="encoding" id="encoding" :value="bindCardObj.encoding" />
<input type="hidden" name="signMethod" id="signMethod" :value="bindCardObj.signMethod" />
<input type="hidden" name="txnType" id="txnType" :value="bindCardObj.txnType" />
<input type="hidden" name="txnSubType" id="txnSubType" :value="bindCardObj.txnSubType" />
<input type="hidden" name="bizType" id="bizType" :value="bindCardObj.bizType" />
<input type="hidden" name="channelType" id="channelType" :value="bindCardObj.channelType" />
<input type="hidden" name="accessType" id="accessType" :value="bindCardObj.accessType" />
<input type="hidden" name="acqInsCode" id="acqInsCode" :value="bindCardObj.acqInsCode" />
<input type="hidden" name="merCatCode" id="merCatCode" :value="bindCardObj.merCatCode" />
<input type="hidden" name="merName" id="merName" :value="bindCardObj.merName" />
</form>
</div>
</template>
<script>
//->去请求绑卡接口, 只需要auth-token
import { bindCard } from "../../api/common_pay";
export default {
name: "my_form",
data(){
return {
bindCardObj: {}
}
},
beforeCreate() {
//->去调取绑卡的接口
//->不需要拼接参数
bindCard().then(data => {
console.log(data.data)
this.bindCardObj = data.data
}, err => {
})
},
mounted(){
// 去提交form表单
this.$nextTick(() => {
setTimeout(() => {
document.autoJumpForm.submit()
}, 100)
})
}
}
</script>
9. 关于 checkbox 和 Radio
终于搞清楚了, 两个互不相干的 checkbox, 要做到互斥的功能,只能通过双向绑定 v-model 的值,去设置 checkbox,是否选中。
实际例子:
<pax-cell-group title="" class="">
<pax-cell-item type="div" href="javascript:;" @click.native="list_toggle_wechat">
<span slot="left">
<pax-checkbox v-model="checkbox_A"
shape="circle"
@click.native.stop
size="30"
:change="myFunc_A" >
<img src="/images/wechat.png" />微信支付
</pax-checkbox>
</span>
<span slot="right"></span>
</pax-cell-item>
<pax-cell-item type="div" href="javascript:;" @click.native="list_toggle_QPAY">
<span slot="left">
<pax-checkbox v-model="checkbox_B"
shape="circle"
@click.native.stop
size="30"
:change="myFunc_B" >
<img src="/images/quick-payment.png" />快捷支付
</pax-checkbox>
</span>
<span slot="right"></span>
</pax-cell-item>
</pax-cell-group>
<script>
export default {
data(){
return {
checkbox_A: true,
checkbox_B: false
}
},
methods: {
list_toggle_wechat (e) {
// 点击 list
},
list_toggle_QPAY (e) {
// 点击 list
},
myFunc_A (e) {
var that = this
if (that.checkbox_A === true) {
// 表示已选择 微信支付
//-> 去取消 快捷支付 的选中
that.checkbox_A = false
that.checkbox_B = true
} else {
that.checkbox_A = true
that.checkbox_B = false
}
},
myFunc_B (e) {
var that = this
if (that.checkbox_B === true) {
// 表示已选择 快捷支付
//-> 去取消 微信支付 的选中
that.checkbox_A = true
that.checkbox_B = false
} else {
that.checkbox_A = false
that.checkbox_B = true
}
}
}
}
</script>
在 点击 checkbox 或者 Radio 的时候,会触发 list,
所以, 会弹出两次 12,
所以, 要阻止事件冒泡, 阻止事件向上传播
在 checkbox 或者 Radio 上加上 @click.native.stop 就可以了
10. js 去触发表单提交
js 去触发 checkbox 点击选中
<VCheckbox id="QPAY" v-model="checkVal" @click.native.stop></VChexkbox>
document.getElementById('QPAY').click()
js 去触发表单提交
<form name="autoJumpForm" method="post"></form>
document.autoJumpForm.submit()