VUE2.0 tips整理
/*
相关技术
1.框架:element
2.echarts:可视化图表,[官网](https://echarts.apache.org/zh/index.html)
*/
- 引入静态图片资源到表格中
//(1)页面中引入图片
import ims from "@/assets/images/layer_logo2.png"
TableData: [
{
n1: "海宁奕瑞",//所属集团/园区
n2:
//logo
"https://tenfei03.cfp.cn/creative/vcg/800/new/VCG41560336195.jpg",
}, {
n1: "中创新航科技股份有限公司",
n2: ims
}
],
//(2)template中使用
<el-table-column label="集团/园区logo" prop="n2">
<template slot-scope="scope">
{{ scope.row.n2 }}
<img style="width:100px;height: 50px;" :src="scope.row.n2" />
</template>
</el-table-column>
- 修改element中自带的样式
/* >>>深度修改样式,只能用在原生css语法中,不能在css预处理器如less\scss等直接使用,但可用/deep/ ..el-tabs__nav-wrap::after的方式修改 */
.app-container>>>.el-tabs__nav-wrap::after {
background-color: transparent !important;
}
- 计算属性生成可视化图表的series配置项
computed: {
getNewSeries() {
return this.legendData.map((item, index) => {
return {
name: item,
type: 'line',
stack: 'total',
smooth: false,
symbol: "none",
data: this.seriesData[index]
}
})
}
},
- element树级菜单鼠标移动上去出现对应增删改图标
//1.Templete中
<el-tree :data="data" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false">
<span class="custom-tree-node" slot-scope="{ node, data }" @mouseover="treeNodeMouseover(data)"
@mouseleave="treeNodeMouseout(data)">
<span>{{ node.label }}</span>
<span v-show="data.dropdownShow">
<el-button type="text" size="mini" @click="() => append(node, data)">
<i class="el-icon-plus"></i>
</el-button>
<el-button type="text" size="mini" @click="() => editNode(node, data)">
<i class="el-icon-edit"></i>
</el-button>
<el-button type="text" size="mini" @click="() => remove(node, data)">
<i class="el-icon-delete"></i>
</el-button>
</span>
</span>
</el-tree>
//2.data中
data: [{
id: 1,
label: '一级 1',
dropdownShow: false,
children: [{
id: 4,
label: '二级 1-1',
dropdownShow: false,
children: [{
id: 9,
label: '三级 1-1-1',
dropdownShow: false,
}, {
id: 10,
label: '三级 1-1-2',
dropdownShow: false,
}]
}]
}, {
id: 2,
label: '一级 2',
dropdownShow: false,
children: [{
id: 5,
label: '二级 2-1',
dropdownShow: false,
}, {
id: 6,
label: '二级 2-2',
dropdownShow: false,
}]
}, {
id: 3,
label: '一级 3',
dropdownShow: false,
children: [{
id: 7,
label: '二级 3-1',
dropdownShow: false,
}, {
id: 8,
label: '二级 3-2',
dropdownShow: false,
}]
}],
//3.methods中
//鼠标移入树节点
treeNodeMouseover(data) {
this.$set(data, 'dropdownShow', true);
},
// 鼠标移出树节点
treeNodeMouseout(data) {
this.$set(data, 'dropdownShow', false);
},
// 增加
append(node, data) {
const newChild = { data: this.id++, label: 'testtest', children: [] };
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild);
},
// 编辑-树
editNode(node, data) {
this.editFormVisible = true, //编辑弹框
this.editForm = Object.assign({}, data);
},
// 删除
remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
children.splice(index, 1);
},
- Watch监听父组件传递过来的数据
props: {
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
immediate:true,
handler(val) {
this.setOptions(val)
}
},
},
- vue3-seamless-scroll无缝滚动,
引于【Cheng Lucky】
- 批量删除/单个删除,可判断是否有id进行不同操作
// 批量删除、删除
handleDelete(row) {
let that = this;
this.$modal.confirm('是否删除数据').then(function () {
if (row.id == undefined) {//批量删除
that.delData(that.delList);
} else {//单个删除
that.delData([{ id: row.id }]);
}
}).then(() => {
this.$modal.msgSuccess("删除成功")
}).catch(() => { });
},
- element表格分页(首次获取全部数据)
(1)template
<el-table v-loading="loading2" row-key="id"
:data="totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<el-table-column label="所属集团/园区" prop="groupName" min-width="110"></el-table-column>
<el-table-column label="集团/园区logo" prop="logo" min-width="110">
<template slot-scope="scope">
<el-image style="height: 40px;" :src="scope.row.logo"></el-image>
</template>
</el-table-column>
<el-table-column label="所属公司" prop="companyName"></el-table-column>
<el-table-column label="所属厂区" prop="plantName"></el-table-column>
<el-table-column label="所属建筑" prop="buildingName"></el-table-column>
</el-table>
<el-pagination align="right" @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="currentPage" :page-size="pageSize" layout="total,prev,pager,next,sizes,jumper"
:total="total">
</el-pagination>
(2) Data中数据:
//表格数据
TableData: [],
// 返回的所有数据
totalData: [],
currentPage: 1,//当前页
total: 0,//总条数
pageSize: 10,//每页数据条数
(4)methods:
// 分页-每页条数改变时触发
handleSizeChange(val) {
this.pageSize = val;
},
// 当前页面改变时触发,跳转到其他页
handleCurrentChange(val) {
this.currentPage = val;
},
- vue设置当前实时时间到页面上
methods: {
// 给时间拼接上0
NewTimeData(timeitem) {
return timeitem < 10 ? "0" + timeitem : timeitem
},
// 获取当前时间
getTopData() {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
let hours = date.getHours();
let minutes = date.getMinutes();
let seconds = date.getSeconds();
console.log(year, month, day, hours, minutes, seconds, 666)
// 拼接
this.nowTime = year + "." + this.NewTimeData(month) + "." + this.NewTimeData(day) + " / " + this.NewTimeData(hours) + ":" + this.NewTimeData(minutes) + ":" + this.NewTimeData(seconds) //nowTime 为最终要展示的结果
}
},
created() {
this.getTopData();
},
mounted() {//页面初始化完成后再对dom节点进行相关操作
// 时间转换
this.timer = setInterval(() => {
this.getTopData();
}, 1000);
},
beforeDestroy() {
window.clearInterval(this.timer)//停止执行定时器
}
- 正则限制element输入框只能输入数字,且输入文本最长为3
(1)只能输入数字,且输入文本最长为3
<el-input v-model='width' oninput="value=value.replace(/[^\d]/g,'')" maxLength='3' />
(2)输入框只能输入数字和小数点
<el-input v-model="dialogForm.copNum" maxlength="30"
oninput="value=value.replace(/[^0-9.]/g,'')"></el-input>
oninput =“value=value.replace(/[^\d]/g,’’)” //只能输入数字
oninput =“value=value.replace(/[^0-9.]/g,’’)” //只能输入数字和小数
或者:
设置input的type="number"
- element表格中渲染图片
<el-table-column label="集团/园区logo" prop="logo">
<template slot-scope="scope">
<el-image style="height: 40px;" :src="scope.row.logo"></el-image>
</template>
</el-table-column>
- 跑马灯组件demo
1.创建组件
<template>
<!-- 跑马灯消息滚动组件 -->
<div class="marquee-wrap" ref="marquee-wrap">
<div class="scroll" ref="scroll">
<p class="marquee">{{ text }}</p>
<p class="copy" ref="copy"></p>
</div>
<p class="getWidth" ref="getWidth">{{ text }}</p>
</div>
</template>
<script>
export default {
name: 'marquee',
props: ['val'],
data() {
return {
timer: null,
text: ''
}
},
created() {
let timer = setTimeout(() => {
this.move()
clearTimeout(timer)
}, 1000)
},
mounted() {
for (let item of this.val) {
this.text += item
}
},
methods: {
move() {
let maxWidth = this.$refs['marquee-wrap'].clientWidth
let width = this.$refs['getWidth'].scrollWidth
if (width <= maxWidth) return
let scroll = this.$refs['scroll']
let copy = this.$refs['copy']
copy.innerText = this.text
let distance = 0
this.timer = setInterval(() => {
distance -= 1
if (-distance >= width) {
distance = 16
}
scroll.style.transform = 'translateX(' + distance + 'px)'
}, 20)
}
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>
<style scoped>
.marquee-wrap {
width: 100%;
overflow: hidden;
position: relative;
}
.marquee {
margin-right: 0.16rem;
}
p {
word-break: keep-all;
white-space: nowrap;
font-size: 0.28rem;
}
.scroll {
display: flex;
}
.getWidth {
word-break: keep-all;
white-space: nowrap;
position: absolute;
opacity: 0;
top: 0;
}
</style>
2.页面中引入,注册并使用组件
引入:
// 引入跑马灯组件
import marquee from "@/components/marquee/marquee.vue";
export default {
components: {
// 注册跑马灯组件
marquee,
},
}
使用:
<Marquee class="realData">
<ul class="fa-scroll-cont">
<li v-for="item in realData" :key="item.name">
<span class="roll-text">{{ item.city }}</span>
</li>
</ul>
</Marquee>
- echarts设置配置项
(1)设置x坐标换行并设置行高
axisLabel: {
color: "#8F9296",
formatter(val) {
return '{a|' + `${val.slice(0, 2)}\n${val.slice(2)}` + '}'
},
rich: {
a: {
height: 15, // 设置字体行高
}
}
},
(2)解决echarts数据重绘的时候,数据源已变但legend并没有改变
this.chart.setOption(chartOption, true);第二个参数:是否与之前的option进行合并,默认为false,改为true(合并)
(3)echarts设置没有数据的时候,显示“暂无数据”
this.chart.setOption({
// 没有数据时显示"暂无数据"
graphic: {
type: 'text',
left: 'center',
top: '40%',
silent: true, // 不响应事件
invisible: seriesArr.length > 0, // 有数据就隐藏
style: {
fill: '#8F9296',
text: '暂无数据',
fontSize: '16'
}
},
(4)echarts设置legend为省略号,当鼠标移动上去显示完整名字
legend: {
show: true,
top: 10,
itemWidth: 8,
textStyle: { color: '#5C6063' },
formatter: function (name) {
return echarts.format.truncateText(name, 60, '14px Microsoft Yahei', '…');
},
tooltip: {
show: true
}
},
(5)echarts给y轴设置最大值
yAxis: {
type: 'value',
max: (value) => {
if (value == null) {return }
return (value.max + value.max * 0.1).toFixed(2);
},
}
(6)解决echarts绘制散点图数据过多时,hover到散点上数据消失的问题
在 Echarts 中,当数据点过多时,为了提高性能,Echarts 会对离视口较远的数据点进行优化,使其不会渲染出来。然而,在这种情况下,当你将鼠标悬停在一个没有渲染出来的数据点上时,Echarts 仍然能够显示该数据点的相关信息。这可能导致一些用户感到困惑,因为他们可能会误认为这个数据点并不存在。
(a).可以设置 Echarts 的 large 参数为 true, 使得 Echarts 在数据点较多的情况下不再对离视口较远的数据点进行优化,并始终保持它们的可见性.
(b).设置 largeThreshold 参数来控制在多少个数据点以上才开始启用这种模式
option = { xAxis: {},
yAxis: {},
series: [{
type: 'scatter', large: true, // 启用大型图表模式
largeThreshold: 500, // 当数据点数量超过 500 个时启用启用大型图表模式 data: [],
}],};
- element时间选择器,设置时间选择禁用范围-只能选当前日期之前的日期
//:picker-options=“pickerOptions” 是限制选择时间的属性
.html页面元素
<el-date-picker
v-model="item.endYear"
:picker-options="pickerOptions"
type="datetime"
>
</el-date-picker>
data() {
// 这里存放数据
return {
pickerOptions:{
disabledDate (time) {
//disabledDate 文档上:设置禁用状态,参数为当前日期,要求返回 Boolean
return time.getTime() > Date.now()//选当前时间之前的时间
//return time.getTime() < Date.now()//选当前时间之后的时间
}
},
}
}
- vue-element表格,动态改变table内容高度,超出显示滚动条
1. Template
<div style="height: calc(100% - 80px);" ref="getH">
<el-table v-loading="loading" :key="tableDataStatu"
:data="projectData.slice((currentPage - 1) * pageSize, currentPage * pageSize)"
style="width: 100%;overflow: auto;" @selection-change="handleSelectionChange" :height="tableBodyH">
<el-table-column type="selection"></el-table-column>
<el-table-column prop="name" size="small" show-overflow-tooltip label="项目名称" align="center"
min-width="200"></el-table-column>
<el-table-column v-show="true" show-overflow-tooltip prop="imgUrl" label="项目效果图" align="center"
min-width="100">
<template slot-scope="scope">
<el-image style="height:50px;width: 100%;padding-top: 10px;"
:src="IMG_URL + scope.row.imgUrl"></el-image>
</template>
</el-table-column>
2. Data
export default {
data(){
return {
tableBodyH: 0,
bodyclientHeight: document.body.clientHeight,//当前页面宽度,用于监听窗口变化
}
},
mounted() {
this.$nextTick(() =>
// 动态获取表格外部高度并给表格内容设置高度
let { width, height } = this.$refs.getH.getBoundingClientRect()
this.$set(this, "tableBodyH", height - 15)
})
//窗口变化,重新设置页面高度
window.onresize = () => {
return (() => {
window.clientHeight = document.body.clientHeight;
this.bodyclientHeight = window.clientHeight
})()
}
},
watch: {
// 监听页面高度bodyclientHeight,只要变化了就改变页面盒子高度
bodyclientHeight: {
deep: true,
handler(newVal, oldVal) {
//浏览器窗口变化-改变table高度
if (newVal !== oldVal) {
let { width, height } = this.$refs.getH.getBoundingClientRect()
this.$set(this, "tableBodyH", height - 15)
}
}
}
},
}
- element消息提示封装
messageInfo(type, text) {//type-1:警告;2:错误;3:成功
let newType = ""
if (type == 1) {
newType = "warning"
} else if (type == 2) {
newType = "error"
} else if (type == 3) {
newType = "success"
}
return this.$message({ message: text, type: newType })
},
- element缓冲
开启: this.$modal.loading("验证中...");
关闭:this.$modal.closeLoading();
- 解决element-message消息显示重叠问题
解决方案:将方法定义为 async 异步函数,然后使用 await 等待执行。
async checkLogin () {
if (this.username === '') {
await this.$message.warning('请输入用户名')
}
if (this.password === '') {
await this.$message.warning('请输入用户密码')
}
}
- 计算属性返回不同的class名
(1)计算属性设置返回值
58. computed:{
theWeather(){
return function(Weather){
switch (Weather) {
case "晴":case "平静":case "微风":case "和风":case "清风":case "热":case "冷":
return "WeatherIcon1";
break;
case "少云": case "晴间多云": case "多云": case "阴":
return "WeatherIcon2";
break;
case "有风":case "强风/劲风":case "疾风":case "大风":case "烈风":case "风暴":case "狂爆风":case "飓风":case "热带风暴":
return "WeatherIcon3";
break;
case "霾":case "中度霾":case "重度霾":case "严重霾":case "浮尘":case "扬沙":case "沙尘暴":case "强沙尘暴":case "龙卷风":
return "WeatherIcon4";
break;
case "阵雨":case "雷阵雨":case "雷阵雨并伴有冰雹":case "小雨":case "中雨":case "大雨":case "暴雨":case "大暴雨":case "特大暴雨":case "强阵雨":case "强雷阵雨":case "极端降雨":case "毛毛雨/细雨":case "雨":case "小雨-中雨":case "中雨-大雨":case "大雨-暴雨":case "暴雨-大暴雨":case "大暴雨-特大暴雨":case "雨雪天气":case "雨夹雪":case "阵雨夹雪":case "冻雨":
return "WeatherIcon5";
break;
case "雪":case "阵雪":case "小雪":case "中雪":case "大雪":case "暴雪":case "小雪-中雪":case "中雪-大雪":case "大雪-暴雪":
return "WeatherIcon6";
break;
case "雾":case "浓雾":case "强浓雾":case "轻雾":case "大雾":case "特强浓雾":
return "WeatherIcon7";
break;
default:
return "WeatherIconelse"
}
}
}
},
(2)展示
<div :class="[theWeather(WeatherList[0].dayweather),'WeatherIcon']" ></div>
- Element-vue时间选择器根据选择的时间动态禁用不可选区域范围
.template
//时间粒度选择
<el-form size="small" :model="Tab1Form" ref="Tab1Form " :inline="true" class="mb10" >
<el-form-item label="时间间隔">
<el-select v-model="Tab1Form.timeInterval" @change="handleChange1" style="width: 120px" placeholder="请选择" >
<el-option v-for="item of timeIntervalOption" :key="item.value" :label="item.name" :value="item.value" ></el-option>
</el-select>
</el-form-item>
//时间控件
<el-form-item label="日期选择">
<el-date-picker type="datetimerange" format="yyyy-MM-dd HH:mm" :picker-options="pickerOptions1" value-format="yyyy-MM-dd HH:mm"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
v-model="Tab1Form.DataTime"
:clearable="false"
>
</el-date-picker>
</el-form-item>
</el-form>
.data/.methods
data() {
return {
selectData1: "",//用户点选的下限时间
dayStartTime: "", //项目有数据的开始时间
D1Statu: 0, //时间粒度状态
Tab1Form: {
// 时间间隔
timeInterval: "0",
DataTime: [
this.timeStampToFormatedDateStr(
new Date().getTime() - 24 * 60 * 60 * 1000
),
this.timeStampToFormatedDateStr(new Date().getTime()),
],
},
timeIntervalOption: [
{
name: "1min",
value: "0",
},
{
name: "5min",
value: "1",
},
],
pickerOptions1: {
// 点选时间控件中的日期触发
onPick: ({ maxDate, minDate }) => {
this.selectData1 = minDate.getTime();
if (maxDate) {
// 第二次点击日期选择器,选好初始时间和结束时间后,解除禁用限制
this.selectData1 = "";
}
},
//限制可选范围
disabledDate: this.disabledDueDate,
selectData1: "",
dayStartTime: null,
},
}
},
methods: {
// 监听时间间隔
handleChange1() {
// 限制时间范围:0(1min):可选时间范围最长为10天;1(5min):可选时间范围最长为2个月;2(10min):可选时间范围最长为4个月;3(20min)/4(30min)/5(60min):可选时间最长范围为6个月
if (this.Tab1Form.timeInterval == 0) {
// 10天
this.D1Statu = 0;
} else if (this.Tab1Form.timeInterval == 1) {
this.D1Statu = 1;
// 2个月
}
},
disabledDueDate(time) {
if (this.D1Statu == 0) {
//只能选10天
if (this.selectData1) {
//后端返回开始有数据的时间开始(dayStartTime)||大于当前时间的禁用||超过用户选择时间后10天的不能选||小于用户选择时间前10天前的都不能选
return (
time.getTime() < this.dayStartTime ||
time.getTime() > Date.now() ||
time.getTime() > this.selectData1 + 10 * 24 * 3600 * 1000 ||
time.getTime() < this.selectData1 - 10 * 24 * 3600 * 1000
);
} else {
return (
time.getTime() < this.dayStartTime || time.getTime() > Date.now()
);
}
} else if (this.D1Statu == 1) {
//只能选2个月
if (this.selectData1) {
return (
time.getTime() < this.dayStartTime ||
time.getTime() > Date.now() ||
time.getTime() > this.selectData1 + 2 * 30 * 24 * 3600 * 1000 ||
time.getTime() < this.selectData1 - 2 * 30 * 24 * 3600 * 1000
);
} else {
return (
time.getTime() < this.dayStartTime || time.getTime() > Date.now()
);
}
}
},
},
created() {
this.dayStartTime = new Date(
new Date(dataTime).setDate(new Date(dataTime).getDate() - 1) ).getTime();
}
- 判断对象和数组是否为空
(1) 对象
var data = {};
var b = JSON.stringify(data) == "{}";
console.log(b); // true
(2) 数组
① 方法一
var data = [];
if(data.length == 0){
//data为空数组时,要执行的代码
alert("data为空");
}
② 方法二
var data = [];
if(data == false){
//data为空数组时,要执行的代码
alert("data为空");
}
- Element解决回显无法修改数据的问题
<el-input :disabled="isDetail" @input="handeinput"v-model="item.factorValue" placeholder="请输入" maxlength="20" style="width: 90px"/>
方法:(强制刷新,缺点:比较消耗资源)
handeinput() {
this.$forceUpdate();
},
- element远程搜索传递多个值
<el-autocomplete
:disabled="isDetail"
v-model="item.industrialName"
@input="handeinput"
:fetch-suggestions="
(queryString, cb) => {
queryUnit(queryString, cb, item.value);
}
"
placeholder="请输入"
@select="handleSelect($event, index)"
suffix-icon="el-icon-search"
>
</el-autocomplete>
queryUnit(queryString, cb, item) {
// 搜索到的列表
let restaurants = [];
// 拿queryString进行模糊查询得到restaurants ONDO:
// 请求接口查询数据
let param = {
industrialName: queryString,
type: item,
};
//请求接口
gwpList(param).then((res) => {
let data = res.content;
if (data.length > 0) {
data.map((item) => {
let NewItem = {
value: item.industrialName,
};
restaurants.push(NewItem);
});
restaurants.map((item, index) => {
let obj = data.filter(
(item1) => item1.industrialName == item.value
);
if (obj.length > 0) {
restaurants[index] = {
...item,
...obj[0],
};
}
});
this.newrestaurants = restaurants;
let results = queryString
? restaurants.filter(this.createStateFilter(queryString))
: restaurants;
cb(results);
} else {
clearTimeout(this.timeout);
this.$message({ message: "未查询到相关数据", type: "warning" });
}
});
},
- Element表单输入框type=’number’的时候去掉输入框中右边上下点选的箭头
.numrule >>> input::-webkit-outer-spin-button,
.numrule >>> input::-webkit-inner-spin-button {
-webkit-appearance: none !important;
}
.numrule >>> input[type="number"] {
-moz-appearance: textfield;
}
- element固定请求格式
(1)删除
handleDelete(row) {
const id = row.id;
console.log(row, "删除row");
this.$modal
.confirm('是否确认删除名称为 "' + row.assetName + '" 的数据项?')
.then(function () {
return carbonAssetDelete({ id });
})
.then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
- vue监听窗口变化
<template>
<div class="Carbencockpit" ref="bodys"></div>
</template>
<script>
data() {
return {
cw: 1920,
ch: 1080,
}
};
mounted() {
this.windowResize();
window.onresize = () => {
this.windowResize();
};
},
methods: {
windowResize() {
let body = this.$refs.bodys;
let cw = this.cw;
let ch = this.ch;
body.style.width = cw + "px";
body.style.height = ch + "px";
// 窗口宽高
let w = window.innerWidth,
h = window.innerHeight;
// 缩放比例
let r = w / cw < h / ch ? w / cw : h / ch;
body.style.transform = `scale( ${r})`;
// 因为scale是以body的原中心点为基准进行缩放,所以缩放之后需要调整外边距,使其位于窗口的中心位置
body.style.marginLeft = -(cw - r * cw) / 2 + (w - r * cw) / 2 + "px";
body.style.marginTop = -(ch - r * ch) / 2 + (h - r * ch) / 2 + "px";
body.style.marginBottom = -(h > ch ? h : ch - r * ch) + "px";
body.style.marginRight = -(w > cw ? w : cw - r * cw) + "px";
},
},
</script>
- vue框架设置全屏/退出全屏
安装组件:npm install screenfull --save
// 当前页面引入-全屏/退出全屏组件
import screenfull from "screenfull";
methods:
// 全屏/退出全屏
fullScreenChange() {
if (this.isFullScreen) {
//全屏
this.isFullScreen = false;
screenfull.request();
} else {
// 退出全屏
this.isFullScreen = true;
screenfull.exit();
}
},
- 在element表单输入框后面增加单位
<el-input
v-model="form.number"
type="number"
style="width: 222px"
class="propUnit Unit2 numrule">
<i slot="suffix"
style="font-style: normal; margin-right: 10px"
>{{ form.unit }}</i>
</el-input>
- 在 Vue 2.0 中,一个应用程序的运行流程主要包括以下几个步骤
1) 创建 Vue 实例:使用 Vue 构造函数创建一个新的 Vue 实例,并传入一个选项对象作为参数。
2) 挂载元素:将 Vue 实例挂载到 HTML 元素上,使 Vue 实例与 DOM 对象关联起来。
3) 渲染模板:在实例化 Vue 时,会通过渲染函数把数据转换成视图,然后把渲染后的结果插入到指定的容器元素中。
4) 数据绑定:Vue 使用数据劫持结合发布订阅者模式的方式,实现数据绑定的效果。
5) 更新视图:当数据发生变化时,Vue 会自动检测数据的变化,然后重新进行渲染,更新视图
- Vue 2.0 中封装 Axios 请求的基本步骤
1. 安装 Axios:首先,在您的项目中安装 Axios 库。可以使用 npm 或 yarn 来完成安装:
npm install axios --save
# 或者
yarn add axios
2. 创建一个专门处理 Axios 请求的文件:在 src 目录下创建一个名为 "api.js" 的新文件。在这个文件中,我们将初始化 Axios 并编写各种请求函数。
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://your-api-url.com',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
// Add a request interceptor
instance.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
console.log(error);
return Promise.reject(error);
});
// Add a response interceptor
instance.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
export default instance;
3. 在组件中使用 Axios:现在,您可以在任何组件中使用 Axios 发起网络请求了。例如:
<template>
<div>{{ message }}</div>
</template>
<script>
import axios from '@/api' // 加载封装的 axios
export default {
name: 'HelloWorld',
data () {
return {
msg: ''
}
},
created () {
axios.get('/someUrl')
.then(response => (this.msg = 'Hello ' + response.data))
.catch(err => console.error(err));
}
</script>
- vue项目打包发布
(1) vue.config.js文件中加上: publicPath:"./" const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, lintOnSave: false, publicPath:"./" })
(2) 命令行运行npm run build
(3) 命令行运行完成后自动生成的dist文件就是打包生成的项目
- 路由跳转
在Vue 2.0中,页面跳转通常通过其内置的路由系统(vue-router)来实现。下面是如何进行页面跳转的几种方法:
1. 编程式导航: 在组件内部,可以通过注入到每个 Vue 实例的 $router 对象来执行导航。
Javascript
// 导航到一个命名路由
this.$router.push({ name: 'targetRouteName' });
// 或者直接通过路径名跳转
this.$router.push('/path/to/route');
// 如果目标路由需要参数,可以这样传递
this.$router.push({ path: '/user/:id', params: { id: '123' } });
2. 使用 v-bind 和 to 属性: 在模板中,可以直接在 <router-link> 组件上设置 to 属性来进行导航,它会渲染成一个 <a> 标签。
Html
<!-- 跳转到命名路由 -->
<router-link to="{ name: 'targetRouteName' }">点击跳转</router-link>
<!-- 跳转到指定路径 -->
<router-link to="/path/to/route">点击跳转</router-link>
3. 动态跳转: 如果是在事件处理函数中,例如按钮点击事件,同样可以使用 $router.push() 方法。
Html
<button @click="goToTargetPage">跳转</button>
// 在 methods 中定义
methods: {
goToTargetPage() {
this.$router.push('/path/to/route');
}
}
4. 重定向和别名: 如果是全局配置级别的重定向或别名跳转,则在 router.js 文件中的路由配置对象里进行定义。
Javascript
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
// ...
{ path: '/alias', component: TargetComponent, alias: '/original-path' }, // 别名
{ path: '*', redirect: '/default-route' }, // 重定向所有未匹配的路由
]
})
确保在项目中正确安装并配置了 vue-router,并且在主入口文件(如 main.js)中已经将 router 注入到了 Vue 实例中
- vue-element表格滚动
在Element UI中,如果你想实现表格(el-table)的无限循环滚动效果,可以结合Element UI的infinite-scroll指令和一些自定义逻辑来实现。以下是一个基本的步骤和代码示例:
1. 首先确保你的项目已经安装了Element UI。
2. 在你的Vue组件中,引入需要的元素和指令:
html
<template>
<div>
<el-table
ref="table"
:data="tableData"
style="width: 100%"
@scroll="handleScroll"
infinite-scroll
infinite-scroll-distance="10"
infinite-scroll-immediate-check="false"
>
<!-- 表格列的定义 -->
<el-table-column prop="column1" label="列1"></el-table-column>
<el-table-column prop="column2" label="列2"></el-table-column>
<!-- 其他列定义... -->
</el-table>
</div>
</template>
3. 在你的Vue组件的脚本部分,定义数据和方法:
javascript
export default {
data() {
return {
tableData: [], // 初始化表格数据为空数组
loading: false, // 是否正在加载更多数据的标志
page: 1, // 当前页数
pageSize: 10, // 每页显示的数据数量
total: 0, // 总数据数量
};
},
mounted() {
this.loadData(); // 在组件挂载后加载初始数据
},
methods: {
loadData() {
this.loading = true;
// 这里假设你有一个获取表格数据的API接口
axios.get('/api/getTableData', {
params: {
page: this.page,
pageSize: this.pageSize,
},
})
.then((response) => {
const { data, pagination } = response.data;
this.total = pagination.total;
this.tableData = [...this.tableData, ...data];
this.loading = false;
})
.catch((error) => {
console.error(error);
this.loading = false;
});
},
handleScroll(target) {
const scrollTop = target.scrollTop;
const scrollHeight = target.scrollHeight;
const clientHeight = target.clientHeight;
// 当用户滚动到距离底部100px时,开始加载更多数据
if (scrollTop + clientHeight >= scrollHeight - 100 && !this.loading && this.total > this.tableData.length) {
this.page++;
this.loadData();
}
},
},
};
在这个示例中,我们使用了infinite-scroll指令来监听表格的滚动事件,并通过handleScroll方法判断是否到达了滚动区域的底部。当满足加载更多数据的条件时,我们增加page的值并调用loadData方法去获取更多的数据。
请注意,这个示例假设你有一个能够返回分页数据的API接口,并且你需要根据你的实际接口进行调整。同时,你也可能需要处理一些边界情况,比如当没有更多数据可加载时的提示等。