构建用户界面:
用 vue 往 html 页面中填充数据,非常方便
框架:
1.框架是一套现成的解决方案,程序员只能遵守框架的规范,去编写自己的业务功能。
2.要学习 vue,就是在学习 Vue 框架中的用法。
3.vue 的指令、组件(是对 UI 结构的复用)、路由、Vuex、vue组件库。
4.只有掌握上面的内容后,才有开发 vue 项目的能力。
数据驱动视图,意为数据的变化会驱动视图更新。
好处:程序员只管把数据维护好,页面结构会自己被 vue 自动渲染出来。
在网页中,form表单负责采集数据,Ajax负责提交数据。
js数据的变化,会被自动渲染到页面上
页面上表单采集的数据发生变化的时候,会被vue自动获取到,并更新到js数据中
el 属性是固定写法。data 对象是要渲染到页面上的数据。
Chrome浏览器在线安装vue-devtools
FireFox浏览器在线安装vue-devtools
本章很重要
v-text 的缺点是:
会覆盖元素内默认的值,有时候无法满足我们的需求,比如姓名: 名字
,我们希望名字可以修改但是姓名不会变化,这时候 v-text 是无法实现的。
这个语法(专业名称叫插值表达式
)可以解决我们上面说到的问题。
插值表达式在实际开发中用的最多
,只是内容的占位符,不会覆盖原有的内容
插值表达式只能用在元素的内容节点上,不能用在元素的属性节点中。
我们现在有一个需求,就是给输入框的 placeholder 属性添加动态属性值,这里需要用到属性绑定指令
测试:(需求是如果count为偶数,则按钮背景变成红色,否则取消背景颜色。)
1.普通写法
2. 使用 $event,不仅要实现变色功能,还要能自由控制每次增加的数值
<body>
<div id="app">
<input type="text" @keyup.esc="clearInput">
<input type="text" @keyup.enter="commitAjax">
div>
<script src="./lib/vue-2.6.12.js">script>
<script>
const vm = new Vue({
el: '#app',
data: {
},
methods: {
clearInput(e) {
// 清空输入框的内容
e.target.value = ''
},
commitAjax() {
alert('触发了提交按键enter')
}
}
})
script>
body>
.lazy 修饰符
效果:让输入框的内容确定之后(回车或者点击)再进行变化,而不是一直跟着输入框内容随时变化,意思就是它只关心最后结果,不关注变化过程。
面试可能会问到
如果刚进入页面时,某些元素不需要被展示,而且后期这个元素很可能也不需要被展示出来,此时 v-if
的性能更好。
如果要频繁切换元素的显示状态,用 v-show
性能会更好。
推荐大家安装的 VScode 中的 Vue 插件:
vue3-snippets
Vetur
<body>
<div id="app">
<table class="table table-bordered table-hover table-striped">
<thead>
<th>索引th>
<th>Idth>
<th>姓名th>
thead>
<tbody>
<tr v-for="(item, index) in list" :title="item.name">
<td>{{ index }}td>
<td>{{ item.id }}td>
<td>{{ item.name }}td>
tr>
tbody>
table>
div>
<script src="./lib/vue-2.6.12.js">script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: 'theshy' },
{ id: 2, name: 'ning' },
{ id: 3, name: 'rookie' },
]
}
})
script>
body>
官方建议:只要用到了 v-for 指令,那么一定要绑定一个 :key 属性,而且尽量把 id 作为 key 值。
vue3 中是没有过滤器,所以我们现在学的过滤器只能在 vue2 中使用。
| 表示要调用过滤器
<body>
<div id="app">
<p>message 的值是: {{ message | capi }}p>
div>
<div id="app2">
<p>message 的值是: {{ message | capi }}p>
div>
<script src="./lib/vue-2.6.12.js">script>
<script>
// 使用 Vue。filter() 定义全局过滤器
Vue.filter('capi', function(str) {
const first = str.charAt(0).toUpperCase()
const other = str.slice(1)
return first + other
})
const vm = new Vue({
el: '#app',
data: {
message: 'hello vue.js'
},
// 过滤器函数,必须被定义到 filters 节点之下
// 过滤器本质上是函数
filters: {
// 形参val 指的就是 管道符| 前面的值
capi(val) {
// .toUpperCase() 可以使字符串变成大写
console.log(val.toUpperCase())
// 强调:过滤器中,一定要有一个返回值
return val.toUpperCase()
}
}
})
const vm2 = new Vue({
el: '#app2',
data: {
message: 'ts'
}
})
script>
body>
如果全局过滤器和私有过滤器名字一致,此时按照“就近原则”,调用的是私有过滤器
。
我们本篇博客的品牌列表案例中,时间那一栏需要优化一下更加美观。
我们需要使用一个叫 dayjs
的包,用来格式化时间的。
dayjs 的参考文档
双括号里支持 js 语法,但是只能写简单的 js 表达式,不能写 if 这样的复杂语句。
for 属性可以指代 id,这样的话我们点击男
这个字也会触发 id 为 cb1 的 input,
而下面的 cb2 只能通过点击选框进行选中,用户体验不好。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>品牌列表案例title>
<link rel="stylesheet" href="./lib/bootstrap.css">
<link rel="stylesheet" href="./css/brandlist.css">
head>
<body>
<div id="app">
<div class="card">
<div class="card-header">
添加品牌
div>
<div class="card-body">
<form @submit.prevent="add">
<div class="form-row align-items-center">
<div class="col-auto">
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">品牌名称div>
div>
<input type="text" class="form-control" placeholder="请输入品牌名称" v-model.trim="brand">
div>
div>
<div class="col-auto">
<button type="submit" class="btn btn-primary mb-2">添加button>
div>
div>
form>
div>
div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th scope="col">#th>
<th scope="col">品牌名称th>
<th scope="col">状态th>
<th scope="col">创建时间th>
<th scope="col">操作th>
tr>
thead>
<tbody>
<tr v-for="item in list" :title="item.name" :key="item.id">
<td>{{ item.id }}td>
<td>{{ item.name }}td>
<td>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" :id=" 'cb' + item.id " v-model="item.status">
<label class="custom-control-label" :for=" 'cb' + item.id " v-if="item.status">已启用label>
<label class="custom-control-label" :for=" 'cb' + item.id " v-else>已禁用label>
div>
td>
<td>{{ item.time }}td>
<td>
<a href="javascript:;" @click="del(item.id)">删除a>
td>
tr>
tbody>
table>
div>
<script src="./lib/vue-2.6.12.js">script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: '宝马', status: true, time: new Date() },
{ id: 2, name: '奔驰', status: false, time: new Date() },
{ id: 3, name: '奥迪', status: true, time: new Date() }
],
// 用户输入的品牌名称
brand: '',
// nextId 是下一个 可用的 id
nextId: 4
},
methods: {
// 定义删除操作
del(id) {
this.list = this.list.filter(item => item.id !== id)
},
// 定义添加功能
add() {
// 如果判断 brand 的字符串为空,则 return 出去
if(this.brand === '') return alert('必须填写有效内容')
// 如果字符串不为空,应该执行添加的逻辑
// 1. 先把要添加的品牌对象整理出来
const obj = {
id: this.nextId,
name: this.brand,
status: true,
time: new Date()
}
// 2. 往 this.list 数组中 push 步骤1 中得到的对象
this.list.push(obj)
// 3. 清空 this.brand 同时让 this.nextId 自增 +1
this.brand = ''
this.nextId++
}
},
})
script>
body>
html>