1. Vue概述
尤雨溪:Vue.js的创建者
- 2014年2月,Vue.js正式发布
- 2015年10月27日,正式发布1.0.0
- 2016年4月27日,发布2.0的预览版本
Vue:渐进式JavaScript框架
声明式渲染→组件系统→客户端路由→集中式状态管理→项目构建
官网:https://cn.vuejs.org/v2/guide/
- 易用:熟悉HTML、CSS、JavaScript知识后,可快速上手Vue
- 灵活:在一个库和一套完整框架之间自如伸缩
- 高效:20kB运行大小,超快虚拟 DOM
Vue渐进式: Vue从基础开始, 会循序渐进向前学习, 如下知识点可能你现在不明白, 但是学完整个vue回过头来看, 会很有帮助
小结
1. Vue是什么?
- Vue是一个javaScript渐进式框架
2. 什么是渐进式?
- 渐进式就是按需逐渐集成功能使用
3. 什么是库和框架?
- 库是方法的集合, 一般是个js文件
- 框架是拥有自己一套规则和语法
2. Vue基本使用
2.1 开发方式
传统开发模式:基于html/css/js文件开发Vue
工程化(脚手架)开发方式:在webpack环境中开发Vue,这是最推荐, 企业常用的方式
3.@vue/cli脚手架
3.1 @vue/cli和脚手架介绍
概念
脚手架是为了保证各施工过程顺利进行而搭设的工作平台
好处
- 开箱即用
- 0配置webpack
- babel支持
- css, less支持
- 开发服务器支持
小结
1. 用Vue开发项目,需要自己配置webpack?
- Vue官方提供了脚手架, 一套标准的文件夹+文件结构+webpack配置,快速搭建项目基本环境
2. 使用脚手架的好处是什么?
- 零配置,开箱即用,基于它快速搭建项目基本开发环境
3.2 脚手架-准备
安装步骤
- 全局安装@vue/cli 模块包
- win系统:
npm i @vue/cli -g
- mac系统:
sudo npm i @vue/cli -g
- 查看
Vue
命令版本
vue -V
3.3 脚手架-创建项目-启动服务
创建脚手架步骤
- 创建项目(注意: 项目名不能带大写字母, 中文和特殊符号)
//vue和create是命令, vuecli-demo是自己的文件夹名
vue create vuecli-demo
// 1. 基于 交互式命令行 的方式,创建 新版 vue 项目
vue create my-project
// 2. 基于 图形化界面 的方式,创建 新版 vue 项目
vue ui
// 3. 基于 2.x 的旧模板,创建 旧版 vue 项目
npm install -g @vue/cli-init
vue init webpack my-project
- 选择模板
可以上下箭头选择, 回车确定, 弄错了ctrl+c从第1步来
3. 选择包管理器
4. 等待下载脚手架项目, 需要的依赖包
5. 终端切换脚手架项目下, 启动内置的==webpack热更新开发服务器
cd vuecil-demo
yarn serve
# 或 npm run serve
3.4 脚手架-目录分析
脚手架里主要文件和作用
- node_modules - 都是下载的包
- public/index.html - 浏览器运行的网页
- src/main.js - webpack打包的入口
- src/App.vue - Vue页面入口
- package.json - 项目描述信息
3.5 脚手架-代码和结构分析
一切从main.js开始, 到index.html结束
main.js和App.vue以及index.html作用和关系?
- main.js - 项目打包入口 - Vue初始化
- App.vue - Vue页面入口
- index.html - 浏览器运行的文件
- App.vue => main.js => index.html
3.6 脚手架-自定义配置
1. 通过 package.json 配置项目
// 必须是符合规范的json语法
"vue": {
"devServer": {
"port": "8888",
"open" : true
}
},
注意:不推荐使用这种配置方式。因为 package.json 主要用来管理包的配置信息;为了方便维护,推荐将 vue 脚手架相关的配置,单独定义到 vue.config.js 配置文件中。
2. 通过单独的配置文件配置项目
- 在项目的跟目录创建文件 vue.config.js
- 在该文件中进行相关配置,从而覆盖默认配置
// vue.config.js
module.exports = {
devServer: {
port: 8888;
}
}
3.7 脚手架-eslint了解
eslint是一个插件, 内置在脚手架项目里配置好了, 运行时检查你的代码风格
例子:
- 先在main.js 随便声明个变量, 但是不要使用
2.运行后观察发现, 终端和页面都报错了
这样的错误, 证明eslint发现你代码不严谨
- 解决方式
- 方式1: 手动解决掉错误
- 方式2: 暂时关闭eslint检查,在vue.config.js中配置后重启服务
3.8 脚手架-单vue文件
- template里只能有一个根标签
- vue文件-独立模块-作用域互不影响
- style配合scoped属性, 保证样式只针对当前template内标签生效
- vue文件配合webpack, 把他们打包起来插入到index.html
<!-- template必须, 只能有一个根标签, 影响渲染到页面的标签结构 -->
<template>
<div>欢迎使用vue</div>
</template>
<!-- js相关 -->
<script>
export default {
name: 'App'
}
</script>
<!-- 当前组件的样式, 设置scoped, 可以保证样式只对当前页面有效 -->
<style scoped>
</style>
小结
1. 单vue文件的好处?
- 独立作用域,不再担心变量重名问题
2. 单vue文件使用注意事项?
- template里只能有一个根标签
3. 单vue文件里标签和样式最后怎么显示到页面?
- webpack打包后, 插入到index.html显示
3.9 脚手架-清理欢迎界面
- src/App.vue默认有很多内容, 可以全部删除留下框
<template>
<div></div>
</template>
<script>
export default {
}
</script>
<style>
</style>
- assets 和 components 文件夹下的一切删除掉 (不要logo和HelloWorld页面)
4.Element-UI 的基本使用
Element-UI:一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
官网地址为: http://element-cn.eleme.io/#/zh-CN
4.1 基于命令行方式手动安装
- 安装依赖包 npm i element-ui –S
- 导入 Element-UI 相关资源
// 导入组件库
import ElementUI from 'element-ui';
// 导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css';
// 配置 Vue 插件
Vue.use(ElementUI);
4.2 基于图形化界面自动安装
- 运行
vue ui
命令,打开图形化界面 - 通过
Vue 项目管理器
,进入具体的项目配置面板 - 点击
插件 -> 添加插件
,进入插件查询面板 - 搜索
vue-cli-plugin-element
并安装 - 配置插件,实现按需导入,从而减少打包后项目的体积
5. Vue模板语法
5.1 模板语法概述
1. 如何理解前端渲染?
2. 前端渲染方式
- 原生js拼接字符串
- 使用前端模板引擎
- 使用vue特有的模板语法
3. 原生js拼接字符串
基本上就是将数据以字符串的方式拼接到HTML标签中
var d = data.weather;
var info = document.getElementById('info');
info.innerHTML = '';
for(var i=0;i<d.length;i++){
var date = d[i].date;
var day = d[i].info.day;
var night = d[i].info.night;
var tag = '';
tag += '<span>日期:'+date+'</sapn><ul>';
tag += '<li>白天天气:'+day[1]+'</li>'
tag += '<li>白天温度:'+day[2]+'</li>'
tag += '<li>白天风向:'+day[3]+'</li>'
tag += '<li>白天风速:'+day[4]+'</li>'
tag += '</ul>';
var div = document.createElement('div');
div.innerHTML = tag;
info.appendChild(div);
}
缺点:不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来。
4. 使用前端模板引擎
基于模板引擎art-template的一段代码,与拼接字符串相比,代码明显规范了很多,它拥有自己的一套模板语法规则。
语法: {{ 表达式 }}
<template>
<div>
<h1>{{ msg }}</h1>
<h2>{{ obj.name }}</h2>
<h3>{{ obj.age > 18 ? '成年' : '未成年' }}</h3>
</div>
</template>
<script>
export default {
data() { // 格式固定, 定义vue数据之处
return { // key相当于变量名
msg: "hello, vue",
obj: {
name: "小vue",
age: 5
}
}
}
}
</script>
优点:大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期的维护。
缺点:没有专门提供事件机制。
5. 模板语法概览
- 插值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
5.2 指令
1. 什么是指令?
属性
- 指令的本质就是自定义属性
- 指令的格式:以v-开始(比如:v-cloak)
2. v-cloak指令用法
- 插值表达式存在的问题:“闪动”
- 如何解决该问题:使用v-cloak指令
- 解决该问题的原理:先隐藏,替换好值之后再显示最终的值
官网:https://cn.vuejs.org/v2/api/
3. 数据绑定指令
v-text
填充纯文本
- 相比插值表达式更加简洁
v-html
填充HTML片段 - 存在安全问题
- 本网站内部数据可以使用,来自第三方的数据不可以用
v-pre
填充原始信息 - 显示原始信息,跳过编译过程(分析编译过程)
5.3 双向数据绑定指令
1. 什么是双向数据绑定?
- 数据变化 -> 视图自动同步
- 视图变化 -> 数据自动同步
设计模式: 是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。(代码分层, 架构设计)
2. MVVM设计思想
MVVM,一种软件架构模式,决定了写代码的思想和层次
- M: model数据模型 (data里定义)
- V: view视图 (页面标签)
- VM: ViewModel视图模型 (vue.js源码)
MVVM通过数据双向绑定
让数据自动地双向同步 不再需要操作DOM
- V (修改视图) -> M(数据自动同步)
- M(修改数据) -> V (视图自动同步)
5.4 事件绑定
1. Vue如何处理事件?
- v-on指令用法
<input type=‘button' v-on:click='num++'/>
- v-on简写形式
<input type=‘button' @click='num++'/>
2. 事件函数的调用方式
- 直接绑定函数名称
<button v-on:click='say'>Hello</button>
- 调用函数
<button v-on:click='say()'>Say hi</button>
案例:点击随机生成笑话
<template>
<div>
<p>{{ word }}</p>
<button @click="jockBtnFn">点击说笑话</button>
</div>
</template>
<script>
export default {
data(){
return {
word: '这里是一条笑话',
jockArr: ['我去相亲网站去了, 那你找到对象了吗? 不! 我找到了他们网站的一个Bug', '这个需求很简单, 怎么实现我不管, 明天上线', '程序员是推动这个世界进步的人']
}
},
methods: {
jockBtnFn(){
let randNum = Math.floor(Math.random() * this.jockArr.length)
let str = this.jockArr[randNum]
this.word = str
}
}
}
</script>
3. 事件函数参数传递
普通参数和事件对象
<template>
<div>
<a @click="one" href="http://www.baidu.com">阻止百度</a>
<hr>
<a @click="two(10, $event)" href="http://www.baidu.com">阻止去百度</a>
</div>
</template>
<script>
export default {
methods: {
one(e){
e.preventDefault()
},
two(num, e){
e.preventDefault()
}
}
}
</script>
4. 事件修饰符
语法:@事件名.修饰符="methods里函数"
- .stop 阻止冒泡
- .prevent 阻止默认行为
<template>
<div @click="fatherFn">
<!-- vue对事件进行了修饰符设置, 在事件后面.修饰符名即可使用更多的功能 -->
<button @click.stop="btn">.stop阻止事件冒泡</button>
<a href="http://www.baidu.com" @click.prevent="btn">.prevent阻止默认行为</a>
</div>
</template>
<script>
export default {
methods: {
fatherFn(){
console.log("father被触发");
},
btn(){
console.log(1);
}
}
}
</script>
5. 按键修饰符
语法:
@keyup.enter
- 监测回车按键@keyup.esc
- 监测返回按键
<template>
<div>
<input type="text" @keydown.enter="enterFn">
<hr>
<input type="text" @keydown.esc="escFn">
</div>
</template>
<script>
export default {
methods: {
enterFn(){
console.log("enter回车按键了");
},
escFn(){
console.log("esc按键了");
}
}
}
</script>
6. 自定义按键修饰符
全局 config.keyCodes 对象
Vue.config.keyCodes.f1 = 112
案例:翻转世界
需求:点击按钮 - 把文字取反显示 - 再点击取反显示(回来了)
<template>
<div id="app">
<h1>{{msg}}</h1>
<button @click="btn">逆转</button>
<button @click="tra">世界</button>
</div>
</template>
<script>
export default {
data() {
return {
msg:"逆转世界"
}
},
methods: {
btn(){
this.msg = this.msg.split('').reverse().join('');
},
tra(){
this.msg=this.msg.substring(2,4)
}
},
}
</script>
<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
h1{
color: red;
font-size: 160px;
}
</style>
5.5 属性绑定
1. Vue如何动态处理属性?
- 语法:
v-bind:属性名="vue变量"
- 简写:
:属性名="vue变量"
<!-- vue指令-v-bind属性动态赋值 -->
<a v-bind:href="url">我是a标签</a>
<img :src="imgSrc">
2. v-model的低层实现原理分析
<input v-bind:value="msg" v-on:input="msg=$event.target.value">
5.6 样式绑定
1. class样式处理
对象语法
语法:
- :class="{类名: 布尔值}"
<template>
<div>
<!-- 语法:
:class="{类名: 布尔值}"
使用场景: vue变量控制标签是否应该有类名
-->
<p :class="{red_str: bool}">动态class</p>
</div>
</template>
<script>
export default {
data(){
return {
bool: true
}
}
}
</script>
<style scoped>
.red_str{
color: red;
}
</style>
数组语法
<div v-bind:class="[activeClass, errorClass]"></div>
2. style样式处理
对象语法
语法
- :style="{css属性: 值}"
<template>
<div>
<!-- 动态style语法
:style="{css属性名: 值}"
-->
<p :style="{backgroundColor: colorStr}">动态style</p>
</div>
</template>
<script>
export default {
data(){
return {
colorStr: 'red'
}
}
}
</script>
<style>
</style>
数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
5.7 分支循环结构
1. 分支结构
- v-if
- v-else
- v-else-if
- v-show
2. v-if与v-show与v-else使用
语法:
v-show="vue变量"
v-if="vue变量"
原理:- v-show 用的display:none隐藏 (频繁切换使用)
- v-if 直接从DOM树上移除,v-if可以配合v-else使用
<template>
<div>
<h1 v-show="isOk">v-show的盒子</h1>
<h1 v-if="isOk">v-if的盒子</h1>
<div>
<p v-if="age > 18">我成年了</p>
<p v-else>还得多吃饭</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isOk: true,
age: 15
}
}
}
</script>
案例-折叠面板
需求: 点击展开或收起时,把内容区域显示或者隐藏
此案例使用了less语法, 项目中下载模块
yarn add less@3.0.4 less-loader@5.0.0 -D
<template>
<div id="app">
<h3>案例:折叠面板</h3>
<div>
<div class="title">
<h4>芙蓉楼送辛渐</h4>
<span class="btn" @click="isShow = !isShow">
{{ isShow ? '收起' : '展开' }}
</span>
</div>
<div class="container" v-show="isShow">
<p>寒雨连江夜入吴, </p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isShow: false
}
}
}
</script>
3. 循环结构
语法
v-for="(值变量, 索引变量) in 目标结构"
v-for="值变量 in 目标结构"
v-for遍历数组
<li v-for='item in list'>{{item}}</li>
<li v-for='(item,index) in list'>{{item}} + '---' +{{index}}</li>
<template>
<div id="app">
<!-- v-for 把一组数据, 渲染成一组DOM -->
<!-- 口诀: 让谁循环生成, v-for就写谁身上 -->
<p>学生姓名</p>
<ul>
<li v-for="(item, index) in arr" :key="item">
{{ index }} - {{ item }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
arr: ["小明", "小欢欢", "大黄"]
}
}
</script>
v-for遍历对象
<div v-for='(value, key, index) in object'></div>
<template>
<div id="app">
<!-- 省略其他 -->
<p>学生详细信息</p>
<ul>
<li v-for="obj in stuArr" :key="obj.id">
<span>{{ obj.name }}</span>
<span>{{ obj.sex }}</span>
<span>{{ obj.hobby }}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
// ...省略其他
stuArr: [
{
id: 1001,
name: "孙悟空",
sex: "男",
hobby: "吃桃子",
},
{
id: 1002,
name: "猪八戒",
sex: "男",
hobby: "背媳妇",
}
]
}
}
}
</script>
key的作用:帮助Vue区分不同的元素,从而提高性能
<li :key='item.id' v-for='(item,index) in list'>{{item}} + '---' {{index}}</li>
v-if和v-for结合使用
<div v-if='value==12' v-for='(value, key, index) in object'></div>