此次項目使用vue3.0來寫,寫的過程當中忽然發現差異挺大的,感受不會寫vue了,因此總結總結。。。html
This is an 官網地址:vue
npm i @vue/cli -gnode
import { Watch, Component, Vue, Emit, Prop } from "vue-class-decorator"; // 沒有組件 @component // 有組件 // import children from "./components/children.vue"; // @component({ components:{children} }) export default class MyChildren extends Vue{ username = ""; // 名字 //userId 父子之間傳值,必傳默認是null @Prop({ type: String, required: true, default: null}) userId: string; @Emit("changeChildren") changeChildren(){} created(){} mounted(){} // 方法 cancel() { // 調用自定義函數 this.changeChildren() } }
import { Component, Emit, Inject, Model, Prop, Provide, Vue, Watch } from "vue-property-decorator" const s = Symbol('baz') @Component export class MyComponent extends Vue { @Emit() addToCount(n: number){ this.count += n} @Emit('reset') resetCount(){ this.count = 0 } @Inject() foo: string @Inject('bar') bar: string @Inject(s) baz: string @Model('change') checked: boolean @Prop() propA: number @Prop({ default: 'default value'}) propB: string @Prop([String, Boolean]) propC: string | boolean @Provide() foo = 'foo' @Provide('bar') baz = 'bar' @Watch('child') onChildChanged(val: string, oldVal: string) { } @Watch('person', { immediate: true, deep: true}) onPersonChanged(val: Person, oldVal: Person){} }
const s = Symbol("baz"); export const myComponent = Vue.extend({ name: "MyComponent", inject: { foo: "foo", bar: "bar", [s]: s }, model: { prop: "checked", event: "change" }, props: { checked: Boolean, propA: Number, propB: { type: String, default: "default value" }, propC: [String, Boolean] }, data() { return { foo: "foo", baz: "bar" }; }, provide() { return { foo: this.foo, bar: this.baz }; }, methods: { addToCount(n) { this.count += n; this.$emit("add-to-count", n); }, resetCount() { this.count = 0; this.$emit("reset"); }, onChildChanged(val, oldVal) {}, onPersonChanged(val, oldVal) {} }, watch: { child: { handler: "onChildChanged", immediate: false, deep: false }, person: { handler: "onPersonChanged", immediate: true, deep: true } } });
// 父級組件提供'foo' var Provider = { provide: { foo: 'bar' } } // 子件注入'foo' var Child = { inject: ['foo'], created() { console.log(this.f00) // bar } }
vue-property-decorator提供OO的風格Vue Component方便類型聲明git
vue-class-component 以class的模式寫vue組件github
vue class component 是vue官方出的 vue property decorator 是社區出的 其中vue class component 提供了vue component等等 vue property decorator深度依賴了vue class component擴展出了不少操做符@Prop @Emit @Inject等等 能夠說是vue class component的一個超集 正常開發的時候 你只須要使用vue property decorator 中提供的操做符便可 再也不從vue class component引入vue
新增和修改都是用同一個頁面,但願點擊各自的按鈕跳轉到頁面時調用各自的接口vue-cli
效果圖
typescript
子組件npm
<template> <!-- 新增/修改 --> <div class="role-change table-mask"> <div class="role-body"> <div class="role-main"> <span class="svg-container table-close" @click="cancel" > <svg-icon icon-class="close" /> </span> <div class="main-box"> <div class="main-item"> <p><span class="m-start">*</span>角色編碼:</p> <el-input v-model.trim="Code" /> </div> <div class="main-item"> <p><span class="m-start">*</span>角色名稱:</p> <el-input v-model.trim="Name" /> </div> </div> <div class="box-btn-bg add-bg tac"> <el-button class="f18 box-btn" @click="cancel" >取消</el-button> <el-button class="f18 box-btn" @click="addSubmit" >保存</el-button> </div> </div> </div> </div> </template> <script lang="ts"> import { Watch, Component, Vue, Emit, Prop } from "vue-class-decorator"; import { addRole, getRoleDetails, getUpdateRole } from "@/api/System/role"; @Component export default class AddRole extends Vue { Code = ""; // 角色編碼 Name = ""; // 角色名稱 @Emit("addRole") addRole(flag) {} @Prop({ type: String, default: null }) addId: string; cancel() { this.addRole(false); } addSubmit() { if (this.Code === "") { this.$message({ message: "請輸入角色編碼", type: "warning" }); } else if (this.Name === "") { this.$message({ message: "請輸入角色名稱", type: "warning" }); } else { if (this.addId) { // 修改接口 // 調用自定義方法 this.addRole(true); } else { // 新增接口 this.addRole(true); } } } } </script>
父組件element-ui
<!-- 新增/修改 --> <add-role v-if="roleShow" :addId="addId" @addRole="addRole" ></add-role> <script lang="ts"> import AddRole from "./components/AddRole.vue"; @Component({ components: { AddRole } }) export default class RoleList extends Vue { roleShow = false; // 默認彈框不顯示 addId = null; // 傳給子組件的id // 新增/修改的自定義方法 addRole(flag) { if (flag) { } this.addId = null; this.roleShow = false; } // 點擊新增按鈕 add(){ this.roleShow = true; } //點擊修改按鈕 edit(){ this.addId = 'newId'; this.roleShow = true; } } </script>
父子之間傳值,點擊修改的時候傳newId,新增的時候不傳默認是null,這樣就能夠在子組件裏區分是新增頁面仍是修改頁面後端
element type="selection" 我但願當我點擊勾選框後第二次點擊是選中的狀態;
我只是爲了實現內容,實際用到的要走接口
<template> <div class="table-mask"> <div class="table-main"> <el-table ref="multipleTable" :data="tableData" style="width: 100%" border row-key="id" @selection-change="handleSelectionChange" @row-click="clickRow" > <el-table-column type="selection" width="50" :reserve-selection="true" align="center" > </el-table-column> <el-table-column label="日期" width="100" align="center" > <template slot-scope="scope">{{ scope.row.date }}</template> </el-table-column> <el-table-column prop="name" label="姓名" width="90" align="center" > </el-table-column> <el-table-column prop="address" align="center" label="地址" > </el-table-column> </el-table> <div> <el-button type="info" @click.stop="cancel" >取消</el-button> <el-button type="primary" @click.stop="submit" >保存</el-button> </div> </div> </div> </template>
.table-mask { position: fixed; top: 0; left: 0; bottom: 0px; right: 0px; z-index: 9; overflow-x: hidden; overflow-y: scroll; background: rgba(0, 0, 0, 0.5); .table-main { position: absolute; left: 50%; top: 50%; margin-top: -200px; margin-left: -280px; width: 560px; padding: 20px; box-sizing: border-box; background: #fff; } }
import { Watch, Component, Vue, Emit, Prop } from "vue-class-decorator"; @Component export default class ChangeTable extends Vue { $refs: { multipleTable: any; }; tableData = [ { id: 1, date: "2016-05-03", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" }, { id: 2, date: "2016-05-02", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" }, { id: 3, date: "2016-05-04", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" }, { id: 4, date: "2016-05-01", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" }, { id: 5, date: "2016-05-08", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" }, { id: 6, date: "2016-05-06", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" }, { id: 7, date: "2016-05-07", name: "王小虎", address: "上海市普陀區金沙江路 1518 弄" } ]; multipleSelection = []; @Emit("ChangeClick") ChangeClick(flag) {} @Prop({ type: Array, required: true }) hasArray: any[]; created() { this.InitData(); } // 初始化 InitData() { if (this.hasArray) { const indexList = []; // 存儲交集的index,用來勾選狀態 this.hasArray.forEach(table => { this.tableData.forEach((item, index) => { if (table.id === item.id) { indexList.push(index); } }); }); this.$nextTick(() => { indexList.forEach(e => { this.$refs.multipleTable.toggleRowSelection(this.tableData[e], true); }); }); } } // 獲取選中的值 handleSelectionChange(val) { this.multipleSelection = val; } // 單擊某一行數據時選中對應的複選框 clickRow(row) { this.$refs.multipleTable.toggleRowSelection(row); } cancel() { this.ChangeClick(false); } submit() { this.ChangeClick({ flag: true, checked: this.multipleSelection }); } }
<el-button @click="handleTable" type="primary" >點擊彈出表格</el-button> <my-table v-if="isTableShow" :hasArray="hasArray" @ChangeClick="ChangeClick" ></my-table>
import myTable from "./components/table.vue"; @Component({ components: { myTable } }) export default class ChangePassword extends Vue { isTableShow = false; hasArray = []; handleTable() { this.isTableShow = true; } ChangeClick(flag) { if (flag) { this.hasArray = flag.checked; } this.isTableShow = false; } }
// 單擊某一行數據時選中對應的複選框 clickRow(row) { this.$refs.multipleTable.toggleRowSelection(row); }
<el-tree ref="tree" :data="dataList" :props="defaultProps" node-key="Code" :default-checked-keys="defaultId" show-checkbox @check-change="getChecked" > </el-tree> <!-- default-checked-keys 默認勾選的節點的 key 的數組 -->
方法
getChecked(){ this.$refs.tree.getCheckedNodes(); }
僅對 type=selection 的列有效,類型爲 Boolean,爲 true 則會在數據更新以後保留以前選中的數據(需指定 row-key)(默認false)
行數據的 Key,用來優化 Table 的渲染;在使用 reserve-selection 功能與顯示樹形數據時,該屬性是必填的。類型爲 String 時,支持多層訪問:user.info.id,但不支持 user.info[0].id,此種狀況請使用 Function。
// 提取導出文件的文件擴展名(類型) const [, extName] = /filename=".*(\..*)";/.exec( res.headers["content-disposition"] ); // 構造下載文件名的名字 const fileName = new Date().getTime().toString() + (extName || ""); // #region 進行下載 const link = document.createElement("a"); link.href = window.URL.createObjectURL(res.data); link.download = fileName; // 此寫法兼容可火狐瀏覽器 document.body.appendChild(link); const evt = document.createEvent("MouseEvents"); evt.initEvent("click", false, false); link.dispatchEvent(evt); document.body.removeChild(link); // #endregion
const list1 = [ { id: 1, name: "張三" }, { id: 2, name: "李四" } ]; const list2 = [ { id: 1, name: "張三" }, { id: 3, name: "王麻子" } ]; const oldArray = [...list1, ...list2]; console.log(oldArray); const newArray = []; for (let i = 0; i < oldArray.length; i++) { let flag = true; for (let j = 0; j < newArray.length; j++) { if (oldArray[i].id === newArray[j].id) { flag = false; } } if (flag) { newArray.push(oldArray[i]); } } console.log(newArray);