vue使用echarts报错Error in mounted hook: “TypeError: this.dom.getContext is not a function”
- 解决
- 一开始是this.$refs.dom获取节点的,后面使用在
<el-row>
标签上就不可以,所以如果使用this.$refs进行echarts的初始化操作会报错,就使用原生dom获取节点后初始化即可
elementUI 日期选择器在vue-admin中设置中文显示
方法
main.js文件当中
1 2 3
| import locale from 'element-ui/lib/locale/lang/zh-CN' Vue.use(ElementUI, { locale });
|
设置前
设置后
moment日期插件输出格式错误
- 之前输出
console.log(moment().format("yyyy-MM-dd"));
- 原来是字母问题,改为大写就可以了
- 之后改为
console.log(moment().format("YYYY-MM-DD"));
moment获取本周-本月
- 获取本周
moment().day(1)
即可设置为星期一moment().day(1).format('YYYY-MM-DD')
;//输出本周星期一的日期也就是2022/05/09moment().day(7)
即可设置为星期天moment().day(7).format("YYYY-MM-DD")
;//输出本周星期一的日期也就是2022/05/15
- 获取本月1日
moment().startOf('month')
即可获取本月一日moment().startOf('month').format("YYYY-MM-DD")
//输出本月1日也就是 2022-05-01
- 获取本月结尾
moment().endOf('month')
即可获取本月最后一天的日期moment().endOf('month').format("YYYY-MM-DD")
//输出本月最后一天,也就是 2022-05-31
- 获取本日
明明组件是复用的,为什么echarts图表只显示一个?
解决
- 原来初始化的时候获取dom是
document.querySelector(xxxx)
改为this.$refs.xxxx
即可
成功解决
支付的轮询
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| if(!this.timer){ this.timer = setInterval(async () => { let result = await this.$API.queryPayStatus(this.orderNo) if(result.code == 200){ clearInterval(this.timer); this.timer = null; this.payStatu = result.code; this.$msgbox.close(); this.$router.push("/paysuccess"); } }, 2000); }
|
流程图
数组去重
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script> var tempArray = [1,2,3,4,5,5,6,7]; var tempSet = new Set(tempArray); var tempAfterArray1 = [...tempSet]; var tempAfterArray2 = Array.from(tempSet); console.log(tempAfterArray1); console.log(tempAfterArray2); </script>
|
filter
和indexOf
结合,filter为真的时候才会返回,indexOf如果找到第一个会停止寻找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| var tempArray = [1, 2, 5, 5, 6, 6, 7];
var a = tempArray.filter((item, index) => { return tempArray.indexOf(item) == index; })
console.log(a);
item = 1,index=0 tempArray.indexOf(item) 返回 0 return 0 == 0 ;
item = 2,index=1 tempArray.indexOf(item) 返回 1 return 1 == 1 ;
item = 5,index=2 tempArray.indexOf(item) 返回 2 return 2 == 2 ;
item = 5,index=3 tempArray.indexOf(item) 返回 2 return 2 == 3 ;
item = 6,index=4 tempArray.indexOf(item) 返回 4 return 4 == 4 ;
item = 6,index=5 tempArray.indexOf(item) 返回 4 return 4 == 5 ;
item = 7,index=6 tempArray.indexOf(item) 返回 6 return 6 == 6 ;
|
element-ui当中<el-table></el-table>索引自定义
关键在于为type='index'
的绑定:index="自定义函数"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <template> <div> <el-table :data="objects" border> <el-table-column align="center" width="80" type="index" :index="indexMethod" label="索引"> </el-table-column> <el-table-column prop="prop" label="工作地址"> </el-table-column> </el-table> </div> </template>
<script> export default { name: "", data() { return { objects: [ { ID: "1", JobTitle: "Front Desk Coordinator", EmailAddress: "Sofie_Jennson149@deons.tech", FirstNameLastName: "Sofie Jennson", }, { ID: "2", JobTitle: "Global Logistics Supervisor", EmailAddress: "Wade_Gallacher1821@elnee.tech", FirstNameLastName: "Wade Gallacher", }, ], }; }, methods: { indexMethod(index) { index = index.toString(); while (index.length < 4) { index = "0" + index; } return index; }, }, }; </script>
<style lang="less" scoped> </style>
|
效果
el-table-column使用插槽并将数据绑定在v-model为什么可以实现双向绑定影响到原来数据
当初学的时候很懵懵懂懂,觉得既然把数据传递给了组件去显示,那应该影响不到原来的数据呢,为什么还会影响到原来数据
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <template> <div> <el-table :data="attrForm" border> <el-table-column prop="EmailAddress" label="邮箱地址"> <template slot-scope="{ row }"> <el-input v-model="row.EmailAddress"></el-input> </template> </el-table-column> </el-table> </div> </template>
<script> export default { name: "", data() { return { attrForm: [ { ID: "1", JobTitle: "Front Desk Coordinator", EmailAddress: "Sofie_Jennson149@deons.tech", FirstNameLastName: "Sofie Jennson", }, { ID: "2", JobTitle: "Global Logistics Supervisor", EmailAddress: "Wade_Gallacher1821@elnee.tech", FirstNameLastName: "Wade Gallacher", }, ], }; }, }; </script>
|
原因
因为element-ui当中,是按照列来传递数据的,也就是当element-ui
遍历attrForm
的时候,会将当前遍历项目传递给每一个<el-table-column>
,所以为什么输入框当中输入的数据会影响到data
- 首先是v-model的原因
- 其次就是传递的是引用数据类型
使用指向同一个数据
差不多这样子图过程吧
数组哪些方法的使用不会影响数组的响应式?
1 2 3 4 5 6 7
| push() pop() shift() unshift() splice() sort() reverse()
|
再加上一个整体替换也不会
比如data
当中的a
数组是响应式的,整体替换,this.a
= b;(b也为一个数组),也不会影响数组的响应式
获取输入框的焦点
1
| this.$refs.xxx.focus();获取焦点
|
el-dialog的显示隐藏的控制
<el-dialog></el-dialog>
是支持.sync的写法的,比如<el-dialog :visible.sync="xxxx"></el-dialog>
由这个xxx
来决定这个dialog
是否是显示还是隐藏
el-form-item
添加下属性label-width:"80px"
或者80px自己改为其他的即可
顺带一提
<el-input>
改为输入框设置type="textarea"
再添加下row="4"即可多行输入
可以使用混入mixin解决export default过长
混入,说简单就是将一个东西和另外一个东西混合在一起,注意是混合,不是替换!,比如我在一个文件里面有方法A,我混入在另外一个文件夹里面,那么另外一个文件夹就可以使用A了
使用:
- 引入要混入的对象
- 配置对象添加
mixins:[],
数组当中填写引入的混入对象的名称即可
例子:
com.js(可以看到,和组件传入的配置对象基本一样)
1 2 3 4 5 6 7 8 9 10 11 12
| export default { data() { return { address:"地球村" } }, methods: { sayOther(){ console.log("回收装备,没区别"); } }, }
|
Home.vue(混入使用com.js)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <template> <div></div> </template>
<script> import com from "@/other/com.js"; export default { name: "", mixins:[com], data() { return { name: "李白", }; }, mounted(){ this.show(); this.sayOther(); console.log(this.name); console.log(this.address); }, methods: { show() { console.log("大家好,我叫" + this.name); }, }, }; </script>
|
watch和$nextTick结合使用
- watch只能监视数据的变化,而因为数据变化导致的dom更新是否已经完成watch并不知道(相当于你数据一发生变化,我就执行你设置的回调函数)
- 而如果我们希望等待dom更新完成后在执行回调,我们就需要结合
$nextTick
使用 - $nextTick意思是等待下一次DOM更新后在执行回调
- 比如说轮播图,如果我们轮播图数据发生了变化,
watch
监视到了,如果我们立马执行操作使得轮播图重新绘制生成,那么肯定是不行的,因为dom都没有生成,轮播图怎么重新获取dom进行生成,所以我们就可以在里面添加$nextTick
等下次DOM更新完成后执行即可 - 顺带一提: watch支持异步请求,并且支持深度监视,computed不支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script> <div id="app"> <p ref="title">{{name}}</p> </div> <script> var vm = new Vue({ data: { name: 'tom' } }).$mount('#app'); vm.name = "汤姆"; console.log(vm.$refs.title.textContent);
vm.$nextTick(()=>{ console.log(vm.$refs.title.textContent); }) </script>
|
解构赋值 { } 和 [ ]
{ }
不多说
[ ]
按顺序解构赋值
1 2
| let[,attr] = "v-on:text".split(":"); console.log(attr);
|
可以使得切换路由的时候,路由滚动条可以滚动到我们想滚动的位置
1 2 3 4 5 6 7 8
| const router = new VueRouter({ mode: "history", routes, scrollBehavior(to, from, savedPosition){ return {x:0,y:0} } })
|
getters当中要用一个||[] ||{} 的用处
- 因为有些项目需要从后台发送请求来渲染页面,但是这些数据因为网络延迟的问题肯定不能及时到达,所以就需要在到达之前使用
[]
或者{}
(依据返回数据是数组还是对象来选择),来进行填充,不然你一个空字符串去参与遍历(比如v-for
)那肯定会报错的 - 再者,有人会说getters的事情和我组件有什么关系,一个是仓库,一个是组件,还是有关系的,(因为组件调用了
mapGetters
来获取仓库的数据),当数据不存在的时候或者遍历一个不可以遍历的数据的时候,就会报错(虽然报错后数据显示依旧正常,是因为后期数据返回,重新渲染了~)(这叫假报错) - 所以有时候为了避免假报错,就需要使用
||[] ||{}
比如这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const getters = { categoryView(state){ return state.skuDetailInfo.categoryView||{}; }, skuInfo(state){ return state.skuDetailInfo.skuInfo||{}; }, spuSaleAttrList(state){ return state.skuDetailInfo.spuSaleAttrList||[] } }
|
- 还有就是有时候我们多层嵌套读取数据,比如
a.b.c
通过a读取b,又通过b读取c,假如读取到b的时候,b是undefined
,那么在读取c就会报错,所以这个时候就可以考虑使用||[] 或者 ||{}
了
localStorage.getItem();如果获取不到指定的key,返回的是null不是返回undefined
axios的请求头(Content-Type)
1 2 3 4 5 6 7 8
| 'Content-Type: application/json '
'Content-Type: application/x-www-form-urlencoded'
'Content-Type: multipart/form-data'
|
注意:
jQuery当中的$.post
默认请求头(Content-Type
)为 application/x-www-form-urlencoded; charset=UTF-8
当不使用vuex的时候,我们可以把接口请求函数全部封装在对象当中并挂载Vue原型上
如:在main.js当中
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import * as API from "@/api.js"
new Vue({ ... beforeCreate(){ Vue.prototype.$API = API; }, ... })
|
Vue注册全局注册的二种方式
main.js文件(主入口文件)使用Vue.use方法全局注册
其实element-ui官方也是使用Vue.use()来注册全局组件的~
1 2 3 4 5 6 7 8 9 10 11 12 13
| import Vue from 'vue' import App from './App.vue'
import ElementUI from "element-ui" import "element-ui/lib/theme-chalk/index.css" Vue.use(ElementUI);
Vue.config.productionTip = false
new Vue({ render: h => h(App), }).$mount('#app')
|
一般我们用Vue.componet()
比较多,因为使用Vue.use()
注册全局组件使用起来麻烦点,element-ui看起来使用简单是因为内部封装好了
main.js文件(主入口文件)使用Vue.component方法全局注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import Vue from 'vue' import App from './App.vue'
import MyButton from '@/components/MyButton'
Vue.component('MyButton',MyButton);
new Vue({ render: h => h(App), }).$mount('#app')
|
Vue当中的watch
直接就一个监视回调函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <template> <div> <button @click="name = '我是渣渣辉'">这是按钮</button> <span>{{ name }}</span> </div> </template>
<script> export default { name: "MyButton", data() { return { name: "李白", }; }, watch: { name(newValue, oldValue) { console.log("值发生了变化"); }, }, }; </script>
<style lang="less" scoped> </style>
|
如果需要监视对象当中某一个值的变化的话,就需要用到这种形式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| data() { return { eat:{ vegetable:"西红柿", meat:"牛肉" } }; }, watch: { 'eat.meat'(newValue, oldValue) { console.log("值发生了变化"); }, },
|
书写配置项(比如是否深度监视)
如果我们想监视一个对象当中所有值的变化,包括内部对象的值的变化,我们不可以一个个去书写监听回调吧?我们可以使用配置项当中的deep
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| <template> <div> <button @click="eat.meat = '和牛'">改变肉类</button><br/> <button @click="eat.vegetable = '青菜'">改变蔬菜</button><br/> <button @click="eat.other.fruit = '苹果'">改变水果</button><br/> <span>{{ eat.meat }}</span> <br/> <span>{{ eat.vegetable }}</span><br/> <span>{{ eat.other.fruit }}</span><br/> </div> </template>
<script> export default { name: "MyButton", data() { return { eat: { vegetable: "西红柿", meat: "牛肉", other: { fruit: "草莓", }, }, }; }, watch: { eat: { deep: true, handler() { console.log("值发生了变化"); }, }, }, }; </script>
<style lang="less" scoped> </style>
|
npm run build:prod 或者 npm run build:stage
- npm run build:prod: 构建生产环境
- 打包的时候会读取
.env.development
文件的,所以不需要前缀可以编辑下这个文件
- npm run build:stage: 构建测试环境
- 打包的时候会读取
.env.production
文件的,所以不需要前缀可以编辑下这个文件
Navigation aborted from “/center“ to “/login“ via a navigation guard
解决:
vue_project\src\router\index.js 路由主入口文件当中添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location, onResolve, onReject) { if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) return originalPush.call(this, location).catch((err) => { if (VueRouter.isNavigationFailure(err)) { return err } return Promise.reject(err) }) } const originalReplace = VueRouter.prototype.replace VueRouter.prototype.replace = function replace(location, onResolve, onReject) { if (onResolve || onReject){ return originalReplace.call(this, location, onResolve, onReject) } return originalReplace.call(this, location).catch((err) => { if (VueRouter.isNavigationFailure(err)) { return err } return Promise.reject(err) }) }
|