目录
Vue%20%E6%A1%86%E6%9E%B6-toc" style="margin-left:0px;">一、认识 Vue 框架
Vue%20%E7%9A%84%E5%BC%80%E5%A7%8B-toc" style="margin-left:0px;">二、Vue 的开始
Vue%20%E7%9A%84%E6%96%B9%E6%B3%95%E4%B9%A6%E5%86%99-toc" style="margin-left:0px;">三、Vue 的方法书写
Vue%20%E7%9A%84%E5%86%85%E7%BD%AE%E6%8C%87%E4%BB%A4-toc" style="margin-left:0px;">四、Vue 的内置指令
1. 渲染
Vue%20%E7%9A%84%E7%B1%BB%E5%90%8D%E6%B8%B2%E6%9F%93-toc" style="margin-left:80px;">( 1 ) Vue 的类名渲染
Vue%20%E7%9A%84%E6%A0%B7%E5%BC%8F%E6%B8%B2%E6%9F%93-toc" style="margin-left:80px;">( 2 ) Vue 的样式渲染
2. 绑定属性
3. 条件渲染
4. 循环渲染
Vue%20%E4%B8%AD%20key%20%E7%9A%84%20%E9%97%AE%E9%A2%98%20%3A-toc" style="margin-left:80px;">Vue 中 key 的 问题 :
5. 绑定事件
6. 双向数据绑定
Vue%20%E6%A1%88%E4%BE%8B%20-%20%E5%8A%A8%E6%80%81%E8%A1%A8%E6%A0%BC%20%3A-toc" style="margin-left:0px;">Vue 案例 - 动态表格 :
跳转链接 => Vue _ 舒适版 02
跳转链接 => Vue _ 舒适版 03
跳转链接 => Vue _ 舒适版 04
Vue%20%E6%A1%86%E6%9E%B6">一、认识 Vue 框架
Vue 是一个渐进式框架
+ 因为框架一整套完整的生态系统
=> 把所有功能分开
=> 可以单独使用某一个功能
=> 随着你的需求逐渐增加内容
+ 特点: 学习成本低
+ 例子:
=> 有一个文件叫做 vue.js, 包含基础语法部分
=> 有一个文件叫做 vue-router.js, vue 里面扩展的部分
=> 根据你的需求, 引入不同的文件来实现开始 Vue
+ 就是一个第三方
+ 使用套路, 下载, 引入, 使用
+ 使用 npm 下载 ( 指令 $ npm i vue )
=> 下载以后, 有一个叫做 vue.js 和 vue.min.js 的文件
=> 引入以后就可以直接使用了
=> 在学习阶段, 推荐使用 vue.js
如何使用 Vue
+ Vue 的开始, 就是引入文件以后
+ 会提供给我们一个叫做 Vue 的 构造函数
+ 当你 创建实例 的时候, 表示你开始使用 Vue 了数据驱动视图
+ 框架帮我们把渲染页面的事情做完了
+ 我们只要准备好数据, 框架会帮我们把数据渲染到页面上
+ 对于开发人员来说, 只要专注于数据的操作即可
Vue%20%E7%9A%84%E5%BC%80%E5%A7%8B">二、Vue 的开始
<div id="app" class="box">
<!-- 这里可以识别 Vue 的语法 -->
<!--
插值表达式
+ 向某一个部分插入一个值
+ 语法: {{ 简单的表达式 }}
+ 在 Vue 的根节点内, 可以直接使用 data 中的成员名称
-->
<p>
<!-- 在 Vue 渲染页面的时候, 会捕获到 data 配置项中的 message 成员 -->
<!-- 把 message 成员的值, 完整替换 {{ message }} -->
{{ message }}
</p>
<p>
{{ count }}
</p>
</div>
<!-- 这里没有办法识别 Vue 的语法 -->
{{ message }}
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的开始
1. 引入一个 js 文件
=> vue.js
2. 通过 Vue 提供的构造函数来创建实例
=> new Vue({})
=> 对象数据类型, 就是对本次实例的所有配置项
*/
// 2. 创建 Vue 实例
const app = new Vue({
// el 属性, 表示关联一个页面上的元素, 需要填写的值是一个选择器
// 因为涉及到帮你渲染页面这个行为, 那么总要有一个标签来接受渲染的所有内容
// 我们管 Vue 实例关联的元素叫做 Vue 的根节点
// 你所有和 Vue 相关的语法, 以及渲染操作, 只有在这个元素内好使
el: '#app',
// data 属性, 表示你需要使用的数据
// 你所有书写在 data 内的成员, 都可以在 Vue 的根节点内直接使用 Vue 语法进行渲染
// 注意: 当你的 data 内的数据改变得时候, 只要你的数据发生变化, Vue 会实时进行页面的从新渲染
data: {
message: 'hello Vue',
count: 1,
arr: [100, 200, 300, 400, 500]
}
})
console.log(app)
/*
vue-tools 工具
+ 是一个浏览器插件
+ 帮助我们快速学习 Vue 的工具
+ 帮我们查看一些内容
*/
</script>
Vue%20%E7%9A%84%E6%96%B9%E6%B3%95%E4%B9%A6%E5%86%99">三、Vue 的方法书写
<div id="app">
<!--
插值表达式可以书写一个简单的表达式
+ 一句话都可以
-->
<p> {{ message }} </p>
<p> {{ reverseStr() }} </p>
<p>
{{ age >= 18 ? '成年' : '未成年' }}
</p>
<!-- 需求: 在这里出现一个 30 ~ 60 之间的随机数字 -->
<p>
{{ randomNum(30, 60) }}
</p>
<!-- 需求: 在这里出现一个 50 ~ 80 之间的随机数字 -->
<p>
{{ randomNum(50, 80) }}
</p>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的方法书写
+ 在 Vue 内, 有的时候需要用到一些函数
+ 我们可以在 data 内书写一个属性, 值是一个函数
=> Vue 不推荐这样书写
=> 因为当你把 函数 和 数据 混合在一起的时候, 不利于后期维护
=> Vue 单独给你开辟了一个配置项, 叫做 methods, 专门用来存储方法的
+ 注意:
=> 在 Vue 的所有函数内
=> this 都是指向当前 Vue 实例
*/
const app = new Vue({
el: '#app',
data: {
message: 'hello vue',
age: 18
},
// methods 配置项就是专门用来书写方法的配置项
methods: {
randomNum: function (a, b) {
// 这里的 this 就是 Vue 实例
// 你想操作的所有数据, 都可以书写 this.xxx 来操作
// 例如 你需要操作 data 内的 message 数据, 就书写 this.message
return Math.floor(Math.random() * (b - a + 1) + a)
},
reverseStr () {
// 专门来操作 data 中的 message 数据的方法
return this.message.split('').reverse().join('')
}
}
})
console.log(app)
</script>
Vue%20%E7%9A%84%E5%86%85%E7%BD%AE%E6%8C%87%E4%BB%A4">四、Vue 的内置指令
1. 渲染
<div id="app">
<p> {{ message }} </p>
<hr>
<!-- Vue 在渲染页面的时候, 会用 innerText 的形式, 把 data 中的 s1 数据的值填充在这个 p 标签内 -->
<p v-text="s1"></p>
<p v-text="s2"></p>
<hr>
<!-- Vue 在渲染页面的时候, 会用 innerHTML 的形式, 把 data 中的 s1 数据的值填充在这个 p 标签内 -->
<p v-html="s1"></p>
<p v-html="s2"></p>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的渲染指令
+ 指令(私人): Vue 自己创建的一些属于元素身上的自定义属性
=> Vue 在渲染页面的时候, 就会捕获这些他自己设置的指令
=> 通过你用不同的指令来进行不同的操作
=> 所有指令的书写形式, 都是以一个属性的形式书写在标签身上
1. v-text
+ 语法: v-text="data中的数据"
+ 意义: 等价于原生 JS 中的 innerText
=> 把 data 中这一条数据当做文本渲染在标签内
2. v-html
+ 语法: v-html="data中的数据"
+ 意义: 等价于原生 JS 中的 innerHTML
=> 把 data 中的这一条数据当做超文本渲染在标签内
*/
new Vue({
el: '#app',
data: {
message: 'hello vue',
s1: '我是一个数据',
s2: '<h1>我也是一个数据</h1>'
}
})
</script>
Vue%20%E7%9A%84%E7%B1%BB%E5%90%8D%E6%B8%B2%E6%9F%93">( 1 ) Vue 的类名渲染
<div id="app">
<p hello="world"></p>
<!--
类名有一定的特殊性
+ 可能有多种值
+ box box2 box3
+ 可以被当做单纯的字符串看待
+ 也可以其中某一个类名动态的
-->
<p class="iconfont icon-play active"></p>
<hr>
<!--
1. 单独渲染一个类名(常用)
+ 就是直接使用 v-bind 指令去绑定属性
解释: 这个 p 元素的 class 的值, 就使用 s1 这个数据的值
-->
<p :class="s1"></p>
<hr>
<!--
2. 对象形式渲染多个类名
+ 使用 v-bind 的指令给 class 绑定一个对象数据类型
+ 注意:
=> 对象的 key 就是你要绑定的类名
=> 对象的 值 需要使用一个布尔值来决定这个类名有或者没有
解释:
+ 把 { active: true, box: true, container: false } 对象绑定给了 p 标签的 class 属性
=> 根据对象中的数据
=> active 值是 true, 表示给 p 标签添加 active 类名
=> box 值是 true, 表示给 p 标签添加 box 类名
=> container 值是 false, 表示不给 p 添加 conatiner 类名
-->
<p :class="obj"></p>
<!--
另一种书写方式(常用)
+ 不在 data 中准备对象了, 而是直接把对象书写在标签身上
+ 在 data 内只是使用 某一个变量 来控制其中的某一个类名
解释: 你在使用这个对象的时候, iconfont 和 icon-play 类名是始终存在的
+ 而 active 类名, 是取决于 data 中 boo 数据是 true 还是 false
-->
<p :class="{ iconfont: true, 'icon-play': true, active: boo }"></p>
<hr>
<!--
3. 以数组的形式绑定多个类名
+ 给 class 属性直接赋值为一个数组
+ 数组内以字符串的形式书写一个一个的类名, 每一个类名都会被直接绑定上
解释:
+ 把 [ 'box', 'box2', 'box3' ] 通过 v-bind 帮顶给 p 标签添加
+ 数组内的每一个值都是 p 标签的一个类名
-->
<p :class="classes"></p>
<!--
及其少见的形式
+ 数组内嵌套多个变量
解释:
+ 把 [ s1, s2, s3 ] 给到了 p 标签的 class 属性
+ 因为数组内写的是三个变量
+ 会从 data 中找到 s1 s2 s3 三个变量的值, 当做类名进行赋值
-->
<p :class="[ s1, s2, s3 ]"></p>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的类名渲染
*/
new Vue({
el: '#app',
data: {
s1: 'active',
s2: 'box',
s3: 'box2',
obj: {
active: true,
box: true,
container: false
},
boo: true,
classes: [ 'box', 'box2', 'box3' ],
}
})
</script>
Vue%20%E7%9A%84%E6%A0%B7%E5%BC%8F%E6%B8%B2%E6%9F%93">( 2 ) Vue 的样式渲染
<div id="app">
<p hello="world"></p>
<!--
style 也有一些特殊性
1. 有可能有多个值
2. 每一个单独的值, 都包含 样式名 和 样式值
+ color: red; font-size: 30px
-->
<p style="color: red; font-size: 30px;"></p>
<hr>
<!--
1. 直接以对象的形式进行绑定
+ 我们在 data 内以对象的形式书写一个样式集
+ 直接把这个对象绑定在元素的 style 属性上
解释:
+ 把 { color: red, font-size: 30px } 对象直接绑定给 p 标签的 style 属性
+ 会把对象中的两个样式直接加上
-->
<p :style="stylies">我是一段文本</p>
<hr>
<!--
2. 以数组的形式进行绑定
+ 可以在数组内书写多个对象
+ 会把每一个对象的样式都绑定上
解释:
+ 把 数组 给到了 p 标签的 style 属性身上
+ 因为数组内书写的是两个变量, 每一个变量都表示一个对象
+ 会把 两个 对象内的数据都渲染上
-->
<p :style="[ stylies, stylies2 ]">我又是一段文本</p>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的样式渲染
*/
new Vue({
el: '#app',
data: {
stylies: {
color: 'red',
'font-size': '30px'
},
stylies2: {
'font-weight': 700,
'background-color': 'skyblue'
}
}
})
</script>
2. 绑定属性
3. 条件渲染
<div id="app">
<p> {{ message }} </p>
<hr>
<!--
当 age >= 18 为 true 的时候, 这个 p 标签有
当 age <= 18 为 false 的时候, 这个 p 标签没有
-->
<!-- <p class="box1" v-if="age >= 18"> 成年人 </p> -->
<hr>
<!-- 下面两个标签只会渲染一个 -->
<!-- <p class="box1" v-if="age >= 18"> 成年人 </p>
<p class="box2" v-else> 未成年人 </p> -->
<hr>
<!--
<p class="box1" v-if="age >= 18"> 大学 </p>
<p class="box2" v-else-if="age >= 15"> 高中 </p>
<p class="box3" v-else-if="age >= 12"> 初中 </p>
<p class="box4" v-else> 小学 </p> -->
<hr>
<p v-if="age >= 18">我用的是 v-if 指令</p>
<p v-show="age >= 18">我用的是 v-show 指令</p>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的内置指令 - 条件渲染
+ if else 语句
1. if 语句
+ 语法: v-if="条件"
+ 意义: 如果条件为 true, 那么这个标签结构渲染出来
=> 如果条件为 false, 那么这个标签结构不渲染
2. if else 语句
+ 语法:
v-if="条件" 书写在一个标签身上
v-else 书写在另一个标签身上
+ 意义:
=> 根据条件的 true 或者是 false
=> 渲染两个标签中的一个
3. if ... else if 语句
+ 语法:
v-if="条件" 书写在一个标签身上
v-else-if="第二个条件" 书写在一个标签身上
v-else-if="第三个条件" 书写在一个标签身上
v-else-if="第四个条件" 书写在一个标签身上
...
+ 意义:
=> 根据条件来决定渲染哪一个标签
+ 注意:
=> 若干个标签只会渲染一个
Vue 的内置指令 - 条件渲染
+ show
1. v-show
+ 语法: v-show="条件"
+ 意义: 根据条件决定该标签显示不显示
=> 不管条件是 true 还是 false, 该标签都会渲染出来
=> 当条件为 true 的时候, 标签是 display: block;
=> 当条件为 false 的时候, 标签是 display: none;
*/
new Vue({
el: '#app',
data: {
message: 'hello Vue',
age: 18
}
})
</script>
4. 循环渲染
<div id="app">
<p>{{ message }}</p>
<hr>
<!--
会根据 arr 这个数组内有多少个成员, 渲染多少个 li 标签
-->
<!-- <ul>
<li v-for="(item, index) in arr">
{{ item }} ----- {{ index }}
</li>
</ul> -->
<!--
会根据 arr 这个数组内有多少个成员, 渲染多少个 li 标签
-->
<!-- <ul>
<li v-for="item in arr">
{{ item }}
</li>
</ul> -->
<hr>
<!-- <ul>
<li v-for="(item, index) in str">
{{ item }} --- {{ index }}
</li>
</ul> -->
<hr>
<!-- <ul>
<li v-for="(item, index) in num">
{{ item }} --- {{ index }}
</li>
</ul> -->
<hr>
<ul>
<li v-for="(val, key, index) in obj">
{{ val }} --- 对象内的每一个值 <br>
{{ key }} --- 对象内的每一个键 <br>
{{ index }} --- Vue 对每一个数据进行了一个编号 <br>
-----------------------------------
</li>
</ul>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的内置指令 - 循环渲染
+ 就是 Vue 把 for 循环这个事情制作了一个指令
+ 在 Vue 里面叫做 万物皆可循环
,
1. 遍历数组
+ 语法: v-for=" (item, index) in 数组 "
+ 意义: 会根据数组有多少项, 把这个标签渲染多少个个
=> 随着循环, item 分别是数组内的每一项数据
=> 随着循环, index 分别是数组内的每一个索引
2. 遍历字符串
+ 语法: v-for=" (item, index) in 字符串 "
+ 意义: 会根据字符串有多少个字符, 把这个标签渲染多少个
=> 随着循环, item 分别是数组内的每一个字符
=> 随着循环, index 分别是数组内的每一个索引
3. 遍历数字
+ 语法: v-for=" (item, index) in 数字 "
+ 意义: 会从 1 开始逐次 +1 向你指定的数字进行遍历
=> 随着循环, item 就是从 1 开始的每一个数字
=> 随着循环, index 分别是每一个数字所表示的索引
4. 遍历对象
+ 语法: v-for=" (val, key, index) in 对象 "
+ 意义: 会根据对象内有多少个成员, 把这个标签循环渲染多少回
=> val 就是对象内每一个 值
=> key 就是对象内每一个 键
=> index 依旧是索引, 就是把每一个数据给了一个编号
*/
new Vue({
el: '#app',
data: {
message: 'hello Vue',
arr: [ 100, 200, 300, 400, 500 ],
str: 'hello world',
num: 5,
obj: {
name: 'Jack',
age: 18,
gender: '男'
}
}
})
</script>
Vue%20%E4%B8%AD%20key%20%E7%9A%84%20%E9%97%AE%E9%A2%98%20%3A">Vue 中 key 的 问题 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table {
width: 550px;
margin: 30px auto;
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<table border="1" cellspacing="0">
<thead>
<tr>
<th>选中</th>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<!--
只要根据数组把 tr 标签循环渲染就可以了
+ 根据 users 内有多少个 对象, 渲染多少个 tr
+ 用什么指令: v-for
+ 指令写在哪一个标签身上: tr
-->
<!--
解决 diff 算法出现的问题
+ 以 动态绑定 属性的方式, 绑定一个 key
+ 尽量使用数据唯一值, 会把每一个元素标签锁定上数据唯一值
-->
<tr v-for="(item, index) in users" :key="item.id">
<!--
item 就是 users 内的每一个对象
需要把对象内的数据渲染在指定标签身上
-->
<td>
<input type="checkbox" :checked="item.is_select">
</td>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.gender }}</td>
<td>{{ item.age }}</td>
<td>
<button>编辑</button>
<button>删除</button>
</td>
</tr>
</tbody>
</table>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 中 key 的问题
*/
// 准备一条数据
const arr = [
{ id: 1, name: 'Jack', age: 18, is_select: true, gender: '男' },
{ id: 2, name: 'Rose', age: 20, is_select: false, gender: '女' },
{ id: 3, name: 'Tom', age: 22, is_select: true, gender: '男' }
]
const app = new Vue({
el: '#app',
data: {
users: arr
}
})
/*
key 的作用
问题:
+ 当我的数组渲染好以后
+ 我做了一些操作, 然后发现修改的内容和我预想的不一样
+ 将来我渲染的表格某些操作不能做了
原因:
+ 因为 Vue 在渲染页面的时候
+ 每一次修改, 其实都是从新渲染页面
+ 在渲染的时候, 有一个自己的 diff 算法
=> 为了节约性能, 会按照最少的改变去操作
解决:
+ 给标签身上加上唯一值
+ 在 Vue 里面提供了一个 key 的属性来作为唯一值绑定
+ 有了唯一值, 就不会按照最小的变化, 而是按照不变的来操作
+ 注意: key 绝对不能使用数组的索引, 必须要使用数据唯一值, 基本上都是 id
结论:
+ 只要有 v-for 必写 :key
*/
</script>
</body>
</html>
5. 绑定事件
<div id="app">
<p>{{ message }}</p>
<hr>
<!-- 我想给这个按钮绑定一个点击事件 -->
<!--
通过 v-on 指令给 button 元素绑定了一个 click 事件
+ 使用的 事件处理函数
+ 是 methods 中的 clickHandler 函数
当你点击 button 按钮的时候
+ 就会触发 methods 中的 clickHanlder 函数
-->
<button v-on:click="clickHandler">按钮</button>
<hr>
<!--
简单的小案例 : 计数器
-->
<!-- 需要一个点击事件 -->
<button v-on:click="subHandler">-</button>
<!-- span 内的数据, 必须要使用一个 data 中的成员 -->
<!-- 只有这样才能保证数据变化的时候, 内容跟随变化 -->
<span>{{ count }}</span>
<!-- 需要一个点击事件 -->
<button v-on:click="addHandler">+</button>
<br>
<!-- 把 v-on: 换成 @ -->
<button @click="subHandler">-</button>
<span>{{ count }}</span>
<button @click="addHandler">+</button>
<hr>
<!--
在绑定一个键盘事件的基础上, 做了一个额外的限定, 只有键盘按下, 并且按下的是 回车键 的时候
+ 才会触发 事件处理函数
-->
<input type="text" @keydown.enter="downHandler">
<br>
<!--
esc 内应该做一个什么样的操作合理
如何实现重置
+ 把这个 input 的 value 设置为 空字符串
如何把这个 input 的 value 设置为 空字符串
+ ( 一定要往数据驱动视图这方面去考虑解决方案 )
-->
<!-- 只要 data 中的 str 变化, 这个 input 的 value 就变化了 -->
<input type="text" @keydown.esc="escHandler" :value="str">
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的 内置指令 之 绑定事件
1. v-on
+ 语法: v-on:事件类型="需要用到的事件处理函数"
+ 注意: 只要是在 Vue 内, 所有的 this 都是 当前实例
=> 既然是 Vue 的实例
=> 那么可以直接在事件处理函数内进行 data 中数据的操作
+ 简写形式
=> v-on: 可以简写为 @
=> 你书写 @click 就等价于 v-on:click
2. 事件的绑定的 操作符
+ Vue 提供了对于键盘事件的 操作符
+ 可以直接锁定某些按键
=> 直接连接在事件类型后面书写
=> .enter 的连接符, 表示按下 回车键
*/
new Vue({
el: '#app',
data: {
message: 'hello Vue',
count: 1,
str: 'hello world'
},
methods: {
clickHandler () {
console.log('我是一个事件处理函数')
console.log(this)
},
subHandler () {
// 减号点击的事件
// 需要操作 data 中的 count 进行数量的减少
// 因为是 methods 内的函数, 所以 this 一定是指向当前 Vue 实例
// 我们直接通过 this.count 来操作
this.count--
},
addHandler () {
// 加号点击事件
this.count++
},
downHandler () {
console.log('键盘按下')
},
escHandler () {
console.log('esc 按下了')
// 当我把 str 设置为 空 的时候
// 会瞬间影响页面变化, input 就变成了 空内容
this.str = ''
}
}
})
</script>
6. 双向数据绑定
<div id="app">
<!--
v-bind 是一个 单向绑定
+ 只是把 data 中的数据, 渲染在页面上
-->
<!--
需求:
+ 需要把用户填写的内容放在 data 中的 username 属性上
+ 随着用户输入, 随时修改
-->
<!-- <input type="text" :value="username" @input="handler"> -->
<input type="text" v-model="username">
<!-- 使用双向数据绑定 -->
<!--
解释:
把 data 内的 password 属性的值, 直接赋值给这个 input 的 value 属性
当 这个 input 的 value 属性修改的时候, 会直接修改 data 中 password 属性的值
-->
<input type="text" v-model="password">
<button @click="login">登录</button>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 的内置指令 - 双向数据绑定
+ Vue 提供给我们了一个 v-model 的指令
+ 这个指令包含了两个内容
1. v-bind:value
2. v-on:input=function () { 设置 data 内的值 }
*/
new Vue({
el: '#app',
data: {
username: '',
password: ''
},
methods: {
handler (e) {
// 1. 拿到用户输入的内容
// 获取元素, 获取 value
// 通过事件对象, 拿到 value 值
console.log(e.target.value) // 用户输入的内容
// 2. 给 data 中的 username 进行赋值
this.username = e.target.value
},
login () {
// 进行提交操作
console.log('我要发送一个 ajax 请求给到后端')
console.log('携带的参数有两个, ', this.username , this.password)
}
}
})
</script>
Vue%20%E6%A1%88%E4%BE%8B%20-%20%E5%8A%A8%E6%80%81%E8%A1%A8%E6%A0%BC%20%3A">Vue 案例 - 动态表格 :
<div id="app">
<form>
<label>
姓名: <input type="text" v-model="info.name">
</label>
<label>
性别: <input type="text" v-model="info.gender">
</label>
<label>
年龄: <input type="text" v-model="info.age">
</label>
<button type="button" @click="addHandler">添加</button>
</form>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in users" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.gender }}</td>
<td>{{ item.age }}</td>
<td>
<button @click="showEdit(item.id)">编辑</button>
<button @click="delHandler(item.id)">删除</button>
</td>
</tr>
</tbody>
</table>
<div :class="{ dialog: true, active: isShow }">
<!-- 点击关闭按钮取消编辑 -->
<span @click="cancelEdit">X</span>
<form>
<label>
id: <input disabled type="text" v-model="update.id">
</label>
<label>
姓名: <input type="text" v-model="update.name">
</label>
<label>
性别: <input type="text" v-model="update.gender">
</label>
<label>
年龄: <input type="text" v-model="update.age">
</label>
<button type="button" @click="edit">确认编辑</button>
</form>
</div>
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 案例 - 动态表格
*/
const users = [
{ id: 1, name: 'Jack', age: 18, gender: '男' },
{ id: 2, name: 'Rose', age: 20, gender: '女' },
{ id: 3, name: 'Tom', age: 22, gender: '男' }
]
new Vue({
el: '#app',
data: {
// 准备渲染页面的数据
users,
// 准备一个数据是和 添加 文本框进行双向数据绑定
info: {},
// 准备一个数据是和 编辑 文本框进行双向数据绑定
update: {},
// 准备一个数据, 表示 dialog 对话框显示和隐藏
isShow: false
},
methods: {
delHandler (id) {
this.users = this.users.filter(item => item.id !== id)
},
addHandler () {
this.info.id = this.users[this.users.length - 1].id + 1
this.users.push(this.info)
this.info = {}
},
showEdit (id) {
const result = this.users.find(item => item.id === id)
this.update = { ...result }
this.isShow = true
},
cancelEdit () {
this.isShow = false
},
edit () {
const result = this.users.find(item => item.id === this.update.id)
result.name = this.update.name
result.gender = this.update.gender
result.age = this.update.age
this.isShow = false
}
}
})
</script>
详解 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue_案例-动态表格</title>
<style>
table {
width: 550px;
margin: 30px auto;
text-align: center;
}
form {
width: 500px;
display: flex;
flex-direction: column;
margin: 0 auto;
}
.dialog {
width: 500px;
padding: 20px;
background-color: #fff;
border: 2px solid #ccc;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
height: 120px;
display: none;
}
.dialog.active {
display: block;
}
.dialog > span {
position: absolute;
right: 15px;
top: 15px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<form>
<label>
姓名: <input type="text" v-model="info.name">
</label>
<label>
性别: <input type="text" v-model="info.gender">
</label>
<label>
年龄: <input type="text" v-model="info.age">
</label>
<button type="button" @click="addHandler">添加</button>
</form>
<table border="1" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in users" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.gender }}</td>
<td>{{ item.age }}</td>
<td>
<!--
问题: 确认编辑, 还是进入编辑状态
-->
<button @click="showEdit(item.id)">编辑</button>
<!-- 每一个 tr 内的 button 删除按钮都需要有一个点击事件 -->
<!--
当我删除的时候, 需要知道你要删除的这一条数据的 id
在渲染页面的时候, 把 id 给渲染进去
-->
<button @click="delHandler(item.id)">删除</button>
</td>
</tr>
</tbody>
</table>
<!--
进入编辑状态, 就是让他显示出来
+ 怎么显示出来, 添加 active 类名
+ dialog 类名是始终存在的,
+ active 有时候有, 有时候没有
-->
<div :class="{ dialog: true, active: isShow }">
<!-- 点击关闭按钮取消编辑 -->
<span @click="cancelEdit">X</span>
<form>
<label>
id: <input disabled type="text" v-model="update.id">
</label>
<label>
姓名: <input type="text" v-model="update.name">
</label>
<label>
性别: <input type="text" v-model="update.gender">
</label>
<label>
年龄: <input type="text" v-model="update.age">
</label>
<button type="button" @click="edit">确认编辑</button>
</form>
</div>
<!--
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.gender }}</td>
<td>{{ item.age }}</td>
<td>
<button>编辑</button>
<button @click="delHandler(1)">删除</button>
</td>
</tr>
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.gender }}</td>
<td>{{ item.age }}</td>
<td>
<button>编辑</button>
<button @click="delHandler(2)">删除</button>
</td>
</tr>
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.gender }}</td>
<td>{{ item.age }}</td>
<td>
<button>编辑</button>
<button @click="delHandler(3)">删除</button>
</td>
</tr>
-->
</div>
<script src="./vue/vue.js"></script>
<script>
/*
Vue 案例 - 动态表格
*/
const users = [
{ id: 1, name: 'Jack', age: 18, gender: '男' },
{ id: 2, name: 'Rose', age: 20, gender: '女' },
{ id: 3, name: 'Tom', age: 22, gender: '男' }
]
new Vue({
el: '#app',
data: {
users,
// 因为将来我需要向数组中添加一个对象数据类型
// 直接使用对象来采集用户信息
info: {},
update: {},
// 控制编辑框是否显示
isShow: false
},
methods: {
delHandler (id) {
// 需要删除数组中的某一项
// 注意: 你只要能把数组中对应的某一个删除掉, 页面会自动更新的
// 问题: 删除数组中的哪一个 ?
// console.log('删除点击事件')
// console.log(`删除数组中 id 为 ${ id } 的数据`)
// filter()
// item 表示数组中的每一项
// return 的形式书写筛选条件
// 从 this.users 数组中, 筛选出所有 id 和 我接收到的 id 不一样的项
// const result = this.users.filter(function (item) { return item.id !== id })
// console.log(id, result)
this.users = this.users.filter(item => item.id !== id)
},
addHandler () {
// 直接使用 this.info 这个信息
// console.log(this.info)
// 1. 补一个 id 属性
this.info.id = this.users[this.users.length - 1].id + 1
// 2. 把我们的 info 插入到数组内
this.users.push(this.info)
// 3. 选做: 清空文本框
this.info = {}
},
showEdit (id) {
// 进入编辑状态
// 把本条信息渲染在 dialog 内的表单内
// 如何找到对应的信息
// 我们有了 id, 只要从 this.users 内找到一个 id 一样
const result = this.users.find(item => item.id === id)
// 如何渲染
// dialog 的所有文本框 双向数据绑定 关联着 data 内的 update 对象
// 只要我给 update 内的 name 赋值, 那么 name 文本框就有内容了
this.update = { ...result }
/*
假设 result 就是 this.user[0]
根据 vue 的规则, 只要 this.users[0] 的数据修改了, 页面就变
result 和 this.users[0] 存储的是同一个对象的地址, result 改变, this.users[0] 就会变
最好是把 result 复制一份给到 this.update
*/
// 让 dialog 显示
// 只要把 data 中的 isShow 设置为 true 就可以了
this.isShow = true
},
cancelEdit () {
// 直接关闭 dialog 对话框就可以了
this.isShow = false
},
edit () {
// 就是把 update 的内容在从新赋值回到 this.users 中的某一个内
// console.log(this.update)
// 1. 找到 this.users 内 id 一样的那一条数据
let result = this.users.find(item => item.id === this.update.id)
// 2. 进行替换操作
result.name = this.update.name
result.age = this.update.age
result.gender = this.update.gender
// 3. 关闭 dialog 对话框
this.isShow = false
}
}
})
// const o1 = { name: 'Jack' }
// const o2 = {
// ...o1
// }
// console.log(o1, o2)
// o2.name = 'Rose'
// console.log(o1, o2)
// const arr = [ { id: 1, name: 'Jack' } ]
// let result = arr[0]
// let update = { id: 1, name: '张三' }
// console.log(arr[0], result, update)
// result = update
// console.log(arr[0], result, update)
</script>
</body>
</html>
跳转链接 => Vue _ 舒适版 02
跳转链接 => Vue _ 舒适版 03
跳转链接 => Vue _ 舒适版 04