因为项目需要前后端分离,后端竟然不用控制view层了,页面的跳转后端不再干涉,(前端的vue经过打包后成了一张index.html) 后端只需要响应给前端json串就ok,其实这不是爽歪歪?但是觉得还是奇奇怪怪,感觉前端是个黑盒了, 于是忍不住去学习了vue

感觉前端的框架带来的这种前后端分离变化还是特别明显的,后端确实不用再操心view层了,页面的转换有vue通过后端的切换不同的组件,后端基本上没有什么变化,但是相应数据基本上是清一色的json格式的数据了, 此外, 目前碰到的后端的安全框架 SpringSecurity的使用有了些许变化,起码认证成功还是失败,不能往指定的页面跳转了,转而使用消息+状态码提示,因为就一张index.html,还能往哪里跳转?

下面是近几天的学习笔记, 还是再整理一遍,毕竟会忘

认识MVVM框架Vue

MV VM分别对应着

  • model : 数据模型,存放后端传递过来的数据
  • view : 视图,其实就是html, 页面
  • viewModel : vue 的实例

下面是一个入门的例子: 通过这个例子可以看到:

  • 我们new 出来vue的实例,然后把它关联在了html中id为 app的代码块,这样目的是如果我们在这个代码块中使用vue的模板语法,vue可以解析
  • data: 这个模块盛放的 mvvm中的第一个m

其实这也可以看出,vue的开发模式,它的出现屏蔽掉了dom操作,我们再也不用document.getElementById(), 然后innnerHtml了, 现在的工作就是把后端给的值填充进data块中的属性字段就ok,一旦发生改变,页面会自动渲染上最新的值

<body>
<div id="app">
<input type="text" v-model="username"><!-- 声明式开发 dom监听 -->
<p>Haha {{username}}</p> <!-- 数据绑定 -->
</div> </body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app', // 元素选择器, 选出根路径
data:{ // Data Model 数据模型
username:'哈哈'
}
});
</script>

模板语法:

双大括号 取值:

<p>{{msg}}</p>
<p>{{msg.toUpperCase()}}</p> <!-- 可以调用js函数 -->

嵌入文本或html

<p v-text="msg"></p>    <!--  相当于 textContent -->
<p v-html="msg"></p> <!-- 相当于 innerHtml -->

强制数据绑定,在原标签前添加 :

<img :src="imaUrl" alt="">

绑定监听事件: @符

  • 比较有趣的地方,如果在methods块中,js函数的定义是无参数据的, 在html代码块中可以直接写函数名,而不写小括号,因为java代码写多了,看了想笑 ,(当然(),也可以写上,但是js编程者会认为这是没事找事)
<button @click="text"> 点我111 </button>
<button @click="text222('haha')"> 点我222 </button>

计算属性

计算属性,说白了就是vue给我们的一块糖,让我们定制数据的变化规则,然后vue帮我们渲染在html页面上

现在是2020年的5月23号,当我再回来看computed时,想再补充一下,如何更好的理解计算属性: 所谓计算属性,说白了,其实就是根据data中现有的属性计算得到一个新的属性 ,此外,计算属性函数是不需要我们手动执行的,会自动执行

  • 计算属性是针对data中的字段的操作
  • 计算属性中的每一个函数,都分两部分: get和set , 默认是get,作用是把这个方法的返回值渲染进页面, set方法,就是重新设置值, 然后get会重新渲染html
  • 计算属性是存在缓存的,key就是函数的名字,value就是计算得到的值

例子:

<body>
<div id="app">
姓名: <input type="text" placeholder="FirstName" v-model="secondName"> <br>
姓名1: <input type="text" placeholder="FullName1" v-model="FullName1"> <br>
姓名3: <input type="text" placeholder="FullName3" v-model="FullName3"> <br>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
// 下面的全部回调函数中, this都是vm对象
var vm = new Vue({
el: '#app',
data: {
firstName: 'A',
secondName: 'B',
},
computed: {
FullName1() {
return this.firstName + ' ' + this.secondName;
},
// todo 通过计算属性实现双向的数据绑定, 不受其他影响
FullName3: {
get() { // 计算并返回当前属性的值
return this.firstName + ' ' + this.secondName;
},
set(vel) { // get 执行之后 把结果返回给 set
const names = vel.split(' ');
alert(names[0]);
alert(names[1]);
this.firstName = names[0];
this.secondName = names[1];
}
}
}
});

计算属性写在computed块中, 可以看到它常用的两种写法, 在使用是时候都是直接使用函数名就行,因为它并没有参数

  • 函数名(){}
  • 对象名:{ get(){} , set(){} }

上面的FullName1以函数的,这种书写格式是对 get方法的默认实现,方法的返回值会被渲染到页面上

FullName3还重写了set(val){} 方法, 如果我们在FullName3对应的输入框里面输入新的值, val就是这个新的值,在set方法中,如果对当前vue实例的data中的属性做了改动,这个改动是双向的,页面中所有使用对应字段的地方的值,都会重新渲染

事件的监听:

它的语法:

// 下面的全部回调函数中, this都是vm对象
var vm = new Vue({
el: '#app',
data: {
firstName:'',
secondName:''
},
computed: {},
method: {},
watch: {/* 监视 */
firstName: function (newVal) {
this.firstName = newVal + ' ' + this.secondName;
}
}
});

它会监听data中的属性,当用户改变了data中属性的值,就会触发对应的回调

class和style的绑定

class和style的属性绑定同样使用的是使用 : 强制属性绑定

首先是写好 css属性,才能进一步使用vue将属性样式绑定在html上

head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.aClass{
font-size: 30px;
color: #ff4400;
}
.bClass{
color: #00b4ff;
}
.cClass{
color: #1c036c;
}
</style>
</head>

语法:

  • :class="data中的css属性"
  • :class="{data中的css属性:boolean, data中的css属性:boolean}", 这种对象语法,就是当类名确定但是是否显示不确定时使用,比如让一个导航栏中的一个高亮显示
  • :style="{color:activeColor,fontSize:fontSize +'px'}", style有单位的+单位
<body>
<div id="text">
<h2>1. class绑定 :: class='X X X '</h2>
<p :class="a">123123字符串</p>
<p :class="{aClass:isa, bClass:isb}">class是对象,绑定class 类名:boolean </p>
<h2>2. style 绑定 </h2>
<p :style="{color:activeColor,fontSize:fontSize +'px'}">2. style 绑定 </p>
<button @click="update" >点击</button>
</div>

下面的vue对象

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#text',
data: {
a:'aClass', // 关联着最上面的css样式
isa:true,
isb:false,
activeColor:'red',
fontSize:'30'
},
methods:{
update() {
this.a='bClass'
}
}
})

条件渲染

<p v-if="ok">deal</p> --> ok是vue中data的数据,ok为true时, 显示
<p v-else>false</p> --> 和 v-if成对出现, ok为false, 显示 <p v-show="ok"> 成功 </p>
<p v-show="!ok"> 失败 </p>

列表的渲染 v-for, 及对数组的操作

下面的例子使用v-for遍历数组中的每一个数据, 遍历的同时使用{{对象.属性}}展示属性,同时可以根据每个li的index绑定上不同的事件

<body>
<div id="text">
<ul>
<!-- 一旦有 v-for 加上key-->
<li v-for="(p,index) in person" :key="index">
{{p.name}} : {{p.age}} : {{index}}
<button @click="deleteP(index)"> 删除</button>
<button @click="updateP(index,{name:'Cat',age:20})"> 更新</button>
</li>
</ul>
</div> var vm = new Vue({
el: '#text',
data: {
person: [ /* vue 只会监视person的改变, 不会监视数组中数据的改变*/
{name: 'tom', age: 23},
{name: 'tom2', age: 223},
{name: 'tom2', age: 23},
{name: 'tom3', age: 232},
{name: 'tom5', age: 23}
]
},
methods: {
deleteP(index) {
this.person.splice(index, 1); //从index开始 删除1个
},
updateP(index, person) {
// this.person[index]=person; 并没有改变 persons , 从index开始,删除1个 添加person
this.person.splice(index, 1, person)
}

如果我们更新的js是这样写的, 数组中的内容确实会被改变,但是页面的上数据并不会更新

 this.person[index]=person; 并没有改变 persons  , 从index开始,删除1个 添加person

因为vue监听的person的改变,person中只有一个数组,虽然数组中的数据变了, 但是数组没变,所以我们使用vue的提供的splice进行数组的操作

splice(下标,数量,[新的对象数组])

他可以实现数组的增删改的效果

  • 删除
//删除起始下标为1,长度为2的一个值(len设置2)
var arr2 = ['a','b','c','d']
arr2.splice(1,2);
console.log(arr2);
//['a','d']
  • 修改
//替换起始下标为1,长度为1的一个值为‘ttt’,len设置的1
var arr = ['a','b','c','d'];
arr.splice(1,1,'ttt');
console.log(arr);
//['a','ttt','c','d']
  • 添加
var arr = ['a','b','c','d'];
arr.splice(1,0,'ttt');
console.log(arr);
//['a','ttt','b','c','d']

其他数组相关的操作

  • unshift()添加到第一个
  • shift() 添加到最后一个
  • push() 压栈,栈顶
  • pop()弹出
  • sort()排序
  • reverse() 反转

数组的映射,过滤,排序

js的箭头函数和java8的lambda表达式特别像

  • 映射
array.map(item=>item.id)
// 可以将数组中的每一个元素映射成他的id属性
  • 过滤
persons = person.filter(p => p.name.indexOf(searchModel)>=0);
// 保留数组中满足条件的对象
  • ES6的语法糖

    把对象的指定字段存放进声明的多个常量中
const{searchModel,person,orderType} = this;
  • 排序
persons.sort(function (p1,p2) {
// 升序
if (orderType===1){
return p1.age-p2.age;
} else if (orderType===2){ // 降序
return p2.age-p1.age;
}

事件绑定相关

@click绑定事件

<button @click="text1">text1</button>
<button @click="text2('haha')">text2</button>
<button @click="text3($event)">text3</button>
<button @click="text4">text4</button><!-- 如果没有指定参数进去,传递进去的就是event-->
<button @click="text5(123,$event)">text5</button> var vm = new Vue({
el:'#test',
methods:{
text1(){
alert("text 1");
},
text2(msg){
alert(msg);
},
text3(event){
alert(event.target.innerHTML);
},
text4(event){
alert(event.target.innerHTML);
},
text5(msg,event){
alert(msg+event.target.innerHTML);
},

可以看到@click使用vue中method的函数时,如果没有参数,可以简写,去掉(), 如果不写参数,传递进去的是事件本身event , text三中通过event拿到了标签的文本内容

@click.prevent阻止事件的默认行为

<a href="http:www.baidu.com" @click.prevent="text8">百度一下</a>  <!-- 阻止事件的默认行为 -->

监听某个按键的点击事件

<input type="text" @keyup.enter="text9"> <!--  @keyup.13(名字)  监听某一个键的点击事件 -->

收集表单数据

使用vue将用户填入表单中的数据收集起来, 收集到哪里去? 其实是收集到 vue的data块中的属性中

其实就是在html使用v-model暴力绑定dom监听, 将单选框,输入框,多选框中用户输入进去的内容和data中的属性关联起来

  • input,textarea 等输入框,收集起来的值就是用户输入进去的值
  • 单选框 radio ,多选框 checkbox 等选择框,收集起来的值的 html中的value属性的值
<h1>表单中最终提交给后台的是 value值</h1><br>
<h2> 使用v-model实现表单数据的自动收集 </h2>
<form action="/XXX" @submit.prevent="handleSubmit" ><!-- 阻止表单的默认自动提交事件 -->
<span>用户名:</span>
<input type="text" v-model="username"><br>
<span>密码</span>
<input type="password" v-model="pwd" ><br> <span>性别</span><br>
<input type="radio" id="female" value="女" v-model="sex">
<label for="female">女</label><br>
<input type="radio" id="male" value="男" v-model="sex">
<label for="male">男</label><br><br> <span>爱好</span><br>
<input type="checkbox" id="basket" value="basket" v-model="likes">
<label for="basket">篮球</label>
<input type="checkbox" id="foot" value="foot" v-model="likes">
<label for="foot">足球</label>
<input type="checkbox" id="pingpang" value="pingpang" v-model="likes">
<label for="pingpang">乒乓球</label><br><br> <span>城市</span><br>
<select v-model="cityId">
<option value="">未选择</option>
<option :value="city.id" v-for="(city,index) in allCitys" :key="index">{{city.name}}</option>
</select>
<span>介绍:</span>
<textarea name="" id="" cols="30" rows="10" v-model="dec"></textarea> <input type="submit" value="注册"><br> </form>
</div>
<script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({
el:'#test',
data:{
username:'',
pwd:'',
sex:'女',
likes:['foot'],
allCitys:[{id:1,name:'北京'},{id:2,name:"山东"},{id:3 ,name:"青岛"}],
cityId:'3' /* 默认让 3被选中*/,
dec:"哈哈"
}, methods:{
handleSubmit(){
alert(this.username+this.pwd);
alert(this.sex);
}
}
})

vue的生命周期

vue对象在创建初始化的过程中一次执行如下声明周期相关的方法, 根据这个特性,通常把加载进入一个新的页面中时去发送ajax请求的方法放到mounted(){},收尾工作放在beforeDestroy(){}

var vm = new Vue({
el: "#text",
data: {}, beforeCreate() { // 创建之前回调
console.log("beforeCreate");
}, created() { // 创建之后回调
console.log("created");
}, beforeMount() {
console.log("beforrMount");
}, // todo 常用, 异步操作, 比如发起ajax请求获取数据, 添加定时器
mounted() { // 初始化显示之后会立即调用一次
console.log("mounted");
this.intervalId = setInterval(() => {
console.log("干掉vm之后, 定时器还在跑, 内存泄露了");
this.isShow = !this.isShow;
}, 1000); /*
如果下面不使用箭头回调函数, this就是window, 而不是vm
* setInterval(() => {
this.isShow= !this.isShow;
},1000);
* */
}, // 更新阶段
beforeUpdate() { //更新阶段之前回调
console.log("beforeUpdate");
}, updated() { // 更新阶段之后回调
console.log("updated");
}, // 死亡阶段
// todo 常用 收尾工作
beforeDestroy() { // 死亡之前回调一次
console.log("beforeDestroy ");
clearInterval(this.intervalId);
}, destroyed() {
console.log("destroyed");
}, methods: {}
}
});

ES的语法糖,箭头函数

比如在设置定时器时, 定时器中需要对vue的属性进行操作,在定时器的代码块中this指的是定时器对象,es6的箭头语法解决就这个问题, 在箭头函数中this没有的属性,会到外层的vue中来找

this.intervalId = setInterval(() => {
console.log("干掉vm之后, 定时器还在跑, 内存泄露了");
this.isShow = !this.isShow;
}, 1000);

动画

按照vue的下面的几步要求, vue 会给目标元素添加或者移除特定的 css,实现动画的效果

  1. 需要添加动画的标签被 <transition name="" > XXX </transition>包裹

<div id="test">
<transition name="YYY">
<p v-show="isShow" class="">toggle</p>
<button @click="isShow=!isShow">toggle</button> </transition>
</div> <script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#test',
data() {
return {
isShow: true
}
}
});
  1. 定义以 .YYY-开头的 css属性, 这个YYY就是上面自定义的YYY, 需要在这些自定义的属性中指定过度的属性以及隐藏的属性

一个简单的动画效果标签从隐藏->出现, 再从出现到隐藏的过程,就像下面这样

v-enter  v-enter-to   v-leave    v-leave-to
隐藏 出现 出现 隐藏

自定义这四个时期的状态

/* 显示的过度效果*/
.YYY-enter-active {
transition: all 1s;
} /* 隐藏的过度效果*/
.YYY-leave-active {
transition: all 3s;
} /* 从无到有的样式 */
.YYY-enter {
opacity: 0;
} /* 从有到无的样式 */
.YYY-leave-to {
opacity: 0;
transform: translateX(20px); /* 离开时,向X轴的正方向移动20px*/
}

格式化时间的插件库

点击进入 moment.js网址 ,在这里可以找到需要引入的script标签

点击进入 moment.js的文档 在文档中可以找到对应的格式和例子

 <div id="test">
<h2>显示格式化的日期时间</h2>
<p>{{date}}</p>
<p>默认完整: {{date | dateFormat}}</p><!-- 一旦我们这么写, 他就会把date的值,传递给dateFormat函数 -->
<p>年月日: {{date | dateFormat('YYYY-MM-DD')}}</p><!-- 一旦我们这么写, 他就会把date的值,传递给dateFormat函数 -->
<p>时分秒: {{date | dateFormat('HH:mm:ss')}}</p><!-- 一旦我们这么写, 他就会把date的值,传递给dateFormat函数 --> </div> /* 这个在官网上查找 */
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.21.0/moment.js"></script> <script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
// 自定义过滤器
Vue.filter('dateFormat',(value,format)=>{ /* Vue是函数对象 */
return moment(value).format(format || 'YYYY-MM-DD HH:mm:ss');
}); new Vue({
el:'#test',
data:{
date:new Date()
}
});

Es的语法糖

es6 的语法: 形参默认值 , 没传值的话,就使用默认值

 function(value,format="YYYY-MM-DD"){
return moment(value).format(format);
}

vue的指令

常见的原生指令如下

v:text : 更新元素的textContent <br>
v:html : 更新元素的innerHtml<br>
v-if: true 如果为true,标签才会输出到页面 <br>
v-else: 如果为false,标签才会输出到页面 <br>
v-show: 通过控制display的样式来控制显示和隐藏<br>
v-for: 遍历数组对象 <br>
v-on: 绑定监听事件, 一般直接写 @ <br>
v-bind: 强制绑定解析表达式 一般简写成 : <br>
v-model: 双向数据绑定 <br>
ref: 指定唯一的标识, Vue对象可以通过 $els 属性来访问这个元素对象 <br>
v-cloak: 防止闪现可能应为网速的原因{{msg}} 一直解析不了, 于是用户就看到它了,不友好, 于是 vue推出 与css配合 [v-cloak] {display:none} <br>

补充最后两个

  • ref 指定唯一的标识, Vue对象可以通过 $els 属性来访问这个元素对象
  • 防止闪现可能应为网速的原因{{msg}} 一直解析不了, 于是用户就看到它了,不友好, 于是 vue推出 与css配合 [v-cloak] {display:none}

例子:

<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak] { /* 回去寻找有这个属性名的标签 [v-cloak] , 就是下面的p标签 */
display:none
}
</style>
</head>
<body> <div id="test">
<p ref="content123">哈哈哈哈</p>
<button @click="hint">提示</button>
// v-cloak="" + 上面的css 样式避免 {{ }} 闪现的效果
<p v-cloak="">{{msg}}</p>
<br> </div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
// 注册全局指令
Vue.directive('') new Vue({
el:'#test',
data:{
msg: '嘿嘿'
} ,
methods:{
hint(){
// 因为 `<p ref="content123">哈哈哈哈</p>` 使用了ref,所以vue可以通过this.$refs.content123 找到指定的这个元素
alert(this.$refs.content123.textContent)
}
}
});

后端小白的VUE入门笔记, 前端高能慎入的更多相关文章

  1. 后端小白的VUE入门笔记, 进阶篇

    使用 vue-cli( 脚手架) 搭建项目 基于vue-cli 创建一个模板项目 通过 npm root -g 可以查看vue全局安装目录,进而知道自己有没有安装vue-cli 如果没有安装的话,使用 ...

  2. Python爬虫 小白[3天]入门笔记

    笔记来源 Day-0 1.如果你还不了解Python的基础语法,可以移步|>>>Python 基础 小白 [7天] 入门笔记<<<|或自行学习. 简介 1.什么是爬 ...

  3. Python基础 小白[7天]入门笔记

    笔记来源 Day-1 基础知识(注释.输入.输出.循环.数据类型.随机数) #-*- codeing = utf-8 -*- #@Time : 2020/7/11 11:38 #@Author : H ...

  4. VUE 入门笔记

    前端的MVVM概念今年来也算是如火如荼,了解完 MVVM的概念,也该找个去尝试下 首先我先试了下 国内小而美的 VUE 试着照着文档敲出入门文件,内容都在注释里 <!doctype html&g ...

  5. Vue入门笔记#数据绑定语法

    #数据绑定语法# #文本: 数据绑定的基础表型形式,使用“Mustache”语法(双大括号)(特意查了一下Mustache同“moustache”释义为:髭:上唇的胡子,小胡子,最起码我觉得挺形象的) ...

  6. Vue入门笔记#过渡

    Vue过渡,可以在元素从DOM中移除,插入时自动调用过渡效果.根据设定,会适时的触发过渡效果. 在使用的目标标签里添加 transition: <div transition="my_ ...

  7. Vue入门笔记(一)--基础部分

    github地址:https://github.com/iTao9354/basicVue(demo01-28) 一.初识Vue 使用双大括号{{message}}将数据渲染进DOM中.      可 ...

  8. vue入门笔记

    Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还便于与 ...

  9. vue入门笔记(新手入门必看)

    一.什么是Vue? 1.    vue为我们提供了构建用户界面的渐进式框架,让我们不再去操作dom元素,直接对数据进行操作,让程序员不再浪费时间和精力在操作dom元素上,解放了双手,程序员只需要关心业 ...

随机推荐

  1. python模块之:paramiko

    1. 介绍: paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来实现.安装: ...

  2. vSphere、 ESXi、Vcenter、vSphere Client关系

    vSphere是什么? vSphere 是VMware公司发布的一整套产品包,是VMware公司推出的一套服务器虚拟化解决方案,包含VMware ESXi hypervisor,VMware vCen ...

  3. lower_bound 和 upper_bound 功能和用法

    以前用这两个函数的时候,简单看了几句别人的博客,记住了大概,用的时候每用一次就弄混一次,相当难受,今天对照着这两个函数的源码和自己的尝试发现:其实这两个函数只能用于 "升序" 序列 ...

  4. C++ 洛谷 P1273 有线电视网 题解

     P1273 有线电视网  很明显,这是一道树形DP(图都画出来了,还不明显吗?) 未做完,持续更新中…… #include<cstdio> #include<cstring> ...

  5. Git 安装教程(2.21.0)

    获取安装包地址 1.官网(较慢):https://git-scm.com/downloads 2.下载链接:http://down-ww3.newasp.net/pcdown/soft/soft1/g ...

  6. Codeforces 760C:Pavel and barbecue(DFS+思维)

    http://codeforces.com/problemset/problem/760/C 题意:有n个盘子,每个盘子有一块肉,当肉路过这个盘子的时候,当前朝下的这一面会被煎熟,每个盘子有两个数,p ...

  7. 20190101.DDD笔记

    建立领域模型步骤 根据提供的信息完善主要业务场景和业务流程: 根据业务流程识别领域事件并按照时序排列: 针对领域事件进行命令识别: 针对领域事件和命令进行聚合和子域的初步识别: 在识别的subdoma ...

  8. Java零基础个人学习路线总结

    之前学习Java的时候走过一些弯路,一直想写一篇文章来总结下自己对自学Java的认识.趁着这次开通专栏的机会整理一篇文章,既可以巩固所学,也可以为后来境遇相同的人做个参考. 首先提出几个问题 Java ...

  9. 关于java爬虫以及一些实例

    首先是工具介绍 Jsoup jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法 ...

  10. 个人永久性免费-Excel催化剂功能第93波-地图数据挖宝之两点距离的路径规划

    在日常手机端,网页端的向地图发出两点距离的行程规划,相信绝大多数人都有用到过,但毕竟是个体单一行为,若某些时候需要用到批量性的操作,就显得很不现实了,同时,数据只是在应用或网页内,非结构化的数据,也是 ...