网站首页 > 博客文章 正文
学习大纲
表单输入绑定
思考:之前写项目如何获取表单中的数据
回答:步骤1给搜索框增加id属性,步骤2通过选择器获取里面的内容
现在:要告诉大家一个更简单的方法
专业术语:数据双向绑定
简介&语法
- 单向绑定:M 自动同步 V
- 双向绑定:M 自动同步 V && V 自动同步 M
- 语法:v-model="data中的键" (仅支持input/textarea/select)
练习
- 单向绑定:模型放msg和url属性 同步到视图
- 双向绑定:input框修改查看模型数据变化
- 其他:textarea、checkbox、radio练习
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>单向绑定</h1>
<div>{{msg}}</div>
<div>{{url}}</div>
<a :href="url">点我</a>
<h1>双向绑定(仅支持input/textarea/select)</h1>
<input type="text" v-model="msg" />
<h1>其他:textarea、checkbox、radio练习</h1>
<textarea cols="30" rows="10" v-model="textareaContent"></textarea>
<b>{{textareaContent}}</b>
<hr />
兴趣爱好(兴趣爱好多个值 用数组):
<input type="checkbox" value="玩小黄鸭" v-model="checkboxContent"/> 玩球
<input type="checkbox" value="篮球" v-model="checkboxContent" /> 篮球
<input type="checkbox" value="足球" v-model="checkboxContent" /> 足球
<input type="checkbox" value="挤痘痘" v-model="checkboxContent" /> 挤痘痘
<input type="checkbox" value="臭脚" v-model="checkboxContent" /> 臭脚
<br />
{{checkboxContent}}
<hr />
性别:
<input type="radio" name="sex" value="男" v-model="radioContent" > 男
<input type="radio" name="sex" value="女" v-model="radioContent"> 女
<input type="radio" name="sex" value="特殊群体" v-model="radioContent"> 特殊群体
<br />
{{radioContent}}
<br />
<br />
<br />
<br />
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// - 单向绑定:模型放msg和url属性 同步到视图
// - 双向绑定:input框修改查看模型数据变化
// - 其他:textarea、checkbox、radio练习
let vm = new Vue({
el: '#app',
data: {
msg: "测试数据",
url: "http://qf.com",
textareaContent: "测试数据",
checkboxContent: [], //切记切记切记 checkbox多个值 必须是数组
radioContent: "特殊群体"
}
})
</script>
</body>
</html>
小总结
双向绑定:可以讲模型数据同步到视图,并且视图数据可以同步到模型的表现
语法:v-model=“data中的键” (仅针对input/textarea/select)
脚下留心:针对input:checkbox 模型中必须是数组,其他都是字符串
实战:购物车案例&修饰符
- 需求
步骤1:赋值下述代码&遍历显示模型数据 (数据在模型的carts中)
步骤2:勾选商品显示数据 (勾选的数据放到chooseCarts:[]中)
步骤3:添加数据+1 (触发addCartFn方法,模型carts数据+1)
步骤4:统计 (封装totalFn方法)
步骤5:全选&全不选 (封装chooseCartsFn方法)
步骤6:细节优化(input框单击同步、input框输入同步,input框只能输入数字)
- 需求代码
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>购物车</h1>
<input type="checkbox" /> 全选&全不选
<hr />
<ul>
<li >
<input type="checkbox" value="" />
标题:,
价格:,
数量:
<input type="text" size="1" />
<input type="button" value="+" />
</li>
</ul>
<hr /><hr />
<h2>勾选商品</h2>
<h2>总数量:,总价:</h2>
</div>
<script>
new Vue({
el: '#app',
data: {
//购物车商品
carts: [
{title:'商品1', price: 1, number: 1},
{title:'商品2', price: 2, number: 1},
{title:'商品3', price: 3, number: 1}
]
},
//声明普通方法
methods: {
}
})
</script>
</body>
</html>
- 完成代码
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>购物车</h1>
<input type="checkbox" @click="chooseCartsFn"/> 全选&全不选
<hr />
<ul>
<li v-for="(cart,index) in carts">
<!-- 加下留心:逻辑上加点击事件,但是这边被vue封装了 所以改成change事件 -->
<input type="checkbox" :value="cart" v-model="chooseCarts" @change="totalFn" />
标题:{{cart.title}},
价格:{{cart.price}},
数量:{{cart.number}}
<!-- <input type="text" :value="cart.number" size="1" /> -->
<input type="text" v-model.number="cart.number" size="1" @keyup="totalFn" />
<input type="button" value="+" @click="addCartFn(index)"/>
</li>
</ul>
<hr /><hr />
<h2>勾选商品</h2>
{{chooseCarts}}
<h2>总数量:{{totalNum}},总价:{{totalPrice}}</h2>
</div>
<script>
// 步骤1:赋值下述代码&遍历显示模型数据 (数据在模型的carts中)
// 步骤2:勾选商品显示数据 (勾选的数据放到chooseCarts:[]中)
// 步骤3:添加数据+1 (触发addCartFn方法,模型carts数据+1)
// 步骤4:统计 (封装totalFn方法)
// 步骤5:全放&全不选 (封装chooseCartsFn方法)
// 步骤6:细节优化(input框单击同步、input框输入同步,input框只能输入数字)
new Vue({
el: '#app',
data: {
// 存放勾选商品
chooseCarts: [],
//购物车商品
carts: [
{title:'商品1', price: 1, number: 1},
{title:'商品2', price: 2, number: 1},
{title:'商品3', price: 3, number: 1}
],
// 总的购买数量和购买价格
totalPrice: 0,
totalNum: 0
},
//声明普通方法
methods: {
chooseCartsFn() {
// 假设 chooseCarts 长度 没有3个 也就是没有全部都打钩
// 就 全部够
// 否则 全部不够
if (this.chooseCarts.length == 3)
{
this.chooseCarts = []
} else {
this.chooseCarts = this.carts
}
// 调用模型:this.data中的键
// 调用方法:this.方法名()
// this就是vm这个对象
this.totalFn()
},
addCartFn(index) {// index指当前操作的购物车商品
// this.carts 获取模型数据
this.carts[index].number += 1
},
totalFn() {
// 声明临时变量存放数据
let tmpTotalNum = 0
let tmpTotalPrice = 0
// 遍历选择的商品 进行统计
for (let i = 0; i < this.chooseCarts.length; i++)
{
tmpTotalNum += this.chooseCarts[i].number
tmpTotalPrice += this.chooseCarts[i].number *
this.chooseCarts[i].price
}
// 修改模型数据
this.totalNum = tmpTotalNum
this.totalPrice = tmpTotalPrice
}
}
})
</script>
</body>
</html>
Class与Style绑定
class="left header"
class="data中的键 有时候还有放多个data中的键"
注:怎么放?可不是简单的加空格
思考:标签的class和style属性 一定是固定的 没有情况需要放模型数据吗?
回答:肯定有
解决:通过手册Class与Style绑定 就是给class和style属性值 改成data中的键
语法
class使用模型数据
单个【直接写字符串】
多个-数组【数组中的每个值就是要显示的class】
多个-对象【键就是要显示的class,值来控制是否展示bool】
style使用模型数据
多个-对象【键是css属性名,值是css属性值】
多个-数组【上面一个个对象】
练习
- 需求:给class和Style绑定模型数据
- 需求代码
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.bgRed {background: red;}
.bgBlue {background: blue;}
.bgGreen {background: green;}
.fontRed {color: red;}
.fontBlue {color: blue;}
.fontGreen {color: green;}
</style>
</head>
<body>
<div id="app">
<!-- bgRed -->
<h1>class绑定模型数据(字符串语法)</h1>
<!-- bgBlue显示该类/fontRed不现实该类 -->
<h1>class绑定模型数据(对象语法) </h1>
<h1>class绑定模型数据(数组语法)</h1>
<!-- bgGreen/fontRed -->
<!-- 背景红色/字体20px -->
<h1>style绑定模型数据(对象语法)</h1>
<h1>style绑定模型数据(数组语法)</h1>
<!-- 背景黄色 -->
</div>
</body>
</html>
- 完成代码
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.bgRed {background: red;}
.bgBlue {background: blue;}
.bgGreen {background: green;}
.fontRed {color: red;}
.fontBlue {color: blue;}
.fontGreen {color: green;}
</style>
</head>
<body>
<div id="app">
<!--
bgRed
传统
<h1 class="bgRed">class绑定模型数据(字符串语法)</h1>
但是:现在我想讲bgRed这个类 变成模型中的键
通过:动态参数 v-bind 但是我们简写 :
-->
<h1 v-bind:class="classString">class绑定模型数据(字符串语法)</h1>
<!-- bgBlue显示该类/fontRed不现实该类 -->
<h1 v-bind:class="classObj">class绑定模型数据(对象语法) </h1>
<h1 v-bind:class="classArr">class绑定模型数据(数组语法)</h1>
<!-- bgGreen/fontRed -->
<!-- 背景红色/字体20px -->
<h1 v-bind:style="styleObj">style绑定模型数据(对象语法)</h1>
<h1 v-bind:style="styleArr">style绑定模型数据(数组语法)</h1>
<!-- 背景黄色 -->
</div>
<script>
new Vue({
el: "#app",
data: {
classString: "bgRed",
classObj: {"bgBlue":true, "fontRed": true},
classArr: ["bgGreen", "fontRed"],
styleObj: {"background": "red", "font-size": "20px"},
styleArr: [
{"background": "yellow"},
{"color": "green"}
]
}
})
</script>
</body>
</html>
小总结
class
一个类 【模型中直接写字符串】
多个类-对象 【对象的键-就是类名,对象的值-布尔型控制类名是否显示】
多个类-数组 【数组中的值就是要显示的类名】
style
对象 【对象的键-就是CSS属性名,对象的值-就是CSS属性值】
数组 【数组中值-是一个个对象,每个对象由 CSS属性名:CSS属性值
四、ToDoList案例
完成下述案例
步骤1:循环显示模型数据
步骤2:添加数据放到模型中
步骤3:点击删除 移除模型数据
静态效果地址:https://github.com/webopenfather/ToDoList
步骤1:循环显示模型数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
</head>
<style type="text/css">
ul li { list-style: none; }
.main { width: 100%; display: flex; align-items: center; justify-content: center; margin: 15px 0px;}
.cc { float: right; }
td { display: flex; align-items: center; justify-content: space-between; padding: 5px 20px !important; }
</style>
<body>
<div class="container" id="app">
<h1 style="text-align: center;">ToDoList</h1>
<div class="main">
<div class="left">
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入内容" />
</div>
<div class="right">
<!-- 添加 -->
<button type="button" class="btn btn-primary">添加</button>
</div>
</div>
<table class="table table-condensed">
<tr>
<td class="active" v-for="todo in todos">
{{todo.title}}
<button type="submit" class="btn btn-default cc">
删除
</button>
</td>
</tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
todos: [
{title: "吃饭"},
{title: "睡觉"},
{title: "欺负钱某"}
]
}
})
</script>
</body>
</html>
步骤2:添加数据放到模型中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
</head>
<style type="text/css">
ul li { list-style: none; }
.main { width: 100%; display: flex; align-items: center; justify-content: center; margin: 15px 0px;}
.cc { float: right; }
td { display: flex; align-items: center; justify-content: space-between; padding: 5px 20px !important; }
</style>
<body>
<div class="container" id="app">
<h1 style="text-align: center;">ToDoList</h1>
<div class="main">
<div class="left">
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入内容" v-model="content" />
</div>
<div class="right">
<!-- 添加 -->
<button type="button" class="btn btn-primary" @click="add">添加</button>
</div>
</div>
<table class="table table-condensed">
<tr>
<td class="active" v-for="todo in todos">
{{todo.title}}
<button type="submit" class="btn btn-default cc">
删除
</button>
</td>
</tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
todos: [
{title: "吃饭"},
{title: "睡觉"},
{title: "欺负钱某"}
],
// todo内容
content: ""
},
// 声明普通方法
methods: {
add() {
// 这里面应该给模型todos增加数据
// this.todos.push({
// title: "所x"
// })
// 发现:上述代码写死了
// 传统:1-加id或class,2-获取
// 现在:1-双向绑定同步到模型中,2-哪里需要直接操作模型
this.todos.push({
title: this.content
})
// 清空模型
this.content = ""
}
}
})
</script>
</body>
</html>
步骤3:点击删除移除模型数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
</head>
<style type="text/css">
ul li { list-style: none; }
.main { width: 100%; display: flex; align-items: center; justify-content: center; margin: 15px 0px;}
.cc { float: right; }
td { display: flex; align-items: center; justify-content: space-between; padding: 5px 20px !important; }
</style>
<body>
<div class="container" id="app">
<h1 style="text-align: center;">ToDoList</h1>
<div class="main">
<div class="left">
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入内容" v-model="content" />
</div>
<div class="right">
<!-- 添加 -->
<button type="button" class="btn btn-primary" @click="add">添加</button>
</div>
</div>
<table class="table table-condensed">
<tr>
<td class="active" v-for="(todo, index) in todos">
{{todo.title}}
<button type="submit" class="btn btn-default cc" @click="del(index)">
删除
</button>
</td>
</tr>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
todos: [
{title: "吃饭"},
{title: "睡觉"},
{title: "欺负钱某"}
],
// todo内容
content: ""
},
// 声明普通方法
methods: {
del(index) {
// alert(111)
// 实战:传递ID 异步请求 删除
// 现在:数据是固定在模型中的 不用请求接口 直接从模型中移除一条数据
//
// 作用:从数组中删除一个元素
// 语法:数组.splice(从第几个开始删 下标, 删的个数)
this.todos.splice(index,1)
},
add() {
// 这里面应该给模型todos增加数据
// this.todos.push({
// title: "所x"
// })
// 发现:上述代码写死了
// 传统:1-加id或class,2-获取
// 现在:1-双向绑定同步到模型中,2-哪里需要直接操作模型
this.todos.push({
title: this.content
})
// 清空模型
this.content = ""
}
}
})
</script>
</body>
</html>
#五、axios 与 fetch 实现数据请求
明确需求
思考:在vue中如何发送异步请求获取数据
回答:传统(ajax、jq $.ajax) 现在(axios、fetch)
axios简介&语法
Axios[?k'si:??]是一个用JS写的HTTP库(配合vue使用从而获取接口数据)
基于ajax和promise封装的
-----------------------------------
- 手 册:https://www.kancloud.cn/yunye/axios/234845
- 库地址:https://cdn.bootcss.com/axios/0.18.0/axios.js
- GET请求/POST请求
axios({
url
method
data
headers
}).then().catch()
###GET
axios({
method:"get"
//方案1
//url:"http://118.31.9.103/请求路径?参数1=值1&....&参数n=值n",
//方案2(推荐)
url:"http://118.31.9.103/请求路径",
params: {键:值,...,键n:值n}
}).then(res => {
}).catch(error=>{
console.log(error)
})
###POST
axios({
url:"http://118.31.9.103/请求路径",
method:"post",
data:"参数1=值1&....&参数n=值n"
}).then(res => {
}).catch(error=>{
console.log(error)
})
多学一招
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
axios练习
- 需求1:在day2目录下创建data.json接口文件
{
"meta": {
"msg": "提示信息",
"status": 200
},
"data": [
{"id": 1, "title": "test1"},
{"id": 2, "title": "test2"},
{"id": 3, "title": "test3"},
{"id": 4, "title": "test4"}
]
}
- 需求2:通过axios请求data.json本地文件
- 需求3:通过axios请求线上“卖座电影正在热映”
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>本地请求</h1>
<button @click="fn1">点击请求</button>
<h1>线上请求</h1>
<button @click="fn2">点击请求</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
fn1Data: [],
fn2Data: []
},
methods: {
fn1() {
axios({
url: "./data.json",
method: "get"
}).then(res => {
// console.log(res)
// 将响应的数据保存到 模型中
this.fn1Data = res.data.data
console.log(res.data.data)
}).catch(err => {
console.log(err)
})
},
fn2() {
axios({
url: "https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=4101518",
method: "get",
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"15747611471361504633687","bc":"110100"}',
'X-Host': 'mall.film-ticket.film.list'
}
}).then(res => {
// console.log(res)
// 将响应的数据保存到 模型中
this.fn2Data = res.data.data.films
console.log(res.data.data.films)
}).catch(err => {
console.log('this is err')
console.log(err)
})
}
}
})
</script>
</body>
</html>
fetch简介&语法
fetch(请求地址,{
method: 请求方式,
headers:{},
//body:"name=kerwin&age=100"
body:JSON.stringify({
数据1: 值1,
数据n: 值n
})
}).then(res=> res.json()).then(res=>{
console.log(res);
})
fetch练习
- 需求1:通过axios请求data.json本地文件
- 需求2:通过axios请求线上“卖座电影正在热映”
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>本地请求</h1>
<button @click="fn1">点击请求</button>
<h1>线上请求</h1>
<button @click="fn2">点击请求</button>
<div v-for="film in films">
<p>编号:{{ film.filmId}}</p>
<p>标题:{{ film.name}}</p>
<img v-bind:src="film.poster" width="300" height="150" />
<!-- <img :src="film.poster" width="300" height="50" /> -->
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
// 正在热映
films: []
},
// 声明普通方法
methods: {
fn2() {
fetch('https://m.maizuo.com/gateway?cityId=410500&pageNum=1&pageSize=10&type=1&k=2817913', {
method: 'get',
headers: {
'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.0.4","e":"15748374011636382539989","bc":"410500"}',
'X-Host': 'mall.film-ticket.film.list'
}
})
.then(res => res.json())
.then(res => {
console.log(res)
this.films = res.data.films
})
},
// fn1: function(){}
// fn1: () => {}
fn1() {
fetch('./data.json',{
method: 'get',
// headers:{},
//body:"name=kerwin&age=100"
// body:JSON.stringify({
// 数据1: 值1,
// 数据n: 值n
// })
})
// .then(res=> {
// // console.log(res)
// // console.log(res.json()) // 返回的promise对象
// return res.json()
// })
.then(res=> res.json())
.then(res=>{
console.log(res);
})
}
}
})
</script>
</body>
</html>
小总结(异步请求区别和选择ajax/jq/axios/fetch)
ajax/jq/fetch关系
最初ajax 瑕疵:1-异步回调地狱,2-语法麻烦,3-语法有兼容性问题
后来jq 明确:基于ajax封装
好处:语法更简单、解决兼容性问题
瑕疵:异步回调地狱
官方是如何解决异步回调地狱的:promise
最后:fetch 官方封装的 不需要导入库直接使用(fetch = XMLHttpRequest + promise)
fetch和axios(面试)
明确:vue 以前 vue-resource(官方的 后来官方推荐别用 推荐你用axios 第三方的)
相同点:
1.都是项目用来发送异步请求的
2.都是基于XMLHttpRequest + promise
不同点:
1- axios是第三方封装的,fetch是官方封装的
2- axios更强(并发&拦截器 -> 写项目说)
3- fetch每次都需要then res.json()
六、计算属性和侦听器
1、计算属性(明确需求)
- 说明:视图主要负责展示数据,但是在视图写过多的逻辑
- 思考:是否有利于后期维护
- 回答:不行
- 解决:以前(封装起来,直接调用) 现在(计算属性)
- 特色:1-减少代码冗余便于维护,2-有缓存
2、计算属性(语法)
定义
new Vue({
el,
data,
methods,
// 声明计算属性(名词就是普通方法升级版:1-减少代码冗余,2-提高性能 通过缓存)
computed: {
方法1,
...
方法n
}
})
调用:{{ 计算属性函数名 }} 切记切记普通函数升级版 所以不需要叫小括号调用
3、计算属性(练习)
- 效果图
- 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<h1>翻转字符串</h1>
<p>默认显示: {{ msg }}</p>
<p>简单实现: {{ msg.split('').reverse().join('') }} (后期如果多个地方调用,不便于维护)</p>
<p>简单实现2: {{ msg.split('').reverse().join('') }} (后期如果多个地方调用,不便于维护)</p>
<p>普通方法: {{ reverseStrFn() }}</p>
<p>普通方法2: {{ reverseStrFn() }} (注:如果封装的代码特别耗性能)</p>
<p>计算属性: {{ reverseStrComputed }} </p>
<p>计算属性2: {{ reverseStrComputed }} </p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: "hello,webopenfather"
},
// 声明普通方法
methods: {
reverseStrFn() {
console.log(111)
return this.msg.split('').reverse().join('')
}
},
// 声明计算属性
computed: {
reverseStrComputed() {
console.log(222)
// 发现:计算属性定义语法和普通方法一毛一样
// 但是:特性不一样(多个一个缓存)
// 小心:调用不一样 不需要小括号
return this.msg.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
4、侦听器(明确需求)
思考:大家后期做商城项目,是否需要写搜索功能
回答:肯定
思考:以前如何写搜索的
回答:1-给搜索框增加键盘松开事件,2-获取内容,键盘松开之后发送异步请求
现在:新技术侦听器
5、侦听器(语法)
侦听器:名词解释不清,也是方法的升级版 可以监听模型数据变化,交给函数处理
定义
new Vue({
el
data
methods
computed
watch: {
....
// 留心:函数名就是你需要监控的模型数据(也就是说函数名模型中data键)
函数名(新数据, 旧数据) {// 脚下留心:形参是系统传递进来的
}
}
})
调用:不能调用,实战一般怎么用 (将数据保存到模型新数据中,然后视图遍历)
6、侦听器(练习)
- 需求:在页面显示搜索框,用户输入内容 同步页面输出
- 上述需求目的:验证侦听器可以监控数据变化,并交给函数处理
- 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue watch</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
搜索框:
<input type="text" v-model="search">
<hr />
{{search}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
search: "",
searchData: []
},
// 声明侦听器
watch: {
// 脚下留心:函数名不是乱写的
// 而是:要监听的模型数据
search(newData, oldData) {
console.log('新数据:', newData, '旧数据:',oldData)
// 发送异步请求
// axios 得到数据 res
// 思考:数据如何在页面展示呢?
// 回答:保存到模型中即可 this.searchData = res.data
}
}
})
</script>
</body>
</html>
7、计算属性和侦听器区别
- 相同点:研发目的(避免在视图写太多逻辑,导致后期难维护)
- 不同点:
1计算属性(直接通过函数名调用) 侦听器(不能调用 借助模型调用)
2计算属性(有缓存) 侦听器(没有)
3计算属性(一个【键/函数名】监控【n个数据变化 用了几个就监控几个】)
侦听器 (一个【键/函数名】监控【一个数据变化】)
- 代码
<!DOCTYPE html>
<html lang="en">
<head>
<title>计算属性和监听器的区别</title>
<meta charset="UTF-8">
</head>
<body>
<div id="app">
<p>
姓:
<input type="text" v-model="xing">
</p>
<p>
名:
<input type="text" v-model="ming">
</p>
<hr />
姓名(直接搞):{{xing}}{{ming}} 或 {{xing+ming}} <br />
姓名(普通方法):{{ fullNameFn() }} <br />
姓名(计算属性):{{ fullNameComputed }} <br />
姓名(侦听器):{{ fullName }} <br />
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
xing: "",
ming: "",
fullName: ""
},
methods: {
fullNameFn() {
return this.xing + this.ming // 模型变了 受到影响 监控多个数据
}
},
// 声明计算属性
computed: {
fullNameComputed() {
return this.xing + this.ming // 模型变了 受到影响 监控多个数据
}
},
// 声明侦听器
watch: {
xing(newData, oldData) {
// 注:结果要借助模型展示
// this.fullName = this.xing + this.ming
this.fullName = newData + this.ming
},
// ming(newData, oldData) {
// this.fullName = this.xing + newData
// }
}
})
</script>
</body>
</html>
8、小总结
- 什么时候用普通方法:1-事件调用,2-视图有太多相同代码 封装使用普通方法
- 什么时候用计算属性:普通方法多次调用并且每次单个调用耗性能 -> 通过计算属性优化
- 什么时候用侦听器:数据变化后不是直接显示,还需要逻辑
- 语法潜规则
new Vue({
el
data
methods
// 声明计算属性
computed: {
方法 // 1-普通方法升级版,2-调用不加小括号,3-有缓存,
// 4-如果里面有操作模型了 就会再次触发重新缓存
},
// 声明侦听器
watch: {
// 函数名就是data中的键 必须是
方法 // 1.普通方法升级版,2-不能调用需要借助模型
// 3.每次只能监控一个数据
}
})
思考:为什么搜索用侦听器而不是计算属性
回答:计算属性的唯一特性就是缓存,但是搜索后每次都要重新调用 破坏了缓存, 没必要用了。
猜你喜欢
- 2024-09-14 Vue+Element UI实现断点续传、分片上传、秒传
- 2024-09-14 Vue3-笔记十.5(透传Attributes)(vue组件穿透什么意思)
- 2024-09-14 写 Vue 我建议非必要别用 watch(vue不用写html吗)
- 2024-09-14 一文看完vue3的变化之处(vue3稳定吗)
- 2024-09-14 vue中的v-model刨根问底(vue v-model.lazy)
- 2024-09-14 vue的父组件和子组件冲突问题(vue中父组件怎么调用子组件的方法)
- 2024-09-14 「面试题」如何去掉vue的url地址中的#号?及其原理?
- 2024-09-14 Vue进阶(七十一):webpack实现一键动态切换主题色
- 2024-09-14 vue2组件系列第三十七节:Collapse 折叠面板
- 2024-09-14 前端知识点总结——Vue(前端面试题2021及答案vue)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)