1.1Vue:
Vue.js,常简称Vue,是一种专注于用户界面构造的渐进式JavaScript框架。其核心设计哲学围绕着通过一个精炼的API来实现数据的自动响应更新与视图组件的灵活组合,从而极大地提升了开发效率与代码的可维护性。Vue被构想为一个自下而上、层层递进的应用架构体系,这不仅确保了开发者能够平滑地学习曲线并快速上手,同时还赋予了框架足够的深度与弹性,以应对包括高度复杂的单页面应用程序(SPA)在内的广泛应用场景,满足现代前端开发的多元化需求。
核心特点
响应式数据绑定:Vue的核心库只关注视图层,不仅易于上手,而且便于与第三方库或既有项目整合。Vue.js的响应式系统允许数据模型(JavaScript对象)和DOM之间的双向绑定。当数据变化时,视图会自动更新;当视图中的用户输入被修改时,数据也会相应更新。
组件系统:Vue.js鼓励通过可复用的组件来构建用户界面。每个Vue组件都包含了自己的模板、逻辑和样式,它们是Vue应用的基本构建块。
指令(Directives):Vue.js使用特殊的HTML属性(指令)来扩展HTML的功能。例如,v-bind用于响应式地更新HTML属性,v-model用于在表单输入和应用状态之间创建双向数据绑定。
虚拟DOM:Vue.js使用虚拟DOM来优化DOM操作。Vue.js在内存中以JavaScript数据结构的形式维护了一个真实DOM的抽象表示(即虚拟DOM)。只有当它检测到数据变化时,Vue.js才会智能地更新实际DOM,以最小化DOM操作的数量和范围,从而提高性能。
易于学习:Vue.js的设计考虑了易于上手和易用性。即便是初学者也能很快掌握Vue.js的基本概念和构建简单应用的能力。
生态系统:Vue.js拥有一个活跃的社区和丰富的生态系统,包括Vue CLI(官方脚手架工具)、Vue Router(官方路由管理器)、Vuex(状态管理模式库)等,这些工具和库极大地简化了Vue应用的开发和维护。
使用场景
Vue.js非常适合用于构建单页应用(SPA),但也可以轻松整合到现有项目中以增加交互性。由于Vue.js的灵活性和轻量级,它也被广泛用于Web开发的各种场景,包括但不限于:
动态网站和Web应用
渐进式增强现有应用
单页应用(SPA)
复杂的前端项目
总结
Vue.js是一个功能强大、易于上手且灵活的前端框架,它通过简洁的API和强大的生态系统,为开发者提供了构建现代Web应用所需的一切。无论是小型项目还是大型应用,Vue.js都能提供高效、可维护和可扩展的解决方案。
npm install
npm run serve
工程目录:
2.1声明式渲染:
// template即模版的意思,每一个vue文件里必须要有一个,在这里写HTML代码
<template>
<div id="app"></div>
</template>
// 在这里写js逻辑相关的代码
<script>
export default {
name: "app"
};
</script>
// 这里写样式代码
<style></style>
Vue由三部分组成:template,script,style:他们分别对应HTML,JS,CSS.
template中通常只有一个块元素,通常情况下都是div.
差值表达式:—》两层大括号
渲染一串文字:
<template>
<h2>{{title}}</h2>//tem部分确定插值表达式
</template>
<script>//在script中定义字符串变量
// export default是固定格式,不需要纠结
export default {
// 模块的名字
name: "app",,
// 页面中数据存放的地方
data() {
return {
title: "优课达--学的比别人好一点"
};
}
};
</script>
<!-- scope的意思表示这段样式只在本xxx.vue文件中生效,其他xxx.vue文件中不会生效,有锁定的意思 -->
<style scope>
h2 {
color: deeppink;
border: 1px solid #cccccc;
}
</style>
数组:
HTml代码和之前的写法是一样的,填充数据的时候可以吃用数组下标的形式去取数据。
<h2 class="title">{{title}}</h2>
<ul class="list">
<li>{{todoList[0]}}</li>
<li>{{todoList[1]}}</li>
<li>{{todoList[2]}}</li>
<li>{{todoList[3]}}</li>
<li>{{todoList[4]}}</li>
</ul>
//然后在script中定义数组
<script>
export default {
name: "app",
data() {
return {
title: "今日待完成事项",
todoList: [
"完成HTML标签学习",
"完成CSS文字样式学习",
"完成CSS盒模型学习",
"完成Flex布局学习",
"完成JavaScript入门学习"
]
};
}
};
</script>
//修改一下样式CSS
<style lang="scss" scope>
.title {
box-sizing: border-box;
width: 300px;
height: 30px;
margin: 0;
padding: 0 20px;
font-size: 18px;
font-weight: 700;
line-height: 30px;
color: white;
background: #fd6821;
border-radius: 6px;
}
.list {
list-style: none;
margin: 0;
padding: 0;
margin-top: 15px;
li {
box-sizing: border-box;
width: 300px;
height: 30px;
padding: 0 20px;
margin-bottom: 8px;
font-size: 14px;
line-height: 30px;
background: #8d999d;
color: white;
border-radius: 5px;
}
}
</style>
注意:data,scope:
data:方法里面是用来存放数据或者全局变量
scope:将css代码锁定在本文件中,只能在本文件中有用。
差值表达式-对象
渲染一个班级名单列表:
<script>
export default {
name: "app",
data(){
return {
list:[
{
name:"张三",
grade:"三年级二班",
mark:290
},
{
name:"李四",
grade:"三年级二班",
mark:270
},
{
name:"王五",
grade:"三年级二班",
mark:270
}
]
}
}
};
</script>
2.2处理用户输入
v-model(双向绑定)–input
双向绑定:两个输入框
上面的框的内容改变的时候下面的框的内容跟随改变。
用法:
<template>
<p class="page">{{message}}</p>
<input type="text" v-model="message" placeholder="请输入你想输入的内容" />
</template>
<script>
export default {
name: "app",
data() {
return {
message: ""
};
}
};
</script>
<textarea v-model="message" placeholder="请在输入框内输入...">
双向绑定+复选框:
示例:
<div class="food">
<div class="check-box">
<input type="checkbox" value="新奥尔良鸡腿堡" v-model="checkedGoods" />
</div>
<div class="food-name">新奥尔良鸡腿堡</div>
<div class="food-price">¥24</div>
</div>
<script>
export default {
name: "app",
data() {
return {
checkedGoods: []
};
}
};
</script>
2.3处理用户事件
- v-on事件绑定:
第一步:给元素添加点击事件
<button v-on:click="add">按钮</button>
//这样就给按钮注册了一个点击的事件
当点击该按钮的时候就会驱动add方法
简写:Vue为了方便用户开发,每个指令都有一个简写的模式
v-on的简写就是@符号
<button @click="add">按钮</button>
- methods(方法)
第二步:给点击事件添加方法
- 抽离方法
将js代码中的方法写在vue中的规定位置
let alertFn = function () {
alert("Hello World");
};
document.getElementById("btn").addEventListener("click", alertFn);
- 认识方法的书写位置
<script>
export default{
name:"app",
methods:{
// 在这里存放方法
}
}
</script>
- 将抽离的方法放在对应的位置
存放方法的形式的键值对key:value的形式key就是方法名。
value就是方法体
<script>
export default{
name:"app",
methods:{
alertFn:function(){
alert("Hello World");
}
}
}
</script>
案例:
点击按钮数字+1;
<template>
<p>{{ counter }}</p>
<button @click="add">点击</button>
</template>
<script>
export default {
name: "app",
data() {
return {
// 初始次数
counter:0
};
},
methods:{
add:function(){
// 这里的this指向当前的vue实例
this.counter++
}
}
};
</script>
//this纸箱的是当前vue的实例,用在data定义的变量就必须在变量面前加this
<button @click="add">点击</button>
<!-- 等同于 -->
<button @click="add()">点击</button>
<!-- 当你的方法需要接收参数的时候,你可以将参数写在这个括号内 -->
<button @click="add(number)">点击</button
事件修饰符:
- 阻止冒泡事件
<div @click.stop="fn2"></div>
- 捕获事件
<div class="div2" @click.capture="fn2"></div>
- 阻止默认事件
<div class="div2" @click.prevent="fn2"></div>
2.4监听数据变化
在Vue中通过侦听器来实现监听数据变化,
watch的基本用法:
- 书写位置:
export default就是一个对象,里面都是一对对的键值对,用逗号隔开。
<script>
export default {
name: "app",
// 数据 key---data value---Function
data: function () {
return {};
},
// 方法 key---methods value---{}
methods: {}
};
</script>
<script>
export default {
name: "app",
// 侦听器 key---watch value---{}
watch: {}
};
</script>
- 侦听器的侦听对象。
data里面的变量,当变量开始变化的时候,侦听器开始运行。
<script>
export default {
name: "app",
data: function () {
return {
count: 1
};
},
watch: {
count() {
console.log("count发生了变化");
}
}
};
</script>
- 侦听器的运行时机
<script>
export default {
name: "app",
data: function () {
return {
count: 1
};
},
methods: {
add: function () {
this.count++;
}
},
watch: {
count() {
console.log("count发生了变化");
}
}
};
</script>
拓展:
获取前一次的值:
在上面的案例的基础上添加一个参数:
watch:{
inputValue(value,oldValue) {
// 第一个参数为新值,第二个参数为旧值,不能调换顺序
console.log(`新值:${value}`);
console.log(`旧值:${oldValue}`);
}
}
handler方法,immediate属性:
:::color1
当我们侦听的值没有改变的时候,是不会触发侦听器的,页面第一次渲染的时候也不会触发侦听器。
:::
让页面第一次渲染的时候就去触发侦听器,此时就要用immediate属性。
<script>
export default {
name: "app",
watch: {
firstName: {
handler: function (newName, oldName) {
this.fullName = newName + " " + this.lastName;
},
immediate: true
}
}
};
</script>
3.1HTML属性渲染语法:
html标签上都有自己的属性,target,href,title这些属性都是写死的,如何让这些属性跟随data中定义的变量的值的变化而变化,这里就需要用到属性绑定。
- 动态绑定–v–bind
简写:“:”
例:
<img src="#" alt="吴尊" />
如何使用动态绑定:
<template>
<div id="app">
<img src="#" v-bind:alt="imgText" />
</div>
</template>
<script>
export default {
name: "app",
// 数据
data() {
return {
imgText:'周杰伦演唱会图片'
};
}
};
</script>
3.2模板中使用表达式
- 模板中进行计算:
<template>
<div id="app">
<ul>
<li>{{ goods[0].index + 1 }}---{{ goods[0].name }}</li>
<li>{{ goods[1].index + 1 }}---{{ goods[1].name }}</li>
<li>{{ goods[2].index + 1 }}---{{ goods[2].name }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "app",
// 数据
data() {
return {
goods:[
{
index:0,
name:"扫地机器人"
},
{
index:1,
name:"华为手机"
},
{
index:2,
name:"戴尔笔记本"
}
]
};
}
};
</script>
//差值表达式不仅可以写一个变量,还可以进行简单的计算
- 模板中使用三元表达式:
<template>
<div id="app">
<p>{{ flag?'你已经通过了考试':'你还没有通过考试' }}</p>
<button @click="exchange">转换</button>
</div>
</template>
<script>
export default {
name: "app",
// 数据
data() {
return {
flag:true
};
},
methods:{
exchange(){
this.flag = !this.flag;
}
}
};
</script>
3.3条件渲染语句:
- v-if:
<p v-if="isShow()">{{ message }}</p>
<script>
export default {
name: "app",
// 数据
data() {
return {
message:"当条件满足的时候,显示这里的内容"
};
},
methods:{
isShow(){
if(!this.message)
return false;
return true;
}
}
};
</script>
- v-else-if
是v-if的补充:当条件不止一个的时候就可以用到v-else-if
<p v-if="questions[0].type === 'PICK'">{{ questions[0].content }}</p>
<p v-else-if="questions[1].type === 'MULT'">{{ questions[1].content }}</p>
<p v-else>题目还没有加载进来...</p>
<script>
export default {
name: "app",
// 数据
data() {
return {
questions:[
{
type:"PICK",
content:"这是一道选择题"
},
{
type:"MULT",
content:"这是一道多选题"
},
{
type:"ESSAY",
content:"这是一道论述题"
}
]
};
}
};
</script>
v-show:当满足条件的时候就会显示标签中的内容。
区别是:v-show指令只是把标签中的display属性设置为none
v-if指令,如果不满足条件,则此标签在dom中根本不存在。
当标签出现以后就不会再次消失,或者消失/出现频率不高就用v-if
当标签频繁的切换,从消失到显示,就用v-show。
3.4列表渲染语句
列表渲染的核心就是Vue的循环指令 --v-for
<div id="app">
<ul>
<li v-for="item in 5" :key="item">{{ item }}</li>
</ul>
</div>
循环渲染数组:与js遍历数组一样,v-for也可以遍历数组对象。
<ul>
<li v-for="(item,index) in nameList" :key="index">{{ item }}</li>
</ul>
<script>
export default {
name: "app",
// 数据
data() {
return {
nameList:["张淮森","周逸依","梁澄静","宁古薄","丘约靖"]
};
}
};
</script>
循环渲染对象:
循环渲染对象会从对象里面循环取出里面的值。
<!--
value:对象中每一项的值
key:对象中每一项的键
index:索引
-->
<li v-for="(value,key,index)" :key="index"></li>
<ul>
<li v-for="(value,key,index) in book" :key="index">值:{{ value }}--键:{{ key }}--索引:{{ index }}</li>
</ul>
<script>
export default {
name: "app",
// 数据
data() {
return {
book:{
bookName:'指环王',
author:'JK 罗琳'
}
};
}
};
</script>
遍历数组中的对象:
大部分情况下我们遍历的都是数组中的对象:
<ul>
<li v-for="(item,index) in books" :key="index">
{{ index+1 }}----{{ item.title }}----{{ item.author }}----{{ item.publishedTime }}
</li>
</ul>
<script>
export default {
name: "app",
// 数据
data() {
return {
books: [
{
title: '《魔戒》',
author: '约翰·罗纳德·瑞尔·托尔金',
publishedTime: '1954'
},{
title:'《哈利·波特》',
author:'J·K·罗琳',
publishedTime:'1997'
},{
title:'《人性的弱点》',
author:'戴尔•卡内基',
publishedTime:'2008'
}
]
};
}
};
</script>
!vue中key的作用:
一、写在前面
下面总结一下,vue中的key的作用,在vue中我们可能在两种情况下使用key,第一种情况下就是在v-if中,第二种情况下就是在v-for中使用key。下面我们来看一下key在其中起到的作用。
二、在v-if中使用key
首先我们先看在vue中出现的一种情况,我们在vue中如果使用v-if进行切换时,此时Vue为了更加高效的渲染,此时会进行前后比较,如果切换前后都存在的元素,则直接复用。如果我们在模板中切换前后都存在input框,此时我们在input框中写入一些数据,并且进行页面切换,则原有的数据就会保存。
此时我们就可以使用key,给每一个input框,添加一个唯一的标识key,来表示元素的唯一性。
三、在v-for中使用key
对于用v-for渲染的列表数据来说,数据量可能一般很庞大,而且我们经常还要对这个数据进行一些增删改操作。那么整个列表都要重新进行渲染一遍,那样就会很费事。而key的出现就尽可能的回避这个问题,提高效率。v-for默认使用就地复用的策略,列表数据修改的时候,他会根据key值去判断某一个值是否修改,如果修改则重新渲染该项,否则复用之前的元素。在v-for中我们的key一般为id,也就是唯一的值,但是一般不要使用index作为key
key的添加位置:
<li v-for="(item,index) in books" :key="">
key的值一般都是从后台取到的数据的id,主要是为了保证每一个节点都有唯一的key值。
在学习的时候可以使用索引。
<li v-for="(item,index) in books" :key="index">
4.1计算属性
计算属性也是通过键值对方式添加
<script>
export default {
name: 'app',
// 计算属性
computed: {},
};
</script>
计算属性的写法
计算属性内部是由一系列方法组成的键值对,键是方法名,值是方法体,以文章开头的代码为例,计算属性可以这样写:
<script>
export default {
name: "app",
data:function(){
return {
message:"优课达--学的比别人好一点~"
}
}
// 计算属性
computed:{
reverseMessage:function(){
return this.message.split('').reverse().join('')
}
}
};
</script>
计算属性避免了不必要的代码执行,性能更优。
4.2动态class
动态样式绑定就是根据条件去给某个标签添加样式。
<div class="base" v-bind:class="{ active: isActive }"></div>
.active {
border: 1px solid green;
}
active是类名,对应是css样式中的类名
isActice是boolean类型的值,决定是否用该类名
- 类名书写
<div v-bind:class="{ 'base-active': isActive }"></div>
如果是单个单词的话就是不需要加引号
但是连带字符的类名就需要加引号
- 引号规则
<!-- 外双内单 -->
<div v-bind:class="{ 'base-active': isActive }"></div>
<!-- 外单内双 -->
<div v-bind:class='{ "base-active": isActive }'></div>
如果大括号用双引号引起来那么,里面的类名就需要用单引号引起来,反之相反
- 多类名写法
<div v-bind:class='{ "base-active": isActive,"base":true}'></div>
动态样式绑定可以绑定多个类
动态样式绑定的条件类型:
动态样式绑定的条件,就是类名后面的boolean值,如何去获得这个布尔值。
- 变量形式:
<div :class="{ hover: isActive }">手机/运营商/数码</div>
在data中定义布尔类型的变量
data:function(){
return {
isActive:false
}
}
最后通过用户事件来改变布尔值,从而改变动态绑定的样式。
- 方法形式:多用于循环渲染
数据中的type字段决定是否显示“新”这个字样,但是他并不是布尔值,所以用如下的方法来转换一下。
data:function(){
return {
liListData: [
{
imgUrl:
'https://m.360buyimg.com/babel/jfs/t1/30057/19/14881/720/5cbf064aE187b8361/eed6f6cbf1de3aaa.png',
text: '话费',
type: 'NEW',
},
]
}
}
<span :class="{ 'new-appear': isActive(item.type) }">新</span>
isActive: function(type) {
if (type === 'NEW') {
return true;
}
return false;
}
- 表达式形式:
<span :class="{ 'new-appear': item.type === 'NEW' }">新</span>
- 计算属性形式:
computed: {
hoverObj: function () {
return {
hover: this.index === 1,
};
},
},
动态样式绑定的方法
- 对象写法
<div v-bind:class="{ active: isActive }"></div>
可以添加多个属性
<div v-bind:class="{ active: isActive ,hover:true,'after-hover':false}"></div>
- 数组写法
对象的写法遵守键值对的规则,数值的写法当然也遵守数组的规则,在里面添加类名即可
类名都需要带引号
<div v-bind:class="['red-style', 'font-style']"></div>
数组中使用三元表达式:
三元表达式是一种简洁的条件表达式,用于在单个语句中根据条件选择两个值中的一个;他的基本形式是:
条件?表达式1:表达式2
<div v-bind:class="['red-style', 'font-style',isChoosed ? 'redbg' : '']"></div>
三元表达式实现两个类名的二选一;
<div
v-bind:class="['red-style', 'font-style',isChoosed ? 'redbg' : 'bluebg']"
></div>
在数组中使用对象:
<div v-bind:class="['red-style', 'font-style',{'redbg':isChoosed}]"></div>
4.3动态style:
class外部样式
行内样式style:
- 对象语法:
与class对象语法不同的是,他的键值对是css样式的
属性:值组成的一对键值对
<div :style="{background:'red','font-weight':700,'font-size':'20px'}"></div>
属性是单个单词的,可以不写引号;
如果带字符:如font-size就需要带引号;
值:除了数字 ‘font-weight’:700不用引号,其他都用引号,特殊情况 1px solid black,可以使用模板字符串。
font-weight可以写成fontWeight可以不用引号。
- 数组语法
5.1自定义组件:
组件是可以复用的实例,便捷开发。
为了能在中引用,注册组件;
- 全局注册:可以在任意的根实例中使用
- 局部注册:在单个的Vue格式的文件中组件,在需要用到的地方进行注册。
使用方式:
- 引入组件
- 注册组件
- 使用组件
5.2组件单向数据流:
复用组件的内容是不同的,需要从父组件中传递不同的内容给子组件。
prop的使用方法:
基础使用:
- 父组件中传一个title
<template>
<div id="app">
<!-- 注意!title1 和 title2 是父组件的 data 中定义的数据,title 则是子组件中接收数据时的变量名 -->
<HelloVue :title="title1"></HelloVue>
<HelloVue :title="title2"></HelloVue>
</div>
</template>
单向数据流:
单向数据,数据由父级prop流向子组件,父组件的改变会影响子组件的状态,子组件不能修改父组件通过prop传递过来的数据。