vue使用echarts报错Error in mounted hook: “TypeError: this.dom.getContext is not a function”
- 解决
- 一开始是this. r e f s . d o m 获 取 节 点 的 , 后 面 使 用 在 ‘ < e l − r o w > ‘ 标 签 上 就 不 可 以 , 所 以 如 果 使 用 t h i s . refs.dom获取节点的,后面使用在`<el-row>`标签上就不可以,所以如果使用this. refs.dom获取节点的,后面使用在‘<el−row>‘标签上就不可以,所以如果使用this.refs进行echarts的初始化操作会报错,就使用原生dom获取节点后初始化即可
elementUI 日期选择器在vue-admin中设置中文显示
-
方法
-
main.js文件当中
复制// import locale from 'element-ui/lib/locale/lang/en' // lang i18n 注释掉 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
- 获取本日
moment().startOf('day')
明明组件是复用的,为什么echarts图表只显示一个?
- 如图,只有左边有,为什么会这样子?
-
解决
- 原来初始化的时候获取dom是
document.querySelector(xxxx)
改为this.$refs.xxxx
即可
-
成功解决
- 原来初始化的时候获取dom是
支付的轮询
代码
//开始轮询 if(!this.timer){ this.timer = setInterval(async () => { let result = await this.$API.queryPayStatus(this.orderNo) if(result.code == 200){ //说明支付成功了 //清除定时器 clearInterval(this.timer); //置空timer this.timer = null; //更改支付状态记录表 this.payStatu = result.code; //关闭信息弹窗 this.$msgbox.close(); //跳转路由 this.$router.push("/paysuccess"); } }, 2000); }
复制
流程图
数组去重
- set构造函数去重
<script> var tempArray = [1,2,3,4,5,5,6,7]; //转化为set var tempSet = new Set(tempArray); //set转换回来数组 - 方法1 var tempAfterArray1 = [...tempSet]; ///set转换回来数组 - 方法2 var tempAfterArray2 = Array.from(tempSet); //[1, 2, 3, 4, 5, 6, 7] console.log(tempAfterArray1); //[1, 2, 3, 4, 5, 6, 7] console.log(tempAfterArray2); </script>
复制
- 普通方法(这里就说一个~)
filter
和indexOf
结合,filter为真的时候才会返回,indexOf如果找到第一个会停止寻找
var tempArray = [1, 2, 5, 5, 6, 6, 7]; //item为当前遍历的项 //index为当前遍历项的索引 var a = tempArray.filter((item, index) => { return tempArray.indexOf(item) == index; }) //[1, 2, 5, 6, 7] console.log(a); //遍历过程 item = 1,index=0 tempArray.indexOf(item) 返回 0 return 0 == 0 ;//为true,存储'1' item = 2,index=1 tempArray.indexOf(item) 返回 1 return 1 == 1 ;//为true,存储'2' item = 5,index=2 tempArray.indexOf(item) 返回 2 return 2 == 2 ;//为true,存储'5' item = 5,index=3 tempArray.indexOf(item) 返回 2 return 2 == 3 ;//为false,不存储 item = 6,index=4 tempArray.indexOf(item) 返回 4 return 4 == 4 ;//为true,存储'6' item = 6,index=5 tempArray.indexOf(item) 返回 4 return 4 == 5 ;//为false,不存储 item = 7,index=6 tempArray.indexOf(item) 返回 6 return 6 == 6 ;//为true,存储'7'
复制
element-ui当中<el-table></el-table>索引自定义
关键在于为type='index'
的绑定:index="自定义函数"
<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: { //自定义索引,转化为0001,0002,0003的这种 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为什么可以实现双向绑定影响到原来数据
当初学的时候很懵懵懂懂,觉得既然把数据传递给了组件去显示,那应该影响不到原来的数据呢,为什么还会影响到原来数据
例子
<template> <div> <el-table :data="attrForm" border> <el-table-column prop="EmailAddress" label="邮箱地址"> <template slot-scope="{ row }"> <!-- 为什么可以实现用户输入后data当中的数据也改变? --> <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的原因
- 其次就是传递的是引用数据类型使用指向同一个数据
差不多这样子图过程吧
数组哪些方法的使用不会影响数组的响应式?
push() pop() shift() unshift() splice() sort() reverse()
复制
再加上一个整体替换也不会
比如data
当中的a
数组是响应式的,整体替换,this.a
= b;(b也为一个数组),也不会影响数组的响应式
获取输入框的焦点
this.$refs.xxx.focus();获取焦点
复制
el-dialog的显示隐藏的控制
<el-dialog></el-dialog>
是支持.sync的写法的,比如<el-dialog :visible.sync="xxxx"></el-dialog>
由这个xxx
来决定这个dialog
是否是显示还是隐藏
el-form当中的el-form-item占据一行问题
el-form-item
添加下属性label-width:"80px"
或者80px自己改为其他的即可
顺带一提
<el-input>
改为输入框设置type="textarea"
再添加下row="4"即可多行输入
可以使用混入mixin解决export default过长
混入,说简单就是将一个东西和另外一个东西混合在一起,注意是混合,不是替换!,比如我在一个文件里面有方法A,我混入在另外一个文件夹里面,那么另外一个文件夹就可以使用A了
使用:
- 引入要混入的对象
- 配置对象添加
mixins:[],
数组当中填写引入的混入对象的名称即可
例子:
com.js(可以看到,和组件传入的配置对象基本一样)
export default { data() { return { address:"地球村" } }, methods: { sayOther(){ console.log("回收装备,没区别"); } }, }
复制
Home.vue(混入使用com.js)
<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不支持
<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 = "汤姆"; //设置新名字后立马输出里面的文本,发现输出的依旧是'tom',而不是'汤姆' //因为dom还没有更新完成 console.log(vm.$refs.title.textContent); // tom //下一次dom更新完成后输出,发送输出的是'汤姆'了 vm.$nextTick(()=>{ console.log(vm.$refs.title.textContent); // tom }) </script>
复制
解构赋值 { } 和 [ ]
-
{ }
不多说 -
[ ]
按顺序解构赋值
复制let[,attr] = "v-on:text".split(":"); console.log(attr);//输出text
vue-router配置对象当中的scrollBehavior
可以使得切换路由的时候,路由滚动条可以滚动到我们想滚动的位置
const router = new VueRouter({ mode: "history", routes, //每次路由切换的时候,就将滚动条滚动到最顶端 scrollBehavior(to, from, savedPosition){ return {x:0,y:0} } })
复制
getters当中要用一个||[] ||{} 的用处
- 因为有些项目需要从后台发送请求来渲染页面,但是这些数据因为网络延迟的问题肯定不能及时到达,所以就需要在到达之前使用
[]
或者{}
(依据返回数据是数组还是对象来选择),来进行填充,不然你一个空字符串去参与遍历(比如v-for
)那肯定会报错的 - 再者,有人会说getters的事情和我组件有什么关系,一个是仓库,一个是组件,还是有关系的,(因为组件调用了
mapGetters
来获取仓库的数据),当数据不存在的时候或者遍历一个不可以遍历的数据的时候,就会报错(虽然报错后数据显示依旧正常,是因为后期数据返回,重新渲染了~)(这叫假报错) - 所以有时候为了避免假报错,就需要使用
||[] ||{}
比如这个
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 默认的格式请求体中的数据会以json字符串的形式发送到后端(默认) 'Content-Type: application/json ' // 2 请求体中的数据会以普通表单形式(键值对)发送到后端 'Content-Type: application/x-www-form-urlencoded' // 3 它会将请求体的数据处理为一条消息,以标签为单元,用分隔符分开。既可以上传键值对,也可以上传文件 'Content-Type: multipart/form-data'
复制
注意:
jQuery当中的$.post
默认请求头(Content-Type
)为 application/x-www-form-urlencoded; charset=UTF-8
当不使用vuex的时候,我们可以把接口请求函数全部封装在对象当中并挂载Vue原型上
如:在main.js当中
// 也就是先导入封装所有ajax请求的api.js import * as API from "@/api.js" // 挂载到vue原型上,和全局事件总线挂载一样 // 都是在vue生命周期的beforeCreate挂载 new Vue({ ... beforeCreate(){ //全局事件总线 //Vue.prototype.$bus = this; //ajax请求 Vue.prototype.$API = API; }, ... })
复制
Vue注册全局注册的二种方式
Vue.use()
main.js文件(主入口文件)使用Vue.use方法全局注册
其实element-ui官方也是使用Vue.use()来注册全局组件的~
import Vue from 'vue' import App from './App.vue' //引入element-ui组件 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.component()
一般我们用Vue.componet()
比较多,因为使用Vue.use()
注册全局组件使用起来麻烦点,element-ui看起来使用简单是因为内部封装好了
- Vue.componet(参数1,参数2)
- 参数1:注册的组件名
- 参数2:注册的组件
main.js文件(主入口文件)使用Vue.component方法全局注册
import Vue from 'vue' import App from './App.vue' //引入自定义组件 import MyButton from '@/components/MyButton' //全局组成element-ui组件 //参数1: 注册的组件名字为 'MyButton' //参数2: 注册的组件为 MyButton Vue.component('MyButton',MyButton); //或者如果组件配置了name属性,可以直接使用组件的name当中的值 //Vue.component(MyButton.name,MyButton); new Vue({ render: h => h(App), }).$mount('#app')
复制
Vue当中的watch
直接就一个监视回调函数
<template> <div> <button @click="name = '我是渣渣辉'">这是按钮</button> <span>{{ name }}</span> </div> </template> <script> export default { name: "MyButton", data() { return { name: "李白", }; }, watch: { // 监视name值的变化 name(newValue, oldValue) { console.log("值发生了变化"); }, //代码等同于 // name: { // handler(newValue, oldValue) { // console.log("值发生了变化"); // }, // }, }, }; </script> <style lang="less" scoped> </style>
复制
如果需要监视对象当中某一个值的变化的话,就需要用到这种形式
data() { return { eat:{ vegetable:"西红柿", meat:"牛肉" } }; }, watch: { // 监视eat对象当中meat值的变化 'eat.meat'(newValue, oldValue) { console.log("值发生了变化"); }, },
复制
书写配置项(比如是否深度监视)
如果我们想监视一个对象当中所有值的变化,包括内部对象的值的变化,我们不可以一个个去书写监听回调吧?我们可以使用配置项当中的deep
<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当中值的变化,嵌套多少层都会监听到 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
文件的,所以不需要前缀可以编辑下这个文件
- 打包的时候会读取