概念
概念:Vue 是一套使用 Javascript 构建用户界面的渐进式框架。
Vue 框架涉及的内容有:Vue.js 开发概述、环境搭建、 Vue 指令、组件化应
用构建、组件通信、组件嵌套、自定义指令、 自定义过滤器、组件属性、
组件的路由、路由跳转。
注意:Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。
MVVM开发模式
vuejs 是 MVVM 开发模式。
MVVM 是 Model-View-ViewModel 的缩写。MVVM 是一种设计思想。Model
层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑;View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来,ViewModel 是一个同步 View 和 Model 的对象。
在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,而 Model 数据的变化也会立即反应到 View 上。
VueJS框架的特点
1. 组件化开发, 提高代码的复用率
2. 声明式编程, 以前是命令式编程, 不再操作复杂的 DOM 树
3. 虚拟 DOM
创建并启动项目
1.步骤
1) 创建 vue 项目指令:npm init vue@latest 创建项目(指定项目名称,选择插件)
2) 下载项目依赖:npm i
3) 启动项目:npm run dev
2.项目概要
1) scr文件夹中包含:
1> assets(放置图片资源,字体等静态文件)
2> components(放置组件)
3> App.vue(根组件/单文件组件)
1>> template标签:组件模板,决定页面显示内容,包含且必须至少包含一个根元素/标签
2>> style标签:组件样式
3>> script标签:组件 js 逻辑
2) main.js文件:入口文件
插值表达式
语法:<tag>{{变量/表达式}}</tag>
<template>
<div id="list">
<div id="item" v-for="(item,index) in list" :key="index">
<img :src="item.pic" alt="">
<p>{{item.name}}</p>-------------------------插值表达式,使用双层花括号包裹住数据模型中的变量,用于标签内容区,也就是标签之间
</div>
</div>
</template>
指令
1.列表渲染
1)要点
1> key 属性的作用
key 属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes;如果
不使用 key,vue 会使用一种最大限度减少动态元素并且尽可能尝试就地修改/复用相同类
型元素的算法;而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除/销
毁 key 不存在的元素。在进行插入或者重置顺序时,使用 key 属性可以让 diff 算法更
高效,提高渲染效率--(重要点)
2> 特点
列表渲染又称循环渲染,v-for 指令放在哪个元素上, 就会根据数组的长度 n 最终
出 n 个元素,包括内部的子元素, 形成一个列表, 通过 key 属性给渲染出来的每个列
表元素绑定一个唯一索引, 避免 vue 的警告
3> 注意
1>> 该语法不能忘记加上 key="属性值",且 key 的属性值具有唯一性
2>> v-for 语法遍历数组的元素必须在添加 v-for 的标签内部使用,在其外部使用则无法渲染
4> 列表渲染/循环渲染语法
<div v-for="(元素,下标) in 数组" v-bind:key="下标">
5> 导入本地图片语法(本地图片需要从 assets 导入才能使用)
import 名称 from '路径'
data 必须是个函数, 必须返回一个{},data 中返回的数据是可以在组件模板 template
中使用的,其次拼写必须准确,否则无法加载
data中定义的所有变量都是响应式数据, 只要在任何地方修改了响应式数据的值, 当前组
件都会自动更新( 当前组件模板中的所有代码都会重新执行 )
-------vue框架的核心思想: 数据驱动视图更新--(重要点)
2)代码演示
语法:
<div v-for="(item,index) in 数组" v-bind:key="index">
案例:
<template>
<div class="list">
<div class="item" v-for="(item,index) in arrlist" :key="index">
<img :src="item.pic" alt="">
<div class="name"> {{ item.name }} </div>
</div>
</div>
</template>
导入本地图片:(本地图片需要从assets导入才能使用);
语法:import 名称 from '路径'
import pic from './assets/pic.png'
export default {
data(){----------------data必须是个函数, 必须返回一个{},data中返回的数据是可以在组件模板template中使用的,其次拼写必须准确,否则无法加载
return {
arrlist:[
{ name:'嗨购超市',pic },
{ name:'数码电器',pic },
{ name:'嗨购服饰',pic },
{ name:'嗨购生鲜',pic },
{ name:'嗨购到家',pic },
{ name:'充值缴费',pic },
{ name:'9.9元购',pic },
{ name:'领券',pic },
{ name:'领金贴',pic },
{ name:'plus会员',pic }
]
}
}
}
</script>
2.属性绑定
1)要点
1> 语法
<tag v-bind:属性名="变量类属性值"></tag>
v-bind:可以简写成 :
2> 使用场景
当属性值为变量或需要运算的时候需要在属性名前面加上v-bind:或者:
2)代码演示
语法:v-bind:-------------可以简写成 :
------当属性值为变量或需要运算的时候需要在属性名前面加上v-bind:或者:
<template>
<div class="list">
<div class="item" v-for="(item,index) in arrlist" :key="index">
<img :src="item.pic" alt="">
<div class="name"> {{ item.name }} </div>
</div>
</div>
</template>
3.条件渲染
1)要点
1> v-if条件渲染:控制标签的显示/隐藏( 是通过控制标签的插入与删除来实现标签的显
示/隐藏 )
2> v-show条件渲染:控制标签的显示/隐藏( 是通过控制标签添加以及去除display:none
样式值来实现标签的显示/隐藏 )
3> 语法:
1>> v-if="条件表达式"
v-else(v-else 指令不能直接添加给列表渲染的元素,因后期元素渲染成多个会造成
歧义)
2>> v-show="条件表达式"
在元素需要频繁切换的场景下, 建议使用 v-show,它的性能好一些
2)代码演示
<template>
<div class="app">
<h1> {{ num }} </h1>
1.v-if 条件渲染(引号内条件成立则渲染该条语句的元素,不成立则渲染v-else的元素)
<div v-if="arr.length == 0" class="empty">列表加载中...</div>
<div v-else class="box">
2.v-show条件渲染(引号内条件成立则正常渲染元素,条件不成立则自动为该元素添加
display:none属性,使之隐藏)
<div v-show="arr.length == 0" class="empty">列表加载中...</div>
<div v-for="(item,index) in arr" v-bind:key="index">
--------当arr数组为空时,依照arr元素个数循环渲染的元素默认隐藏(在浏览器控
制台看不到),不予渲染
<div class="item"></div>
<span></span>
{{ index + 1 }} {{ item }}
</div>
<h1> {{ obj.name }} {{ obj.age }} </h1>
</div>
</template>
4.渲染到元素内容
1)要点
1> v-html 渲染到元素内容, 拥有 html解析
2> v-text 渲染到元素内容, 没有 html解析,会直接把标签本身显示出来
3> v-html效果类似于原生js的innerhtml,v-text的效果则类似于原生js的innertext
2)代码演示
<script>
export default {
data(){
return {
title:"今天开始学习vuejs",
num:666,
arr:[ ],
obj:{ name:'张三',age:30 }
}
}
}
</script>
<template>
<div class="app">
<h1> {{ title }} </h1>--------title在data()的赋值包含html标签,想要将html标签
的效果展示出来,插值表达式是做不到的
<div v-html="title"> </div>-------v-html可以将其属性值"title"的html标签的效果
渲染出来,效果类似于原生js的innerhtml
<div v-text="title"> </div>-------v-text也可以将属性值"title"渲染出来,但他没
有html解析,会将标签本身显示出来,效果类似于原生js的innertext
<h1> {{ num }} </h1>
</template>
5.双向数据绑定
1)要点
1> v-model 双向数据绑定指令, 当输入的内容发生改变,输入的内容会实时保存在对应的变量中
2> v-model 双向数据绑定指令, 当对应的变量发生改变,改变后的内容会实时显示在输入框中
3> 只有表单元素可以输入内容,故该指令只用于表单元素
4> 语法:
v-model="变量名"
2)代码演示
<script>
export default {
data(){
return {
phone:'',
pass:'',
check:false
}
},
methods:{
login(){
console.log( this.phone, this.pass, this.check );
if( !this.check ){
alert('请勾选协议!')
}
},
}
}
</script>
<template>
<div class="app">
<div class="line">
<input v-model="phone" type="text" placeholder="输入手机号">
---------通过v-model绑定input输入内容和组件实例中的变量,可以做到变量值实时同
步给input输入框,或者input输入内容实时存储在变量中
</div>
<div class="line">
<input v-model="pass" type="text" placeholder="输入密码">
</div>
<div class="line">
<input type="checkbox" v-model="check"> 勾选协议
---------v-model还可以绑定input复选框或者单选框是否被选中的状态属性,实时监测
选项是否被选中,如果选中,check属性获取true值,反之获取false值
</div>
<button @click="login">登陆</button>
</div>
</template>
6.事件绑定
1)要点
注意:v-on:去掉on的事件类型 绑定点击事件 , 可以简写为 @去掉on的事件类型 ,也即用@可以代替v-on:
语法:
v-on:去掉on的事件类型="事件绑定函数名称"(如果需要传参,事件绑定函数名称后面需要带上括号)
2)代码演示
<script>
export default {
data(){
return {
phone:'',
pass:'',
check:false
}
},
methods:{---------------------------定义方法(函数)
login(){----------------该写法等同于login:function(){}
console.log( this.phone, this.pass, this.check );
if( !this.check ){
alert('请勾选协议!')
}
}
}
}
</script>
<template>
<div class="app">
<div class="line">
<input v-model="phone" type="text" placeholder="输入手机号">
</div>
<div class="line">
<input v-model="pass" type="text" placeholder="输入密码">
</div>
<div class="line">
<input type="checkbox" v-model="check"> 勾选协议
</div>
<button @click="login">登陆</button>
----------绑定函数,可以用@代替v-on:,这是函数绑定的简化写法
</div>
</template>
7.this
1)概念
1> 含义:this表示 当前组件实例( 当前组件的对象 ),通过this关键字, 可以拿到当前组件实例身上的所有属性和方法
2> 使用规则:
1>> data中定义的数据在组件模板template中使用可以加this,也可以不加
2>> data中定义的数据在组件js逻辑script中使用,必须加上this
2)代码演示
<script>
export default {
data(){
return {
phone:'',
pass:'',
check:false
}
},
methods:{
login(){
console.log( this.phone, this.pass, this.check );
--------script标签之间的this必须加上
if( !this.check ){
alert('请勾选协议!')
}
},
xxx(){
}
}
}
</script>
<template>
<div class="app">
<div class="line">
<input v-model="phone" type="text" placeholder="输入手机号">
----------------template标签之间的属性可以不加this
</div>
<div class="line">
<input v-model="pass" type="text" placeholder="输入密码">
</div>
<div class="line">
<input type="checkbox" v-model="check"> 勾选协议
</div>
<button @click="login">登陆</button>
</div>
</template>
7.案例
1)事件高亮小案例
思路:高亮的控制思路: 点击时保存当前点击的按钮下标(索引), 然后根据保存的按钮下标判断哪个按钮需要高亮
代码逻辑:触发点击事件,将被点击元素的下标index通过形参i传入绑定函数,然后保存在
设定的变量currentIndex中,相当于改变了currentIndex的值;而currentIndex属性
是date中的响应式数据,该变量值的改变会使当前组件模板中的所有代码都会重新执
行,也即更新,而在重新执行时,属性class中active值只有在下标index值与变量
currentIndex相等的元素上才为true,也就是说只有数组中唯一的下标等于
currentIndex的元素才有class="active"属性,而我们在组件样式中给定的专属
于.btn.active元素的特殊高亮样式也会被渲染给具有class="active"属性的这个元
素,也就实现了点击高亮的效果。
<template>
<div class="tabbar">
<div @click="handleClick(index)" v-for="(item,index) in btns" :key="index" :class="{btn:true , active: this.currentIndex == index }">-------------------当index的值等于currentIndex时,active的值为true
<img :src="item.pic" alt="">
<div class="name">{{item.name}}</div>
</div>
</div>
</template>
2)分类切换高亮小案例
<template>
<div class="box">
<div class="list">
渲染一级分类列表
<div @click="handleClick(index)" v-for="(item,index) in list" :key="index" :class="{ cate:true, active: currentIndex == index }">
{{ item.name }}
</div>
</div>
<div class="sublist">
渲染二级分类列表
<div class="cate" v-for="(item,index) in list[currentIndex].list" :key="index">------此处使用currentIndex响应式数据的值作为一级数组list的下标,索引对应的二级数组进行对应分支的渲染
{{ item.name }}
</div>
</div>
</div>
</template>
<script>
vue框架的核心思想: 数据驱动视图更新
export default {
data(){
return {
list:[
{
name:'手机',
list:[ { name:'苹果手机' },{ name:'小米手机' } ]
},
{
name:'家电',
list:[ { name:'苹果家电' },{ name:'小米家电' } ]
},
{
name:'口红',
list:[ { name:'苹果口红' },{ name:'小米口红' } ]
},
],
currentIndex:0
}
},
methods:{
handleClick(i){
this.currentIndex = i;-----------------------保存下标( 修改currentIndex这个响应式数据的值 )
}
}
}
</script>
<style>
.box{
display: flex;
}
.list .cate{
line-height: 40px;
padding: 0 15px;
}
.list .cate.active{
background-color: #ccc;
border-left: 2px solid red;
}
</style>