Vue基础知识学习
Vue的安装
安装环境
安装Visual Studio Code
- 官网地址:(https://code.visualstudio.com/)下载安装
- Visual Studio Code(VS Code)是微软2015年推出的一个轻量但功能强大的源代码编辑器,基于 Electron 开发,支持 Windows、Linux 和 macOS 操作系统。内置了对JavaScript,TypeScript和Node.js的支持并且具有丰富的其它语言和扩展的支持,功能超级强大。
- 简单来说就是我们编写代码的必备工具
安装nodejs
Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。
通俗点讲 Node.js是一个JavaScript编程语言的运行环境,在没有node.js之前,JavaScript代码几乎只能在浏览器中运行,通过浏览器解释执行。浏览器其实也是JavaScript的一个运行环境,JavaScript在浏览器中运行主要是面向客户端这方面的。后来node.js诞生了,JavaScript就可以在node.js中来运行了,JavaScript可以基于node.js环境做服务端开发。所以node.js也是JavaScript的服务端运行环境。
官方下载地址(https://nodejs.org/en/) 或者中文网站(https://nodejs.org/zh-cn/download/)
一般选LTS长期稳定版嘛 基本功能都差不多,点击下载并安装
安装时,安装路径可以自由更改,最后英文路径或者默认,其它点下一步
安装后,打开Win+R,输入cmd,窗口中输入:node -v 或 npm -v 查看版本号
安装vue脚手架(vue-cli)
官网地址:(https://cli.vuejs.org/zh/guide/installation.html)
- Window + R键打开运行界面,并输入cmd,点击确定。
- 输入命令:npm install -g @vue/cli 安装脚手架
- 或者 yarn global add @vue/cli 安装(前提先安装yarn 使用: npm i yarn -g)
- vue –version 或 vue -V 查看当前版本号
创建项目
配置下载地址
(如果出现Unexpected token .. in JSON at position …. 那么执行)
- 下载慢可以切换成淘宝的国内镜像:
npm config set registry https://registry.npm.taobao.org/ - 查看是否切换成功
npm config get registry - 强制清除npm缓存:
npm cache clean –force - 再执行安装npm:
npm install -g npm
通过命令创建
- 任选一个文件夹位置创建,例如桌面的一个新建文件夹里
- 将新建文件夹拖入vscode里面 将鼠标移动到该文件夹上 右键终端打开
- 输入 vue create xxx (xxx是项目的名称为小写英文)
- 后续就根据项目配置进行选择,上下箭头是移动,空格是确认选择,回车是执行。如果没有,直接回车
运行项目
- 进入项目目录!!!
- npm run serve 运行或者 yarn serve
Vue介绍
- Vue是渐进式(渐进式:项目中可以逐步使用vue框架 可以使用一部分 或者是整个项目) JavaScript 框架
- 框架为单页面的应用程序 (Vue项目入口:只有一个页面 index.html )
- 跳转的页面路由功能- 路由 (其他页面组件)
- 框架里面使用的是虚拟DOM 没有js BOM DOM
特点: MVVM 模式;代码简洁体积小,运行效率高,适合移动PC端开发;本身只关注 UI (和 react 相似),可以轻松引入 Vue 插件或其他的第三方库进行开发。
Vue的优缺点
优点:
轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是非常耗费性能的,不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。
缺点:
- 单页面应用程序,首页加载速度慢
- 不利于搜索引擎优化
Vue的使用
局部使用Vue
- 引入 Vue 的cnd网址 或者是下载到本地js文件 (类似:jquery.js)
- 创建vue实例
- 代码演示
<head> //引入js文件夹里的vue <script src="./JS/vue.js"></script> </head> <body> <!-- 使用vue --> <div id="app"> <p>这是vue的区域了 app--</p> <p>获取vue的信息:{{msg}}</p> </div> <!-- 创建vue实例 --> <script> const vm = new Vue({ el:'#app',//获取element元素 data:{ msg:'hello vue', } }) </script> </body>
搭建vue项目
1.兼容性
Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。
2.安装nodejs
- Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP、Python、Perl、Ruby 等服务端语言平起平坐的脚本语言。发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。
- 通俗点讲 Node.js是一个JavaScript编程语言的运行环境,在没有node.js之前,JavaScript代码几乎只能在浏览器中运行,通过浏览器解释执行。浏览器其实也是JavaScript的一个运行环境,JavaScript在浏览器中运行主要是面向客户端这方面的。后来node.js诞生了,JavaScript就可以在node.js中来运行了,JavaScript可以基于node.js环境做服务端开发。所以node.js也是JavaScript的服务端运行环境。
- 官方下载地址(https://nodejs.org/en/) 或者中文网站(https://nodejs.org/zh-cn/download/)
- 一般选LTS长期稳定版嘛 基本功能都差不多,点击下载并安装
- 安装时,安装路径可以自由更改,最后英文路径或者默认,其它点下一步
- 安装后,打开Win+R,输入cmd,窗口中输入:node -v 或 npm -v 查看版本号
3.安装vue 命令行工具 (CLI)
- 介绍:Vue 提供了一个官方的 CLI,为单页面应用 (SPA) 快速搭建繁杂的脚手架。CLI是一个全局安装的 npm 包,提供了终端里的 vue 命令。它可以通过 vue create 快速搭建一个新项。
- 网址:https://cli.vuejs.org/zh/
- 版本:Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)
- 先安装yarn: npm i yarn -g (推荐)
- 安装vue-cli:
npm install -g @vue/cli (下载模块:npm install 模块 )
或者
yarn global add @vue/cli (下载模块:yarn add 模块 ) - 检查其版本是否正确
vue –version
4.创建一个vue项目–通过脚手架vue-cli
- 创建vue项目: vue create vue-project
说明:vue项目名称最好是英文 不能包含驼峰命名法 - 按需项目需要的依赖配置
- 进入项目
cd 项目名称 - 启动项目
npm run serve
或者
yarn serve - 打包项目
npm run build
目录结构
node_moudles 安装包依赖 –模块
public 单页面入口 - index.html
src 资源文件 – 前端
– – assets 静态文件资源 - 放置 css js images
– – components 公共组件 - 组件化 (样式 布局 效果)
– – App.vue 根组件
– – main.js 入口配置文件
.browserslistrc 浏览器配置
.gitignore 上传git仓库 忽略的文件配置
babel.config.js babel配置
package.json 项目配置文件 (查看项目安装的依赖 版本 名称… )
readme.md 项目说明文件
yarn.lock 配置信息 忽略
Vue组件组成
组成-三部分
- template 视图标签 (template标签不会被渲染 只是包裹作用) 必写
- script 逻辑代码
- style 样式 lang=’less/scss’ scoped
创建组件
- xxx.vue 后缀.vue结尾
- 三部分组件 快捷键 vue
组件使用
- 引入组件
- 注册组件
- 使用组件
<script> //1. 引入组件 import Banner from './components/Banner.vue' export default { name: 'App', //2. 注册组件 components: { Banner, } } </script> <!-- 3. 使用组件 --> <Banner></Banner>
vue基础语法
指令:就是以 v-指令=’js环境’ 具体特定的工具 ,指令。
插值操作 (模板语法)
- 作用:获取vue数据 显示视图 模板语法来声明式地将数据渲染进 DOM
- 语法:
Mustache
<div id="app">
<h2>{{message}}</h2>
<h2>{{message}}, 李银河!</h2>
<!--mustache语法中,不仅仅可以直接写变量,也可以写简单的表达式-->
// 获取data里的数据
<h2>{{firstName + lastName}}</h2>
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{counter * 2}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
// 提供数据
data: {
message: '你好啊',
firstName: 'kobe',
lastName: 'bryant',
counter: 100
},
})
</script>
指令介绍
v-once
在某些情况下,我们可能不希望界面随意的跟随改变
这个时候,我们就可以使用一个Vue的指令
v-once:
该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变。
代码如下:
<div id="app">
<h2>{{message}}</h2>
<h2 v-once>{{message}},李银河</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
v-html -原生HTML
某些情况下,我们从服务器请求到的数据本身就是一个HTML代码
如果我们直接通过插值语法来输出,会将HTML代码也一起输出
但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容
可以使用v-html指令
该指令后面往往会跟上一个string类型
会将string的html解析出来并且进行渲染
<div id="app">
<h2>{{url}}</h2>
<h2 v-html="url"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
url: '<a href="http://www.baidu.com">百度一下</a>'
}
})
</script>
v-text
v-text作用和Mustache比较相似:都是用于将数据显示在界面中
v-text通常情况下,接受一个string类型
缺点是不够灵活:第二个h2不会显示李银河
<div id="app">
<h2>{{message}}, 李银河!</h2>
<h2 v-text="message">, 李银河!</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
v-pre
v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
比如下面的代码
第一个h2元素中的内容会被编译解析出来对应的内容
第二个h2元素中会直接显示
<div id="app">
<h2>{{message}}</h2> //你好啊
<h2 v-pre>{{message}}</h2> //{{message}}
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
v-cloak
在某些情况下,我们浏览器可能会直接显然出未编译的Mustache标签
cloak: “斗篷”
<div id="app" v-cloak>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
// 在vue解析之前, div中有一个属性v-cloak
// 在vue解析之后, div中没有一个属性v-cloak
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
}, 1000)
</script>
条件渲染
条件渲染- v-if (v-else、v-else-if)
- 作用:是否显示元素/ true 显示 false 隐藏
语法:
<span v-if="boolean表达式"></span>
v-else
作用:是对 v-if=’’的结果取反
<span v-if="boolean表达式"></span>
<span v-else>xxxx </span>
v-else-if
作用:是否显示元素 与v-if v-else-if 多语句判断
<span v-if="boolean表达式"></span>
<span v-else-if="boolean表达式"></span>
案例:
<template>
<div>
<h2>条件渲染 vue-if</h2>
<!-- v-if='boolean' -->
<p>v-if的值:{{flag}}</p>
<p v-if="flag">我是v-if为true显示的</p>
<h4 v-else>我是v-else控制显示</h4>
<button @click="change()">点我控制v-if的值</button>
<!-- 多语句 -->
<p v-if="number>5"> number>5 </p>
<p v-else-if=" 2< number <=5"> number大于2小于等于5 </p>
<p v-else> number小于2 </p>
<input type="text" placeholder="请输入数字来判断number" v-model="number">
<br>
<span>{{number}}</span>
</div>
</template>
<script>
export default {
data(){
return{
flag:false,
number:"",
}
},
methods:{
change(){
this.flag=!this.flag
}
}
}
</script>
v-show
- 作用:是否显示元素/ true 显示 false 隐藏
语法:
特点:
控制元素的 display:block/none
<span v-show="boolean表达式"></span>
列表渲染- v-for
1. 遍历数组
语法:
<li v-for="(item,index) in arr" :key="">
{{ item }}
</li>
- 属性
- item 第一个元素 表示数组的每一项内容
- index 第二个元素 表示数组的下标 0 1
- arr 数组数据(或者对象)
- :key其实是 v-bind属性 作用:做当前数据的唯一标识 一般写的是id 不推荐 index
2. 遍历对象
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
- value 对象里每个键值对的值({key:value}中的value)
- key 对象里每个键值对的键名({key:value}中的key)
- index 下标0 1
- object 要遍历的对象名
案例:
<template>
<div>
<h2>数组遍历- v-for</h2>
<p>直接获取数组数据:arr{{ arr }}</p>
<p>遍历数组</p>
<ul>
<li v-for="(item, index) in arr" :key="item.id">
每一项 {{ item }} -- 下标 {{ index }}
</li>
</ul>
--------------------------------------------------
<p>遍历内部是对象的数组</p>
<ul>
<li v-for="(item, index) in books" :key="index">
<h3>书名:{{ item.name }}</h3>
<p>价格:{{ item.price }}</p>
</li>
</ul>
----------------------------------------------------
<p>遍历对象</p>
<ul>
<li v-for="(ele,key) in obj " :key="key">
<p>{{key}}::{{ele}}</p>
<!-- <p>姓名:{{ele.uname}}</p>
<p>年龄:{{ele.age}}</p> -->
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
arr: [1, 2, 3, 4],
books: [
{
id: 1,
name: "三国",
price: 20,
},
{
id: 2,
name: "西游记",
price: 30,
},
{
id: 3,
name: "红楼梦",
price: 40,
},
],
obj: {
uname: "张三",
age: 20,
},
};
},
};
</script>
3. v-for 与 v-if 一同使用
- 注意不推荐在同一元素上使用 v-if 和 v-for 、v-for 的优先级比 v-if 更高
解决办法:
<template>
<div>
<h4>4 v-for 与 v-if 一同使用, v-for 的优先级比 v-if 更高</h4>
<h4>今天上架了什么水果:</h4>
<ul>
<template v-for="(item) in zaoshi">
<li :key="item.id" v-if="item.flag">
种类:{{item.fruit}}
</li>
</template>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
zaoshi:[
{
id:100,
fruit:'苹果',
flag:true,
},
{
id:101,
fruit:'香蕉',
flag:false,
},
{
id:102,
fruit:'阳光玫瑰',
flag:true,
},
{
id:103,
fruit:'车厘子',
flag:false,
},
]
};
},
};
</script>
Vue 事件处理
- 介绍
可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码 - 定义事件
语法:<div v-on:事件名=’dosomething’>
函数dosomething定义的位置:
要求定义mothds属性中 - 事件:
this指向:事件的this指向 当前组件实例对象
事件传递参数:事件传递参数 v-on:click=’canshu(1,2)’
事件对象event:
- 函数不带参数 第一个参数默认是事件对象 event
- 函数带参数 事件对象需要手动传递 $event
v-on:事件名=’函数’
简写:
@事件名=’函数’
- 事件修饰符
Vue.js 为 v-on 提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。.stop
.prevent
.capture
.self
.once
.passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
<template>
<div>
<h2>vue事件处理</h2>
<!-- 事件修饰符 -->
<div @click="parent"> //父元素
我是小头爸爸
<button @click.stop="child">我是大头儿子</button> //子元素
</div>
</div>
</template>
<script>
export default {
methods:{
parent(){
console.log('父元素');
},
child(){
console.log('子元素');
},
}
}
</script>
- 按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:
.enter *
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<template>
<div>
<!-- 按键修饰符 -->
<input type="text" v-on:keyup.enter='getInput'>
</div>
</template>
<script>
export default {
methods:{
getInput(e){
//if(e.keyCode == 13) {
// console.log('按下了回车键--触发是搜索。。。');
//}
console.log('按下了回车键--触发是搜索。。。');
}
}
}
</script>
系统修饰键
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta<template> <div> <!-- 系统修饰键 --> <!-- 可以按下ctrl+回车键触发 --> <textarea @keyup.ctrl.enter="send" cols="30" rows="10"></textarea> <button @click="send">发送</button> // </div> </template> <script> export default { methods: { // 系统修饰键 send(){ console.log('系统修饰键--发送了聊天信息'); } }, }; </script>
鼠标按钮修饰符
.left
.right
.middle
Vue中key属性的作用 (考点)
- 作用:key的作用主要是为了高效的更新虚拟DOM
- 高效的Diff算法
<template> <div> <h2>vue中遍历数据v-foe是否添加key 功能</h2> <p>key作用:提高更新虚拟DOM速度 --底层diff算法--查思路</p> <!-- 默认不带key的遍历 --> <ul> <li v-for="item in arr">{{ item }}</li> <button @click="addF">插入F元素</button> </ul> <!-- 带key的遍历 --> <ul> <li v-for="item in arr" :key="item">{{ item }}</li> <button @click="addF">插入F元素</button> </ul> </div> </template> <script> export default { data() { return { arr: ["A", "B", "C", "D", "E"], }; }, methods: { addF() { // 增加 F (给数组添加元素 arr.splice(下标,删除的个数,添加的值)) this.arr.splice(2, 0, "F"); }, }, }; </script>
数组更新检测
- 说明:在列表渲染中,如果遍历是数组,当数组数据发生改变时,页面什么时候能自动更新(页面重新渲染)
- 实现数组视图同步更新
变更方法 (修改了原数组)
push()
pop()
shift()
unshift()
splice()
sort()
reverse()替换数组(修改后返回新的数组 原数据不修改 视图想同步更新 覆盖原数组)
filter()、concat() 和 slice()
<template>
<div>
<h2>数组更新同步</h2>
<p>arr:{{ arr }}</p>
<button @click="addArr">追加数组</button>
<button @click="sliceArr">切割数组</button>
</div>
</template>
<script>
export default {
data() {
return {
arr: [1, 2, 3],
};
},
methods: {
addArr() {
// this.arr.push(100)
this.arr.reverse();
},
sliceArr() {
//slice() 返回新的数组 n ce(1);
console.log(newArr);
//替换
this.arr = newArr;
},
},
};
</script>
对象更新检测
- 说明:对象修改后 视图同步更新视图 – 内存:栈内存 堆内存
- 实现对象视图同步更新
<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 { data(){ return{ obj:{ uname:'张三', age:20 } } }, methods:{ changeUname(){ this.obj.uname = '拉拉' }, addAttribute(){ // this.obj.love = '女' // 问题: 视图检测不到变化 vue认为obj没有修改 // 方法一:对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中 // this.obj = {...this.obj} // 方法二: es6合并对象 Object.assign({},{},{}) // this.obj = Object.assign({},this.obj) // 方法三: vue官网解决方法 // Vue.set( target, propertyName/index, value ) /**参数: {对象 | 数组} target 目标元素 {string | number} propertyName/index (要添加的属性)数据类型名字或者index {any} value 属性的值 用法:向响应式对象中添加一个 property(属性),并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi') **/ //这里没有引入Vue了,因为组件实例对象vm身上有$set()方法 this.$set(this.obj,'love','女') //删除 同步视图 删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。 this.$delete(this.obj,'age') } } } </script>
Class 与 Style 绑定
介绍:动态的添加class或者是style样式
1.绑定 HTML Class
- 直接绑定变量
<div v-bind:class='变量'></div>
- 对象语法 (最常用)
<div v-bind:class="{类名: 表达式-true显示类名、false隐藏 ,类名:boolean}"></div>
- 数组语法
<div v-bind:class="[变量1,变量2, {类名:boolean}]"></div>
2.绑定内联样式
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' } }
完整练习案例:
<template>
<div>
<h2>动态绑定样式class 和 style</h2>
<h4>动态绑定样式class</h4>
<!-- 绑定变量 -->
<button @click="active = 'box2'">切换颜色-绑定变量</button>
<div v-bind:class="active">动态绑定样式class</div>
<hr />
<!-- 对象语法 -->
<div v-bind:class="{ box: flag }">对象语法</div>
<button @click="flag = !flag">修改flag-对象语法</button>
<hr />
<!-- 数组语法 -->
<div class="aa" v-bind:class="[active, { box2: true }]">数组语法</div>
<hr />
<h2>动态绑定内联样式</h2>
<p>0. 默认的内联写法</p>
<div style="width: 100px; height: 100px; background: orange">
默认的内联写法
</div>
<p>1. 直接变量</p>
<div v-bind:style="styleObject">
对象语法
</div>
<p>2. 对象语法</p>
<div v-bind:style="{color:'green',fontSize:'30px', width:'100px',height: '100px',backgroundColor:'blue'}">
对象语法
</div>
<p>3. 数组语法</p>
<div :style="[styleObject,{border:'5px solid #333'}]">数组语法</div>
</div>
</template>
<script>
export default {
data() {
return {
active: "box",
flag: "true",
styleObject:{
width: '100px',
height: '100px',
background: 'orange',
}
};
},
methods: {
changeColor() {
this.active = "box2";
},
},
};
</script>
<style>
.box {
width: 200px;
height: 200px;
background-color: pink;
}
.box2 {
width: 200px;
height: 200px;
background-color: rgb(21, 226, 253);
}
</style>
Vue-tab栏切换练习
<template>
<div>
<h2>Vue-tab切换</h2>
<ul class="nav">
<li v-for="(item,index) in arr" :key='item' :class="{active:index == num}" @click="changeNav(index)">
{{item}}-{{index}}
</li>
</ul>
<div class="box1">
<div v-for="(ele,n) in content " :key="ele" :class="{show:n == num}">{{ele}}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
num: 0,
arr: ["选项1", "选项2", "选项3"],
content: ["111", "222", 333],
};
},
methods: {
changeNav(index){
this.num = index
}
},
};
</script>
<style lang="less" scoped>
.nav {
overflow: hidden;
list-style: none;
li {
display: inline;
width: 100px;
height: 40px;
line-height: 40px;
margin-right: 10px;
}
.active{
background: lightblue;
}
}
.box1 {
margin: auto;
width: 400px;
height: 200px;
border: 1px solid #000;
>div {
display: none;
}
.show {
display: block;
}
}
</style>
表单输入绑定 (v-modele)
1.介绍
你可以用 v-model 指令在表单 input、textarea 及 select 元素上创建双向数据绑定
通过指令 v-model=’’ 获取表单输入的信息数据 实现双向数据绑定
2.语法:
会将文本框输入的数据实时传递给绑定到data里的msg中
<input type='text' v-model='msg' />
data(){
return{
msg:''
}
}
案例:
<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>
</div>
</template>
<script>
export default {
data() {
return {
msg:'初始值',
sex:'',
//对象的语法--------存储表单数据
formData: {
msg: "", //输入框
sex: 1, //性别
arr: [],
select: "",
},
};
},
methods:{
send() {
console.log("输入的数据为:", this.msg);
},
submit() {
//点击按钮--发送输入的数据给后台-- data -- msg sex arr ...
console.log("提交注册信息表单",this.formData);
},
}
};
</script>
3.修饰符
- lazy 只有当input失去焦点时才更新数据
- number 把input标签中输入的内容转成数字,调用是parseFloat (Nunber())
- trim 去除左右空格
案例:
<template>
<div>
<h3>表单修饰符 -修饰符 </h3>
<!-- .lazy 失去焦点或者回车 获取数据 -->
<input type="text" v-model.lazy="search">
<p>search:{{ search }}</p>
<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>
</div>
</template>
<script>
export default {
data() {
return {
msg:'',
sex:'',
search:'',
num:'只能输入数字',
};
},
methods:{
}
};
</script>
4.v-model实现原理
v-model只不过是一个语法糖而已,真正的实现靠的还是
v-bind:绑定响应式数据
触发oninput 事件并传递数据
v-model 是什么。语法糖 :value + @input。还要分为两种情况
<input v-model="val">
<!-- 基本等价于,因为内部还有一些其他的处理 -->
// $event是事件对象,$event.target.value表示input框中的输入值
<input :value="val" @input="val = $event.target.value">
案例:
<template>
<div>
<!-- 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:'请输入',
msg:'',
inp:'',
sex:'',
search:'',
num:'只能输入数字',
};
},
methods:{
changeVal(e){
console.log(e); //表单的事件对象
console.log(e.target.value); //表单里的文本框内容
this.val = e.target.value; //将文本框内容 赋值给 data里的val 即使用v-bind又让数据进行双向绑定了
}
}
};
</script>
计算属性和侦听器
1. 计算属性
- 介绍: 处理数据后把数据缓存起来 使用数据的时候使用的缓存的数据,但是如果原数据修改了重新计算
- 语法
<template> <div> <h2>计算属性computed</h2> <!-- 如果是字符串 取反操作实现 --> <p>字符串:{{ msg }}</p> <!-- 不推荐: 模板语法里面写很多方法 多次使用不方便 --> // split-先转换为数组, reverse-然后取反, join-最后转为字符串 <p>字符串-取反:{{ msg.split("").reverse().join("") }}</p> <p>封装函数-取反:{{qufan()}}</p> <p>封装函数-取反:{{qufan()}}</p> <p>封装函数-取反:{{qufan()}}</p> <p>计算属性-取反:{{msg2}}</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)=>{ // if(item.flag == true) { // return item.flag // } return item.flag }) } }, }; </script>
2. 侦听器
- 介绍: Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化
<template> <div> <h2>侦听器-watch</h2> <p>功能:监听数据修改了,然后做业务逻辑</p> <input type="text" v-model="inp" name="" id=""> </div> </template> <script> export default { data(){ return{ inp:'', arr:[] } }, //侦听器--数据变化 (当前监听的是inp变化) watch:{ inp:function(n,o){ console.log('新值:',n ,'旧值:',o); //业务逻辑 比如输入东西后 网络请求 //模糊查询 } } } </script>
3. computed和watch区别 (考点)
- 相同:computed和watch都是观察页面的数据变化的。
- 不同:
computed:是计算属性,依赖其它属性值: - 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
watch:没有缓存性,更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作; - 不支持缓存,数据变,直接会触发相应的操作;
- watch支持异步;
Vue 的生命周期方法有哪些 一般在哪一步发请求
生命周期:事物从诞生到消亡的过程
Vue生命周期:
v-if 和 v-show 的区别
v-if: 控制元素的渲染或者销毁
v-show:控制元素的 display:block/none
场景:
频繁切换: v-show
初次渲染优化:v-if
Vue 修饰符有哪些
v-for 为什么要加 key
理解 Vue 的单向/双向 数据流
首先了解一下数据绑定
什么是绑定?
比如当前href属性值取决于表达式school.url.toUpperCase()的结果,这两者之间就是有绑定关系,且通过v-bind指令完成数据绑定。
<a v-bind:href="school.url.toUpperCase()" v-bind:x="hello">点我去{{school.name}}学习</a>
v-bind 单向数据原理
前面学习的指令主要作用是将值插入到模板的内容当中
但除了内容需要动态来决定外,某些属性也希望动态来绑定
作用:动态绑定属性
缩写:**:**
预期:any (with argument) | Object (without argument)
参数:attrOrProp (optional)
v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到Vue进阶时介绍)
在开发中,一般有哪些属性需要动态进行绑定呢?
比如图片的链接src、网站的链接href、动态绑定一些类、样式等等
例子:通过Vue实例中的data绑定元素的src和href,代码如下:
基本使用
很多时候,我们希望动态的来切换class,比如:
当数据为某个状态时,字体显示红色。
当数据另一个状态时,字体显示黑色。
<div id="app">
<!-- 错误的做法: 这里不可以使用mustache语法-->
<!--<img src="{{imgURL}}" alt="">-->
<!-- 正确的做法: 使用v-bind指令 -->
<img v-bind:src="imgURL" alt="">
<a v-bind:href="aHref">百度一下</a>
<!--<h2>{{}}</h2>-->
<!--语法糖的写法-->
<img :src="imgURL" alt="">
<a :href="aHref">百度一下</a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
imgURL: 'https://img11.360buyimg.com/mobilecms/s350x250_jfs/t1/20559/1/1424/73138/5c125595E3cbaa3c8/74fc2f84e53a9c23.jpg!q90!cc_350x250.webp',
aHref: 'http://www.baidu.com'
}
})
</script>
v-bind动态绑定class(对象语法)
- 绑定方式:对象语法
含义是:class后面跟的是一个对象
- 直接通过{}绑定一个类
<h2 :class="{'active': isActive}">Hello World</h2>
- 也可以通过判断,传入多个值
<h2 :class="{'active': isActive, 'line': isLine}">Hello World</h2>
- 和普通的类同时存在,并不冲突
注:如果isActive和isLine都为true,那么会有title/active/line三个类<h2 class="title" :class="{'active': isActive, 'line': isLine}">Hello World</h2>
- 如果过于复杂,可以放在一个methods或者computed中
注:classes是一个计算属性<h2 class="title" :class="classes">Hello World</h2>
比如ul的li标签点击某个标签变颜色
<div id="app">
<!-- 当布尔值为true 这个类名1即 active 就会被添加到标签上 -->
<!-- 一个 { } 表示对象 -->
<h2 class="title" v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
<h2 class="title" v-bind:class="getClasses()">{{message}}</h2>
<button v-on:click="btnClick">按钮</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
isActive: true,
isLine: true
},
methods: {
btnClick: function () {
this.isActive = !this.isActive
},
getClasses: function () {
return {active: this.isActive}
}
}
})
</script>
v-bind动态绑定class(数组语法)
- 数组语法的含义是:class后面跟的是一个数组。
- 直接通过{}绑定一个类
<h2 :class="['active']">Hello World</h2>
- 也可以传入多个值
<h2 :class=“[‘active’, 'line']">Hello World</h2>
- 和普通的类同时存在,并不冲突
注:会有title/active/line三个类<h2 class="title" :class=“[‘active’, 'line']">Hello World</h2>
- 如果过于复杂,可以放在一个methods或者computed中
注:classes是一个计算属性<h2 class="title" :class="classes">Hello World</h2>
例如:
<div id="app">
<h2 class="title" :class="[active, line]">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好啊',
active: 'aaaaaa',
line: 'bbbbbbb'
},
methods: {
getClasses: function () {
return [this.active, this.line]
}
}
})
</script>
小案例 点击li标签变色(默认第一li为红色)
分析:
- v-for绑定给li标签,同时v-on添加点击事件,并且li标签的class用v-bind动态绑定
- 使用v-for绑定到li标签上,自动遍历data中的数据,将下标(index)和每一项内容(item)用插值语法显示到页面
- 在data中添加一个isRed属性值为0,想让class样式显示,需要v-bind绑定的red值为true,即该值可以等等于index,因为index的第一个值就是0
- v-on点击事件点击某一个li,将下标的值赋值给isRed,即当前点击的li标签的class样式显示 end~
<style> .red { color: red; } </style> <!--作业需求: 点击列表中的哪一项, 那么该项的文字变成红色--> <div id="app"> <ul> <!-- <li v-for="每一项,下标 in 数据源">{{item}}</li> --> <li v-for="(item,index) in movie" v-on:click="getColor(index)" v-bind:class="{red:isRed==index}" >{{index}}--{{item}}</li> </ul> </div> <script> const app = new Vue({ el:'#app', data:{ isRed:0, movie:['海王','海尔兄弟','火影忍者','进击的巨人'] }, methods:{ getColor: function (index){ this.isRed = index console.log(this.isRed); } }, }) </script>
v-bind绑定style 一
利用v-bind:style来绑定一些CSS内联样式
在写CSS属性名的时候,比如font-size
可以使用驼峰式 (camelCase) fontSize
或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’
v-model 双向数据原理
Vue2.x响应式数据/双向绑定原理
整体思路是数据劫持+观察者模式
Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据。其中,View变化更新Data,可以通过事件监听的方式来实现,所以 Vue数据双向绑定的工作主要是如何根据Data变化更新View。
Vue中有两种数据绑定的方式:
- 单向绑定(v-bind):数据只能从data流向页面。
- 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
备注: - 双向绑定一般都应用在表单类元素上(如:input、select等)
- v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。
<!-- 准备好一个容器--> <div id="root"> <!-- 普通写法 --> <!-- 单向数据绑定:<input type="text" v-bind:value="name"> 双向数据绑定:<input type="text" v-model:value="name"> <!-- 简写 --> 单向数据绑定:<input type="text" v-bind:value="name"> 双向数据绑定:<input type="text" v-model:value="name"> <!-- 如下代码是错误的,因为v-model只能应用在表单类元素(输入类元素)上 --> <!-- <h2 v-model:x="name">你好啊</h2> --> </div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#root', data:{ name:'哔哩哔哩', } }) </script>
虚拟 DOM 是什么 有什么优缺点
MVVM
全称: Model-View-ViewModel , Model 表示数据模型层。 view 表示视图层, ViewModel 是 View 和 Model 层的桥梁,数据绑定到 viewModel 层并自动渲染到页面中,视图变化通知 viewModel 层更新数据。
- Model层:
数据层
数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
- View层:
视图层
在我们前端开发中,通常就是DOM层。
主要的作用是给用户展示各种信息。
- VueModel层:
视图模型层
视图模型层是View和Model沟通的桥梁。
一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。
- M:模型(Model) :对应 data 中的数据
- V:视图(View) :模板
- VM:视图模型(ViewModel) : Vue 实例对象
Vm(Vue实例对象)把左边的View和右边Model进行连接在一起
观察发现:
- data中所有的属性,最后都出现在了vm身上。
- VM身上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
执行过程 :数据在data中经过 VM视图模型放到了页面View上页面上如果有地方需要更改要映射回数据就再给VM视图模型,然后视图模型再给data里的数据
<!-- 1 准备好一个容器 也就是 view 视图 模板代码-->
<div id="root">
<h1>学校名称:{{name}}</h1>
<h1>学校地址:{{address}}</h1>
<!-- <h1>测试一下1:{{1+1}}</h1>
<h1>测试一下2:{{$options}}</h1>
<h1>测试一下3:{{$emit}}</h1>
<h1>测试一下4:{{_c}}</h1> -->
</div>
<script type="text/javascript">
Vue.config.productionTip = fal se //阻止 vue 在启动时生成生产提示
const vm = new Vue({// 2 VM 视图模型ViewModel
el:'#root',
data:{ // 3 data里的是模型 model
name:"b站大学",
address:"成都",
}
})
console.log(vm)
</script>
Vue的数据代理
首先学习下 Object.defineProperty()方法
Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
defineProperty()参数
Object.defineProperty(obj, prop, descriptor)
- obj 需要定义属性的对象
- prop 需被定义或修改的属性名
- descriptor 需被定义或修改的属性的描述符
例子:定义了一个person对象,里面包含name、sex属性和其它属性值。
注意:age属性是通过defineProperty方法中
<script type="text/javascript">
let number = 19
let person = {
name: '张三',
sex: '男',
}
Object.defineProperty(person, 'age', {
value:19,
enumerable:true, //控制属性是否可以枚举,默认值是false
writable:true, //控制属性是否可以被修改,默认值是false
configurable:true //控制属性是否可以被删除,默认值是false
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
console.log('有人读取age属性了')
return number
},
//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value) {
console.log('有人修改了age属性,且值是', value)
number = value
}
})
console.log(Object.keys(person))
// Object.keys方法传入一个对象作为参数,可以把传入对象所有属性的属性名提取出来变成数组
console.log(person)
</script>
Vue中的数据代理
什么是数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
<script type="text/javascript" >
let obj = {
x:100
}
let obj2 = {
y:200
Object.defineProperty(obj2,'x',{
get(){
return obj.x
},
set(value){
obj.x = value
}
})
</script>
vue常用ui库
移动端
- mint-ui (http://mint-ui.github.io/#!/zh-cn)
- Vant(https://youzan.github.io/vant/#/zh-CN/home)
- VUX (https://vux.li/)
pc端
- element-ui(https://element.eleme.cn/2.13/#/zh-CN/component/installation)
- Ant Design of Vue(https://www.antdv.com/docs/vue/introduce-cn/)
- Avue (https://avuejs.com/)
常用webpack配置
待更新。。。