Vue+element+Nodejs学习记录(7)

26 篇文章 0 订阅
23 篇文章 1 订阅
本文记录了Vue结合Element UI实现Table的动态加载、编辑、删除功能,详细讲解了数据绑定、子组件通信以及如何使用moment处理日期。还介绍了Vue中集成百度地图和Echarts图表的步骤,并探讨了v-show与v-if的区别。
摘要由CSDN通过智能技术生成

1.element中Table表格的使用

先看官网的一个示例:

<template>
  <el-table
    :data="tableData"
    style="width: 100%">
    <el-table-column
      label="日期"
      width="180">
      <template slot-scope="scope">
        <i class="el-icon-time"></i>
        <span style="margin-left: 10px">{{ scope.row.date }}</span>
      </template>
    </el-table-column>
    <el-table-column
      label="姓名"
      width="180">
      <template slot-scope="scope">
        <el-popover trigger="hover" placement="top">
          <p>姓名: {{ scope.row.name }}</p>
          <p>住址: {{ scope.row.address }}</p>
          <div slot="reference" class="name-wrapper">
            <el-tag size="medium">{{ scope.row.name }}</el-tag>
          </div>
        </el-popover>
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template slot-scope="scope">
        <el-button
          size="mini"
          @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
        <el-button
          size="mini"
          type="danger"
          @click="handleDelete(scope.$index, scope.row)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
  export default {
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }]
      }
    },
    methods: {
      handleEdit(index, row) {
        console.log(index, row);
      },
      handleDelete(index, row) {
        console.log(index, row);
      }
    }
  }
</script>

在这里插入图片描述
代码解释看下图:
在这里插入图片描述

2.element中Table进阶使用

我们想实现的功能是数据的动态加载和数据的编辑和删除。

//通过生命周期函数created()加载后端数据展示在网页上
<el-table :data="tableData" style="width: 100%"> 
  <el-table-column label="日期" align="center" width="160">
    <template slot-scope="scope">
      <span>{{scope.row.createtime|moment("YYYY-MM-DD")}}</span>
    </template>
  </el-table-column>
  <el-table-column label="姓名" align="center" width="160">
    <template slot-scope="scope">
      <span>{{scope.row.author}}</span>
    </template>
  </el-table-column>
  <el-table-column label="标题" align="center" width="160">
    <template slot-scope="scope">
      <span>{{scope.row.title}}</span>
    </template>
  </el-table-column>
  <el-table-column label="内容" align="center" width="160">
    <template slot-scope="scope">
      <span>{{scope.row.content}}</span>
    </template>
  </el-table-column>
  <el-table-column label="操作" align="center">
    <template slot-scope="scope">
      <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
      <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
    </template>
  </el-table-column>
</el-table>

<script>

export defalut{
	data(){
		return {
			tableData:[]
		}
	},
    created(){ //进入页面就执行,获取table数据 http://localhost:8000/api/blog/list
      this.getProfile();
    },
    methods:{
		getProfile(){
  			this.$axios.get("/api/blog/list")
    			.then( res =>{
      				//console.log(res.data)
      				//console.log(res.data instanceof Array)
      				this.tableData = res.data.data; //res.data返回的是{data:Array(3),errno:0},所以使用res.data.data
      				console.log(this.tableData)
    			})
    		.catch( err => {
      			console.log(err)
    		})
		}
	}
}
</script>

在这里插入图片描述

我们接下来要实现编辑和删除操作(弹出的dialog我们使用子组件来使用,要注意数据的传递)

在这里插入图片描述

//row包含着所在行的所有数据
<script>

import Dialog from '../components/DialogFound'

export default{
	name:"foundList",
    data() {
      return {
        tableData: [],
        dialog:{
          show:false,
          title:"编辑用户信息",
          option:"edit"
        },
        formData:{
          title:"",
          content:"",
          id:""
        }
      }
    },
    created(){ //进入页面就执行,获取table数据 http://localhost:8000/api/blog/list
      this.getProfile();
    },
    methods:{
      getProfile(){
        this.$axios.get("/api/blog/list")
          .then( res =>{
            //console.log(res.data)
            //console.log(res.data instanceof Array)
            this.tableData = res.data.data; //res.data返回的是{data:Array(3),errno:0},所以使用res.data.data
            console.log(this.tableData)
          })
          .catch( err => {
            console.log(err)
          })
      },
      handleEdit(index,row){
        //console.log(index,row);
        this.dialog.show = true;
        console.log(row.id,row.title,row.content)
        this.formData = {
          id:row.id,
          title:row.title,
          content:row.content
        }
      },
      handleDelete(index,row){
        console.log(index,row.id);
        this.$axios.post("api/blog/del",{
          id:row.id
        })
          .then(res =>{
            if(res.data.errno === 0){
              this.$message({
                message:'删除成功',
                type:'success'
              })
              this.getProfile();
            }
          })
          .catch(err =>{
            console.log(err)
          })
      }
    },
    components:{
      Dialog
    }
  }
</script>

上面getProfile函数会把数据的id、title、content、createtime和author数据请求到,编辑功能的handleEdit把this.dialog.show设置为true,让dialog显示,同时把点击的那行数据row分别赋值给formData,不仅是显示数据,而且也获取我们点击是在哪一个ID,方便后面axios请求参数的确定。删除功能的handleDelete主要的参数是row.id删除对应的数据。

下面我们书写子组件DialogFound.vue

<template>
	
<div class="logFound">

	<el-dialog 
	:title="dialog.title" 
	:visible.sync="dialog.show"
	:close-on-click-modal="false"
    :close-on-press-escape="false"
    :modal-append-to-body="false" >
		
		<div class="form">
			
			<el-form
				ref="formData"
				:model="formData"
				:rules="form_rules"
				label-width="120px"
				style="margin-left:-10px;width:auto">
				
				<el-form-item prop="title" label="标题:">
            		<el-input type="title" v-model="formData.title"></el-input>
          		</el-form-item>

          		<el-form-item prop="content" label="内容:">
            		<el-input type="content" v-model="formData.content"></el-input>
          		</el-form-item>

          		<el-form-item class="text_right">
          			<el-button @click="dialog.show = false">取消</el-button>
          			<el-button type="primary" @click='onSubmit("formData")'>提 交</el-button>
          		</el-form-item>


			</el-form>


		</div>
		

	</el-dialog>
	
</div>


</template>

<script type="text/javascript">
	
	export default{
		name:'logfound',
		props:{
			dialog:Object,
			formData:Object
		},
		data() {
	      return {
	        form_rules: {
		        title: [
		          { required: true, message: "标题不能为空!", trigger: "blur" }
		        ],
		        content: [
		          { required: true, message: "内容不能为空!", trigger: "blur" }
		        ]
      		}
		  };
	    },
	    methods:{
	    	onSubmit(formData){
	    		this.$refs[formData].validate(valid =>{
	    			if(valid){
	    				this.$axios.post("api/blog/update",{
	    					id:this.formData.id,
	    					title:this.formData.title,
	    					content:this.formData.content
	    				})
	    					.then(res =>{
	    						if(res.data.errno === 0){
	    							//操作成功
	    							this.$message({
	    								message:"保存成功!",
	    								type:"success"
	    							});
	    							this.dialog.show = false;
	    							this.$emit("update")
	    						}
	    					})
	    					//console.log(this.formData.id)/* */
	    			}
	    		})
	    	}
	    }
    }
    	

</script>

<style scoped type="text/css">
	

</style>

我们要注意使用props接收父组件传递过来的dialog和formData,在el-form中建议ref和:model使用同一个值,因为使用不同值时候,报错,:model=“formData”就是接收传递过来的值,我们要填充在el-form-item中,v-model中使用formData.title和formData.content赋值,我们注意@click="dialog.show = false"的写法,简单了很多,提交时候,就是把我们表单中提交的数据update数据库,然后刷新当前页面进行显示,onSubmit()函数的参数就是我们的数据formData,在函数把我们填写的title和content数据和传递过来的id数据作为参数调用api/blog/update接口,进行更新数据,更新数据后,我们还要关闭窗口和页面刷新显示,所以设置this.dialog.show=false和this.$emit(“update”),父组件进行接收,然后重新调用getProfile()函数进行获取数据和显示。

<Dialog :dialog='dialog' :formData='formData' @update="getProfile" ></Dialog>

3.Vue中使用moment

1.安装
npm install vue-moment

main.js添加:Vue.use(require('vue-moment'));

2..vue文件使用
<span>{{ someDate | moment("dddd, MMMM Do YYYY") }}</span>

参考文章:
https://www.npmjs.com/package/vue-moment
https://blog.csdn.net/qq_26422747/article/details/78697936
https://blog.csdn.net/Bright2017/article/details/74231668
https://blog.csdn.net/fu983531588/article/details/89330929

4.Vue中使用百度地图

1.在index.html中引入script

<script src='http://api.map.baidu.com/api?v=2.0&ak=你的密钥&callback=init'></script>

2.给定容器,调用API绘图

<template>

	  <!--引入地图文件-->
      <div id="allmap" style="width: 500px;height: 390px;margin-top: 60px;margin-left: 120px">

        <!--复兴公园:121.475063,31.223459-->
        <!--世纪公园:121.558426,31.223459-->
        <!--海棠公园:121.394,31.256064-->

      </div>

</template>

<script>

	export default{
		methods:{
			drawMap(){
				// 百度地图API功能
				var map = new BMap.Map("allmap");    // 创建Map实例
				map.centerAndZoom(new BMap.Point(121.474488, 31.224942), 12);  // 初始化地图,设置中心点坐标和地图级别

			    //三个监测点的信息
			    var data_info = [
			        [121.475063,31.223459,"地址:上海市复兴公园"],
			        [121.558426,31.223459,"地址:上海市世纪公园"],
			        [121.394,31.256064,"地址:上海市海棠公园"]
			    ];

			    //弹出框设置
			    var opts = {
							width : 100,     // 信息窗口宽度
							height: 80,     // 信息窗口高度
							title : "监测点" , // 信息窗口标题
							enableMessage:true//设置允许信息窗发送短息
			    };

			    for(var i=0;i<data_info.length;i++){
					var marker = new BMap.Marker(new BMap.Point(data_info[i][0],data_info[i][1]));  // 创建标注
					var content = data_info[i][2]+ "<div><a href='/manage-content'>水质详情</a></div>";
					map.addOverlay(marker);               // 将标注添加到地图中
					addClickHandler(content,marker);
				}

				function addClickHandler(content,marker){
					marker.addEventListener("click",function(e){
						openInfo(content,e)}
					);
				}

				function openInfo(content,e){
					var p = e.target;
					var point = new BMap.Point(p.getPosition().lng, p.getPosition().lat);
					//InfoWindow(content: String | HTMLElement, opts: InfoWindowOptions)
			        //创建一个信息窗实例,其中content支持HTML内容。1.2版本开始content参数支持传入DOM结点
					var infoWindow = new BMap.InfoWindow(content,opts);  // 创建信息窗口对象
					map.openInfoWindow(infoWindow,point); //开启信息窗口
				}

			    //添加地图类型控件
				map.addControl(new BMap.MapTypeControl({
					mapTypes:[
			            BMAP_NORMAL_MAP,
			            BMAP_HYBRID_MAP
			        ]}));
				map.setCurrentCity("上海");          // 设置地图显示的城市 此项是必须设置的
				map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放
			}
		},
		mounted(){
			this.drawMap()
		}
	} 

</script>

参考文章:https://blog.csdn.net/DOCALLEN/article/details/70877925

5.Vue中使用echarts

1.安装echarts项目依赖

npm install echarts --save

2.在main.js中全局引入echarts

import echarts from “echarts”;
Vue.prototype.$echarts = echarts;

3.创建图表

<template>
  <div id="app">
    <div id="main" style="width: 600px;height:400px;"></div>
  </div>
</template>
export default {
  name: "app",
  methods: {
    drawChart() {
      // 基于准备好的dom,初始化echarts实例
      let myChart = this.$echarts.init(document.getElementById("main"));
      // 指定图表的配置项和数据
      let option = {
        title: {
          text: "ECharts 入门示例"
        },
        tooltip: {},
        legend: {
          data: ["销量"]
        },
        xAxis: {
          data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
        },
        yAxis: {},
        series: [
          {
            name: "销量",
            type: "bar",
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      };
      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    }
  },
  mounted() {
    this.drawChart();
  }
};
</script>

参考文章:https://juejin.im/post/5c0f6c6ae51d451ac27c4532

还可以参考:
https://juejin.im/post/5bfe4968f265da61407e9c12
https://blog.csdn.net/mr_wuch/article/details/70225364
https://segmentfault.com/a/1190000015453413

6.点击按钮动态切换

我们先看一个原生JS操作DOM的方法:

//思路就是,点击函数传递每个折线图的ID,通过判断ID,设置style.display
<el-row>
	<el-button @click="handleDis('pressure')" type="primary" plain>气压</el-button>
	<el-button @click="handleDis('temperature')" type="primary" plain>温度</el-button>
	<el-button @click="handleDis('tds')" type="primary" plain>浊度</el-button>
</el-row>

<div id="pressure"  style="float: left;width: 500px;height:300px;display: block"></div>
<div id="temperature" style="float: left;width: 500px;height:300px;display: none"></div>
<div id="tds" style="float: left;width: 500px;height:300px;display: none"></div>

handleDis(index){

	console.log(index=='pressure') //变量可以不加引号,但是常量要注意加引号

	let pre = document.getElementById("pressure");
	let tem = document.getElementById("temperature");
	let tds1 = document.getElementById("tds");

	if(index=='pressure'){

		pre.style.display = "block";
		tem.style.display = "none";
		tds.style.display = "none";

	}else if(index=='temperature'){

		pre.style.display = "none";
		tem.style.display = "block";
		tds.style.display = "none";

	}else{

		pre.style.display = "none";
		tem.style.display = "none";
		tds1.style.display = "block";

	}

}

接下来使用vue的v-show实现:

v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css–display:none,dom元素还在。

参考文章:https://www.cnblogs.com/echolun/p/7803943.html

//Vue提倡数据驱动,所以建议使用v-show或者v-if(注意v-show和v-if的值都是""括起来,不是{{}})
<el-row>
	<el-button @click="handleDis('pressure')" type="primary" plain>气压</el-button>
	<el-button @click="handleDis('temperature')" type="primary" plain>温度</el-button>
	<el-button @click="handleDis('tds')" type="primary" plain>浊度</el-button>
</el-row>

<div id="pressure" v-show="preVal" style="float: left;width: 500px;height:300px;"></div>
<div id="temperature" v-show="temVal" style="float: left;width: 500px;height:300px;"></div>
<div id="tds" v-show="tdsVal" style="float: left;width: 500px;height:300px;"></div>


handleDis(index){

	console.log(index=='pressure') //变量可以不加引号,但是常量要注意加引号


	if(index=='pressure'){

		this.preVal = true
		this.temVal = false
		this.tdsVal = false

	}else if(index=='temperature'){

		this.preVal	= false
		this.temVal	= true
		this.tdsVal	= false

	}else{

		this.preVal	= false
		this.temVal	= false
		this.tdsVal	= true

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值