演示地址javascript
表單彈框html
實際的項目中會存在不少的表單彈框,而且有許可能是能夠複用的,咱們能夠簡單的封裝成業務組件。技巧就是利用.sync特性
<Dialog :visible.sync="dialogFormVisible"></Dialog> <el-dialog @close="close" title="收貨地址" :visible.sync="visible"> <el-form :model="form"> <el-form-item label="活動名稱" :label-width="formLabelWidth"> <el-input v-model="form.name" auto-complete="off"></el-input> </el-form-item> <el-form-item label="活動區域" :label-width="formLabelWidth"> <el-select v-model="form.region" placeholder="請選擇活動區域"> <el-option label="區域一" value="shanghai"></el-option> <el-option label="區域二" value="beijing"></el-option> </el-select> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="close">取 消</el-button> <el-button type="primary" @click="ok">確 定</el-button> </div> </el-dialog>
export default { props: { visible: false }, data() { return { form: { name: "", region: "" }, formLabelWidth: "120px" }; }, methods: { close() { this.$emit("update:visible", false); }, ok() { this.$emit("update:visible", false); } } };
表單嵌入java
有一些場景,除了表單輸入不一樣,其餘的一些邏輯都是同樣的,這時候就能夠把表單拉出來,作一個判斷,這樣就能公用一個頁面
<el-form :model="form"> <Forms :data.sync="form"></Forms> <el-button @click="close">取 消</el-button> <el-button type="primary" @click="ok">確 定</el-button> </el-form> //Forms <div> <el-form-item label="活動名稱" :label-width="formLabelWidth"> <el-input v-numberInt:5="data.name" v-model="data.name" auto-complete="off"></el-input> </el-form-item> <el-form-item label="活動區域" :label-width="formLabelWidth"> <el-select v-model="data.region" placeholder="請選擇活動區域"> <el-option label="區域一" value="shanghai"></el-option> <el-option label="區域二" value="beijing"></el-option> </el-select> </el-form-item> </div>
export default { props: { data: Object }, data() { return { formLabelWidth: "120px" }; } };
Directive 指令node
有一天,我正在開開心心的寫代碼的時候,產品忽然跟我說,表單僅僅作校驗是不夠的,咱們還要限制用戶輸入,價格只能輸入數字,數量只能輸入整數,我聽到後整我的就很高興說: 我(艹)看(泥)看(馬)(當用戶傻呀,外星人呀,價格是ABC)
<el-input v-numberInt:5="data.name" v-model="data.name" ></el-input>
//JS export const numberInt = { update: function (el, binding, vnode) { let val = binding.value ? binding.value.toString() : '' let len = binding.arg if (val === '') return let reg = new RegExp('^[0-9]{0,' + len + '}$') if (!reg.test(val)) { // 由於model的緣由必須nextTick後去更改才行 Vue.nextTick(() => { vnode.data.model.callback(binding.oldValue) }) } } }
<div class="grid-box"> <span class="vLine" :style="{left: n * 20 + 'px'}" v-for="n in nCol" :key="'v' + n"></span> <span class="hLine" :style="{top: n * 20 + 'px'}" v-for="n in nRow" :key="'h' + n"></span> </div>
export default { name: "Lines", data() { return { nRow: 0, nCol: 0 }; }, created() {}, mounted() { this.nRow = Math.ceil(this.$el.offsetHeight / 20); this.nCol = Math.ceil(this.$el.offsetWidth / 20); }, methods: {} };
<CrystalNum :num="num"></CrystalNum> <div class="crystalnum" > <span v-for="(item, index) in aCount" :key="index" :class="!show && item != oldCount[index]?'animation-flip iconfont icon-'+ item:'iconfont icon-'+ item"></span> </div>
export default { name: "CrystalNum", props: { num: { type: [String, Number], default: "0" } }, data() { return { show: true, oldCount: ["0"], aCount: ["0"] }; }, computed: {}, mounted() {}, watch: { num(cur, old) { this.show = false; this.oldCount = old.toString().split(""); let num = cur; if (typeof num === "number") { num = "" + num; } if (num === "") { this.aCount = ["0"]; } else { let aCount = num.split(""); this.aCount = aCount; } setTimeout(() => { this.show = true; }, 1000); } } };
有好幾個月沒碰原來的項目,回頭看了下,有不少不足的地方,有一些碰到的問題時間過久,沒記錄也沒什麼印象了,回頭有實踐再更新吧,也歡迎拍磚 this
演示地址spa