前端Vue
HalukiSan 2024-08-06 10:03:02 阅读 64
第一章 Vue认识和基础
安装Vue插件到浏览器。
Vue 简介
渐进式 JavaScript 框架
作者:尤雨溪 大学 科尔盖特大学
易学易用,性能出色,适用场景丰富的 Web 前端框架。
Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。
渐进式框架
Vue 是一个框架,也是一个生态。其功能覆盖了大部分前端开发常见的需求。但 Web 世界是十分多样化的,不同的开发者在 Web 上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue 的设计非常注重灵活性和“可以被逐步集成”这个特点。根据你的需求场景,你可以用不同的方式使用 Vue:
无需构建步骤,渐进式增强静态的 HTML
在任何页面中作为 Web Components 嵌入
单页应用 (SPA)
全栈 / 服务端渲染 (SSR)
Jamstack / 静态站点生成 (SSG)
开发桌面端、移动端、WebGL,甚至是命令行终端中的界面
如果你是初学者,可能会觉得这些概念有些复杂。别担心!理解教程和指南的内容只需要具备基础的 HTML 和 JavaScript 知识。即使你不是这些方面的专家,也能够跟得上。
如果你是有经验的开发者,希望了解如何以最合适的方式在项目中引入 Vue,或者是对上述的这些概念感到好奇,我们在使用 Vue 的多种方式中讨论了有关它们的更多细节。
无论再怎么灵活,Vue 的核心知识在所有这些用例中都是通用的。即使你现在只是一个初学者,随着你的不断成长,到未来有能力实现更复杂的项目时,这一路上获得的知识依然会适用。如果你已经是一个老手,你可以根据实际场景来选择使用 Vue 的最佳方式,在各种场景下都可以保持同样的开发效率。这就是为什么我们将 Vue 称为“渐进式框架”:它是一个可以与你共同成长、适应你不同需求的框架。
Vue初次体验
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">{ -- -->{username}}</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
data: {
username: '张三',
},
})
</script>
</body>
</html>
Vue指令语法
①插值表达式:
案例一:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">{ -- -->{num1+num2}}</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
num1: 6,
num2: 8,
},
})
</script>
</body>
</html>
案例二:
对象插值表达式使用。
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<!-- { {num1+num2}} -->
姓名:{ {user.name}} <br />
年龄:{ {user.age}}<br />
性别:{ {user.sex}}
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
// num1: 6,
// num2: 8,
user: {
name: '高启强',
age: 48,
sex: '男',
},
},
})
</script>
</body>
</html>
②v-text用法
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<p v-text="content"></p>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
content: '我是中国人',
},
})
</script>
</body>
</html>
③v-html用法
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<!-- 这样写就直接解析html标签属性 -->
<div v-html="docontent"></div>
<!-- 插值是原样输出 -->
<div>{ {docontent}}</div>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
docontent:
'<h4 style="color: red; font-weight: bold;">欢迎大家来学习前端 vue技术</h4>',
},
})
</script>
</body>
</html>
{ -- -->{ }}
插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容!
v-text
指令的缺点:会覆盖元素内部原有的内容!
v-html
指令的作用:可以把带有标签的字符串,渲染成真正的 HTML 内容!
MVVM架构模型
属性绑定指令
属性绑定指令分单项属性绑定指令和双向数据绑定指令。
①单项数据绑定指令:v-bind
单项数据绑定指令一般开发用在非表单的标签。
案例一:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<!-- v-bind可以简写成英文的: -->
<p :title="title">{ -- -->{title}}</p>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
title: '学习Vue开发',
},
})
</script>
</body>
</html>
案例二:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<input type="text" :placeholder="tips" /><br />
<hr />
<img :src="photo" alt="" style="width: 680" />
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
photo:
'https://syw.ctgu.edu.cn/__local/8/6E/DD/2F507A146723E194C2A7404B0EA_DEE66658_1D0B0.jpg',
tips: '请您输入',
},
})
</script>
</body>
</html>
②事件绑定
v-on:
简写是 @
案例一
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
你看到的数字是{ -- -->{num}}
<hr />
<button @click="add">点击一下加1</button>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
num: 0,
},
methods: {
add() {
this.num += 1
console.log(this)
},
},
})
</script>
</body>
</html>
案例二:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<h2>欢迎来到学习{ -- -->{name}}技术</h2>
<!-- <button v-on:click="showInfo">点我提示信息</button> -->
<button @click="showInfo1">点我提示信息1(不传参)</button>
<button @click="showInfo2($event,88)">点我提示信息2(传参)</button>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
name: 'vue',
},
methods: {
showInfo1(event) {
// console.log(event.target.innerText)
// console.log(this) //此处的this是vm
alert('同学你好!')
},
showInfo2(event, number) {
console.log(event, number)
// console.log(event.target.innerText)
// console.log(this) //此处的this是vm
alert('同学你好!!')
},
},
})
</script>
</body>
</html>
按键修饰符
案例一:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
按键esc清空输入内容
<input type="text" @keyup.esc="doesc" />
<hr />
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
username: '',
},
methods: {
doesc(e) {
//e.targen.value = ''
e.target.value = ''
console.log('执行了esc按键操作')
},
},
})
</script>
</body>
</html>
③双向绑定V-model
案例一:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
双向绑定
<input type="text" v-model="username" />
<input type="text" v-model="password" />
<hr />
单项绑定
<input type="text" :value="username" />
<input type="text" :value="password" />
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
username: '张三',
password: '123456',
},
})
</script>
</body>
</html>
双向绑定在实际开发中用于表单元素。
V-if指令:
V-if是用来判断条件的,和java中的if语句是一样的。
案例:
<div id="root">
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const vm = new Vue({
el:'#root',
data(){
return{
ok:true
}
}
})
V-if 及V-else指令
相当于java中的if else 作用。
案例一:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue使用</title>
</head>
<body>
<div id="root">
<div>
<template v-if="isValues">
<h3>你今天生病了吗? 没有</h3>
<hr>
</template>
<template v-else="isValues === false">
<h3>你今天生病了吗?伤病了</h3>
<hr>
</template>
<button @click="updateValue">点击事件</button>
</div>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
const vm = new Vue({
el:'#root',
data(){
return{
isValues:true,
}
},
methods: {
updateValue(){
this.isValues = !this.isValues
}
},
})
</script>
</html>
V-show指令:
另一个用于根据条件展示元素的选项是 v-show
指令。用法大致一样:
<h1 v-show="ok">Hello!</h1>
<hr>
const vm = new Vue({
el:'#root',
data(){
return{
ok:false,
// isValues:true,
}
},
注意,v-show
不支持 <template>
元素,也不支持 v-else
。
一般来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。
V-for指令:
过滤器(了解学习Vue3中已经删除了。)
filter
过滤器(Filters)是 vue 为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式 和 v-bind 属性绑定。 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道符”进行调用。
案例一:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
先输出
<p>{ -- -->{massage}}</p>
<hr />
通过过滤器输出
<p>{ {massage | cap}}</p>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
massage: 'hello vue.js',
},
methods: {
},
//过滤器声明
filters: {
//过滤器是函数
cap(vul) {
//过滤器必须要求返回值。
//console.log(vul)
//return '啊啊啊啊啊啊'
return vul.charAt(0).toUpperCase() + vul.slice(1)
},
},
})
</script>
</body>
</html>
案例练习
实现效果:
案例代码如下:
<!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" />
<link rel="stylesheet" href="./css/brandlist.css" />
<link rel="stylesheet" href="./tjs/bootstrap.css" />
<title>案例练习</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<div class="card">
<div class="card-header">添加名称</div>
<div class="card-body">
<!-- 添加品牌的表单区域 -->
<!-- form 表单元素有 submit 事件 -->
<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" :key="item.id">
<td>{ -- -->{ item.id }}</td>
<td>{ { item.name }}</td>
<td>
<div class="custom-control custom-switch">
<!-- 使用 v-model 实现双向数据绑定 -->
<input
type="checkbox"
class="custom-control-input"
:id="'cb' + item.id"
v-model="item.status"
/>
<!-- 使用 v-if 结合 v-else 实现按需渲染 -->
<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 | dateFormat }}</td>
<td>
<a href="javascript:;" @click="remove(item.id)">删除</a>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 导入Vue的js -->
<script src="./tjs/dayjs.min.js"></script>
<script src="../js/vue.js"></script>
<script>
Vue.filter('dateFormat', function (time) {
// 1. 对 time 进行格式化处理,得到 YYYY-MM-DD HH:mm:ss
// 2. 把 格式化的结果,return 出去
// 直接调用 dayjs() 得到的是当前时间
// dayjs(给定的日期时间) 得到指定的日期
const dtStr = dayjs(time).format('YYYY-MM-DD HH:mm:ss')
return dtStr
})
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
brand: '',
// nextId 是下一个,可用的 id
nextId: 4,
// 品牌的列表数据
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() },
],
},
methods: {
// 点击链接,删除对应的品牌信息
remove(id) {
this.list = this.list.filter((item) => item.id !== id)
},
// 阻止表单的默认提交行为之后,触发 add 方法
add() {
// 如果判断到 brand 的值为空字符串,则 return 出去
if (this.brand === '') return alert('必须用户名称')
// 如果没有被 return 出去,应该执行添加的逻辑
// 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>
第二章Vue
axios 发送请求后端接口
axios 的基本使用
发送get请求:
axios({
// 请求方式
method: 'GET',
// 请求的地址
url: 'http://127.0.0.1:10086/api/get',//请求路径
// URL 中的查询参数
params: {
id: 1
}
}).then(function (result) {
console.log(result)
})
发送POST请求:
document.querySelector('#btnPost').addEventListener('click', async function () {
// 如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await!
// await 只能用在被 async “修饰”的方法中
const { data: res } = await axios({
method: 'POST',
url: 'http://127.0.0.1:10086/api/post',
data: {
name: 'zs',
age: 20
}
})
console.log(res)
})
案例一:(请求我们之前开发的年级数据)记得在年级的controller加上跨域注解 @CrossOrigin
不加注解错误:
代码如下:
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<!-- 导入Vue的js -->
<!-- <script src="js/vue.js"></script> -->
<script src="js/axios.js"></script>
<script>
//调用axios返回结果是Promise 对象
const result = axios({
method: 'GET',
url: 'http://127.0.0.1:10086/sms/gradeController/getGrades',
})
// console.log(res)
result.then(function (list) {
console.log(list)
})
</script>
</body>
</html>
上述返回结果是:Promise 对象,如果需要后台数据,只需要在返回结果中加上list.data就可以实现。
Post 请求:
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/axios.js"></script>
</head>
<body>
<script>
//调用axios返回结果是Promise 对象
const result = axios({
method: 'post',
url: 'http://127.0.0.1:10086/sms/gradeController/saveOrUpdateGrade',
data:{
name:'大学三年级',
manager:'赵六',
email:'111@163.com',
telephone:'17812345678',
introducation:'这个班级学生学习JavaEE开发'
}
})
// console.log(res)
result.then(function (list) {
console.log(list.data)
})
</script>
</body>
</html>
Vue CLI(Vue 脚手架及工程化开发)
按照官网安装:
命令:在doc 命令下输入:
npm install -g @vue/cli
# OR
yarn global add @vue/cli
npm淘宝的代理:
npm config set registry https://registry.npm.taobao.org
建议用npm
安装好可以查看版本。
用dos 命令:
vue --version
如果想升级Vue CLI可以用下面命令:
npm update -g @vue/cli
# 或者
yarn global upgrade --latest @vue/cli
创建项目用下面命令:
vue create 项目名称
这里选择自定义选择。
先选择vue2.0版。后续我们用vue3.0
下面就可以启动项目了,我就在IDEA中启动了。
启动命令:
npm run serve
ctrl+c
第二种创建Vue工程项目方式:
Vue ui
安装yarn 命令:
①
npm install -g yarn
②查看版本:
yarn --version
③安装yarn的依赖:
yarn install
上述是需要的同学安装。
yarn 没有npm稳定建议使用npm命令。
assets 文件夹:存放项目中用到的静态资源文件,例如:css 样式表、图片资源components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下main.js 是项目的入口文件。整个项目的运行,要先执行 main.jsApp.vue 是项目的根组件。
①自己创建Vue需要在components 目录下。
②导入Vue import Ins from 具体目录
③注册到Vue根元素下面的components
components: {
HelloWorld,
Ins
}
④标签方式使用组件。
下面咱们就体验一下Vue组件。
新建一个mains.Vue如下:
<template>
<div id="app">
<h3>内容输出</h3>
<p>
{ -- -->{username}}
</p>
</div>
</template>
<script>
export default {
name: "Mains",
/*data:{
username:'张大大'
}*/
data(){
return {
username:'张大大'
}
}
}
</script>
<style lang="less">
</style>
①将main.js中的换成mains里内容,上述Mains.Vue就可以在页面渲染。
②说明Vue初始化先执行main.js 油main.js 确定加载哪个Vue来做初始加载。
③Vue初始就是Vue组件
组件中的data用data函数。
Vue事件(下篇)
绑定事件:<div v-on:事件名='函数名'></div>
实现方法:methods:{ -- -->
函数名(){
}
}
事件对象 event
无参数传递 :第一个参数就是event
有参数传递 :需要手动传递事件对象
<div v-on:click='demo(1,2,$event)'></div>
事件修饰符.stop *.prevent *.capture.self.once.passive
案例一(阻止事件冒泡)
<template>
<div>
<h2>vue事件处理</h2>
<!-- 1. 事件修饰符 -->
<div @click="parent">
我是小头爸爸
<!-- 阻止单击事件继续传播 -->
<button @click.stop="child">大头儿子</button>
</div>
</div>
</template>
<script>
export default {
name: "vue-event",
methods: {
child(e) {
e.stopPropagation()//使用vue提供的修饰符
console.log("子元素事件");
},
parent(){
console.log("父元素事件");
}
},
}
</script>
<style scoped>
</style>
两种方式:
一、通过@click.stop 阻止单击事件继续传播
二、通过 e.stopPropagation()阻止单击事件继续传播
按键修饰符.enter * .tab.delete (捕获“删除”和“退格”键).esc.space.up.down.left.right
案例二(按键事件)
<template>
<input type="text" v-on:keyup.enter='getInput'>
</template>
<script>
export default {
name: "input-vue",
methods:{
getInput(e){
//console.log(e);
console.log('按下了回车--搜索');
}
}
}
</script>
<style scoped>
</style>
系统修饰键.ctrl.alt.shift.meta
案例三:
<template>
<div>
<!-- 3. 系统修饰键 -->
<textarea @keyup.ctrl.enter="" cols="30" rows="10"></textarea>
<button @click="send">发送</button>
</div>
</template>
<script>
export default {
name: "vue-send",
methods:{
//系统修饰符
send(){
console.log('发送了聊天信息');
}
}
}
</script>
<style scoped>
</style>
鼠标按钮修饰符.left.right.middle
数组更新检测
说明:在列表渲染中,如果遍历是数组,当数组数据发生改变时,页面什么时候能自动更新(页面重新渲染)
实现数组视图同步更新
变更方法 (修改了原数组)push()pop()shift()unshift()splice()sort()reverse()
替换数组(修改后返回新的数组 原数据不修改 视图想同步更新 覆盖原数组)filter()、concat() 和 slice()
**案例演示数组追加、反转、切割**
```vue
<template>
<div>
<h2>数组更新同步</h2>
<p>arr:{ -- -->{ arr }}</p>
<button @click="addArr">追加数组</button>
<button @click="sliceArr">切割数组</button>
<button @click="reverseArr">数组反转</button>
</div>
</template>
<script>
export default {
name: "vue-array",
data() {
return {
arr: [1, 2, 3],
};
},
methods: {
reverseArr(){
this.arr.reverse()
},
addArr() {
this.arr.push(100)
},
sliceArr() {
//slice() 返回新的数组
let newArr = this.arr.slice(0);
console.log(newArr);
//替换
this.arr = newArr;
},
},
}
</script>
<style scoped>
</style>
```
对象更新检测
说明:对象修改后 视图同步更新视图 -- 内存:栈内存 堆内存
实现对象视图同步更新
Vue.set( target, propertyName/index, value )参数:
{Object | Array} target
{string | number} propertyName/index
{any} value
返回值:设置的值。
用法:
向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi')
案例(对象同步更新)
<template>
<div>
<h2>对象同步更新</h2>
<p>对象obj:{ { obj }}</p>
<button @click="changeUname">修改对象已存在的属性</button>
<button @click=" obj = {user:'admin'}">修改整个obj</button>
<button @click="addAttribute">给obj添加不存在的属性</button>
</div>
</template>
<script>
export default {
name: "vue-object",
data(){
return {
obj:{
uname:'张三三',
age:20
}
}
},
methods:{
changeUname(){
this.obj.uname ='李思思'
},
addAttribute(){
this.obj.sex='女'
console.log('obj',this.obj);
//问题:vue认为 obj没有修改
//1. ...
// this.obj ={...this.obj};
//2. es6: 合并对象 Object.assign({},{},{})
// this.obj=Object.assign({},this.obj)
//3. vue官网解决方法:
//向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。
// this.$set(this.obj,'love','女')
//Vue.set(this.obj,'learn','学习')
//删除 同步视图 删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。
//Vue.delete(this.obj,'age')
}
}
}
</script>
<style scoped>
</style>
Class 与 Style 绑定
介绍:动态的添加class或者是style样式
绑定 HTML Class
直接绑定变量
<div v-bind:class='变量'></div>
对象语法 ***
<div v-bind:class="{类名: 表达式-true显示类名、false隐藏 ,类名:boolean}"></div>
数组语法
<div v-bind:class="[变量1,变量2, {类名:boolean}]"></div>
绑定内联样式v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名
对象语法
<div v-bind:style="{css样式:变量,... }"></div>
数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
直接变量
<div v-bind:style="styleObject"></div>
data: { -- -->
styleObject: {
color: 'red',
fontSize: '13px'
}
}
表单输入绑定
介绍你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定通过指令 v-model='' 获取表单输入的信息数据 实现双向数据绑定
语法: <input type='text' v-model='变量' />data(){ -- -->
return{
msg:''
}
}
修饰符 .lazy 只有当input失去焦点时才更新数据 .number 把input标签中输入的内容转成数字,调用是parseFloat (Nunber()) .trim 去除左右空格
v-model实现原理v-model只不过是一个语法糖而已,真正的实现靠的还是
v-bind:绑定响应式数据触发oninput 事件并传递数据
v-model 是什么。语法糖 :value + @input。还要分为两种情况
<input v-model="val"><!-- 基本等价于,因为内部还有一些其他的处理 -->是事件对象,event.target.value表示input框中的输入值<input :value="val" @input="val = $event.target.value">
*案例练习
<template>
<div>
<h2>表单输入绑定</h2>
<!-- <input type="text" :value="msg" name="" id=""> -->
<!-- 1. 文本/密码 v-model=''-->
<input
type="text"
placeholder="请输入"
v-model="formData.msg"
@keyup.enter="send"
name=""
id=""
/>
<p>msg:{ -- -->{ formData.msg }}</p>
<!-- 2. 多行文本 -->
<!-- 3. 单选按钮 -->
性别:
<input type="radio" v-model="formData.sex" name="aa" value="1" />男
<input type="radio" v-model="formData.sex" name="aa" value="2" />女
<p>选择的性别:{ -- -->{ formData.sex }}</p>
爱好:
<input type="checkbox" v-model="formData.arr" value="a" />吃
<input type="checkbox" v-model="formData.arr" value="b" />喝
<input type="checkbox" v-model="formData.arr" value="c" />玩
<p>选择的爱好:{ -- -->{ formData.arr }}</p>
城市:
<select name="" id="" v-model="formData.select">
<option value="">请选择</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="gaungzhou">广州</option>
</select>
<p>城市选择:{ -- -->{ formData.select }}</p>
<button @click="submit">注册信息</button>
<hr>
<h3>表单修饰符 -修饰符 </h3>
<!-- .lazy 失去焦点或者回车 获取数据 -->
<input type="text" v-model.lazy="search">
<p>search:{ -- -->{ search }}</p>
<!-- .trim 去掉前后空格 -->
<input type="text" v-model.trim="msg" name="" id="">
<p>去空格:{ -- -->{msg}}</p>
<!-- .number 转数字 -->
<input type="number" v-model.number="num" name="" id="">
<p>num:{ -- -->{ num }}</p>
<!-- v-model实现的原理 -->
<input type="text" v-model="inp" name="" id="">
<p>inp:{ -- -->{inp}}</p>
<!-- v-model == v-bind:value='' @input='函数' -->
表单值:<input type="text" :value="val" @input="changeVal" name="" id="">
<p>val:{ -- -->{val}}</p>
</div>
</template>
<script>
export default {
data() {
return {
val:'请输入',
inp:'',
msg: "", //输入框
sex: 1, //性别
arr: [],
select: "",
search:'',
num:'',
//对象的语法---------------
formData: {
msg: "", //输入框
sex: 1, //性别
arr: [],
select: "",
},
};
},
methods: {
send() {
console.log("输入的数据为:", this.msg);
},
submit() {
//点击按钮--发送输入的数据给后台-- data -- msg sex arr ...
console.log("提交注册信息表单",this.formData);
},
changeVal(e){
console.log(e);
console.log(e.target.value);//獲得輸入信息
this.val = e.target.value;
}
},
};
</script>
<style>
</style>
例题:将上述的张大大点击按钮后修改成岳云鹏
实现方式如下:
<template>
<div id="app">
<h3>内容输出</h3>
<p>
{ -- -->{username}}
</p>
<button @click="updateUserName">修改上述张大大</button>
</div>
</template>
<script>
export default {
name: "Mains",
/*data:{
username:'张大大'
}*/
data(){
return {
username:'张大大'
}
},
//这里需要和data函数平级
methods:{
updateUserName(){
this.username = "岳云鹏"
//this 表示Vue对象
}
}
}
</script>
<style lang="less">
</style>
计算属性讲解
计算属性是定义在computed 这个当中。
计算属性中必须有get()
计算属性是计算出来的没有在Vue对象中,通过Vue插件可以证明。
案例显示如下:
定义一个三峡大学,定义一个科技学院 然后通过计算属性将他们连接起来。
实现如下:
<template>
<div id="app">
<span>
{ -- -->{frName}}
</span>
<hr>
<span>
{ {LzName}}
</span>
<hr>
<span>
{ {allName}}
</span>
</div>
</template>
<script>
export default {
name: "Mains",
data(){
return {
frName:"三峡大学",
LzName:"科技学院"
}
},
//用来定义计算属性。
computed:{
allName:{
get(){
return this.frName +'-'+ this.LzName
}
}
},
methods:{
}
}
</script>
<style lang="less">
</style>
计算属性中也有set()函数。 是用来修改数据的【开发当中不常用】。
上述可以简化为下面代码。
allName(){
return this.frName + '-'+this.LzName
}
实现代码如下:
<template>
<div id="app">
<h3>你今天生病了吗?{ -- -->{isValues?'没有':'生病了'}}</h3>
<hr>
<button @click="updateValue">点击变化</button>
</div>
</template>
<script>
export default {
name: "Mains",
data(){
return {
isValues:true,
}
},
computed:{
},
methods:{
updateValue(){
this.isValues = !this.isValues
}
}
}
</script>
<style lang="less">
</style>
上述功能实现了,需要用计算属性来实现。
<template>
<div id="app">
<h3>你今天生病了吗?{ -- -->{info}}</h3>
<hr>
<button @click="updateValue">点击变化</button>
</div>
</template>
<script>
export default {
name: "Mains",
data(){
return {
isValues:true,
}
},
computed:{
info(){
return this.isValues?'没有':'生病了'
}
},
methods:{
updateValue(){
this.isValues = !this.isValues
}
}
}
</script>
<style lang="less">
</style>
案例三
<template>
<div>
<h2>计算属性computed</h2>
<!-- 如果是字符串 取反操作实现 -->
<p>字符串:{ { msg }}</p>
<!-- 不推荐: 模板语法里面写很多方法 多次使用不方便 -->
<p>字符串-取反:{ { msg.split("").reverse().join("") }}</p>
<p>字符串-取反-封装函数:{ { qufan() }}</p>
<p>字符串-取反-封装函数:{ { qufan() }}</p>
<p>字符串-取反-封装函数:{ { qufan() }}</p>
<!-- 计算属性: -->
<p>计算属性:-取反:{ { msg2 }}</p>
<p>计算属性:-取反:{ { msg2 }}</p>
<p>计算属性:-取反:{ { msg2 }}</p>
<button @click="msg = 'how are you'">修改msg</button>
<!-- 例子: v-for='' v-if不能在同一个元素使用 -- computed处理数据 -->
<h4>早市水果更新:</h4>
<ul>
<li v-for="item in zaoshi2" :key='item.id'>
{ -- -->{item.fruit}}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
msg: "hello vue",
zaoshi: [
{
id: 100,
fruit: "苹果",
flag: false,
},
{
id: 101,
fruit: "阳光玫瑰",
flag: true,
},
{
id: 102,
fruit: "车厘子",
flag: false,
},
{
id: 103,
fruit: "榴莲",
flag: true,
},
],
};
},
methods: {
qufan() {
console.log("执行了方法");
return this.msg.split("").reverse().join("");
},
},
//计算属性: 对数据进行加工处理 缓存数据
computed: {
msg2() {
console.log("计算属性: 对数据进行加工处理 缓存数据");
return this.msg.split("").reverse().join("");
},
//处理数据
zaoshi2(){
//过滤方法 返回的满足条件的数组 比如:[1,2,3,4] =>[3,4]
return this.zaoshi.filter((item)=>{
return item.flag
})
}
},
};
</script>
<style>
</style>
侦听器学习:(watch)
定义格式为 watch:{
对那和属性侦听
}
将上面的例子修改一下:
<template>
<div id="app">
<h3>你今天生病了吗?{ -- -->{info}}</h3>
<hr>
<button @click="updateValue">点击变化</button>
</div>
</template>
<script>
export default {
name: "Mains",
data(){
return {
isValues:true,
}
},
computed:{
info(){
return this.isValues?'没有':'生病了'
}
},
watch:{
isValues:{
handler(newValue,oldValue){
//console.log(newValue,oldValue)
console.log('isValues被修改了',newValue,oldValue)
},
}
},
methods:{
updateValue(){
this.isValues = !this.isValues
}
}
}
</script>
<style lang="less">
</style>
侦听 中有handler()函数,通过handler()中newValue,oldValue获得侦听 前的值和侦听后的值。
第二种侦听通过Vue对象中定义的$watch()
<!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>Document</title>
</head>
<body>
<!-- 绑定Vue数据的插值语法 -->
<div id="root">
<h3>你今天生病了吗?{ -- -->{info}}</h3>
<hr />
<button @click="updateValue">点击变化</button>
</div>
<!-- 导入Vue的js -->
<script src="js/vue.js"></script>
<script>
// 初始化Vue
const vm = new Vue({
el: '#root',
//绑定事件
data: {
isValues: true,
},
computed: {
info() {
return this.isValues ? '没有' : '生病了'
},
},
methods: {
updateValue() {
this.isValues = !this.isValues
},
},
})
vm.$watch('isValues', {
handler(newValue, oldValue) {
//console.log(newValue,oldValue)
console.log('isValues被修改了', newValue, oldValue)
},
})
</script>
</body>
</html>
computed和watch区别 (考点面试题)
相同:computed和watch都是观察页面的数据变化的。
不同:computed:是计算属性,依赖其它属性值:
1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
watch:没有缓存性,更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;
1. 不支持缓存,数据变,直接会触发相应的操作;
2. watch支持异步;
# 第三章 vue
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。