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
文件的,所以不需要前缀可以编辑下这个文件
- 打包的时候会读取