一、vue是什么
Vue ,是目前前端主流框架之一,单页面开发,是尤雨溪于2014年发布的一个前端框架,是一套用于构建用户界面的渐进式 javascript 框架,是国内比较流行的前端框架之一,占的市场份额最大,容易入门,可以和第三方库或者已有的项目进行整合,可以做复杂的单页应用。它与React,Angular 齐成前端的三大框架。具体详细请参考官网:https://cn.vuejs.org/
1.1前端三要素构成
HTML(解构):超文本标记语言(Hyper Text Markup Language),决定网页的解构与内容
CSS(表现层):层叠样式表(Cascading Style Sheets),设定网页样式
JavaScript(行为层):是一种弱类型脚本语言,其源码不需经过编译,ESCMAScript核心语言基础DOM(文档对象模型)规定访问HTML和xml的接口,BOM(浏览器对象模型)提供了浏览器窗口之间进行交互的对象和方法
vue常用的css预处理器有哪些
- SASS:基于Ruby ,通过服务端处理,功能强大。解析效率高。需要学习Ruby语言,上手难度高于LESS。
- LESS:基于NodeJS,通过客户端处理,使用简单。功能比SASS简单,解析效率也低于SASS,但在实际开发中足够了,所以如果我们后台人员如果需要的话,建议使用LESS
TypeScript 微软的标准
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集, 而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。由安德斯·海尔斯伯格(C#、Delphi、TypeScript之父; .NET创立者) 主导。
该语言的特点就是除了具备ES的特性之外还纳入了许多不在标准范围内的新特性,所以会导致很多浏览器不能直接支持TypeScript语法, 需要编译后(编译成JS) 才能被浏览器正确执行。
二、vue全家桶是那些
vue全家桶包含cli脚手架、脚手架vue-cli、路由vue-router、状态管理模式vuex、axios、element ui组件 。
为什么要使用Vue.js
轻量级, 体积小是一个重要指标。Vue.js压缩后有只有20多kb(Angular压缩后56kb+,React压缩后44kb+)
移动优先。更适合移动端, 比如移动端的Touch事件
易上手,学习曲线平稳,文档齐全
吸取了Angular(模块化) 和React(虚拟DOM) 的长处, 并拥有自己独特的功能,如:计算属性
开源,社区活跃度高,
独立开发,前后端分离
vue下载
直接下载并用 <script>
标签引入,Vue
会被注册为一个全局变量。
命令行安装
npm install vue
每个 Vue 应用都是通过用 Vue
函数创建一个新的 Vue 实例开始的:
var vm = new Vue({
// 选项
})
虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用 vm
(ViewModel 的缩写) 这个变量名表示 Vue 实例。
当创建一个 Vue 实例时,你可以传入一个选项对象。这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。作为参考,你也可以在 API 文档中浏览完整的选项列表。
一个 Vue 应用由一个通过 new Vue
创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。举个例子,一个 todo 应用的组件树可以是这样的:
根实例
└─ TodoList
├─ TodoItem
│ ├─ TodoButtonDelete
│ └─ TodoButtonEdit
└─ TodoListFooter
├─ TodosButtonClear
└─ TodoListStatistics
2.1生命周期钩子函数
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
三、vue的模板语法
3.1文本
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
<span>Message: {{ msg }}</span>
Mustache 标签将会被替代为对应数据对象上 msg
property 的值。无论何时,绑定的数据对象上 msg
property 发生了改变,插值处的内容都会更新。
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
<span v-once>这个将不会改变: {{ msg }}</span>
3.2v-if与v-show指令显示与隐藏
<p v-if="seen">现在你看到我了</p>
<p v-show="seen">现在你看到我了</p>
这里,v-if
指令将根据表达式 seen
的值的真假来插入/移除 <p>
元素。
v-show通过cssd的display:none隐藏
v-bind
指令可以用于响应式地更新 HTML attribute:
<a v-bind:href="url">...</a>
v-on
指令,它用于监听 DOM 事件:
<a v-on:click="doSomething">...</a>
v-model双向绑定用来坐表单处理
v-model
在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
计算属性和侦听器
computed是从现有的数据中计算出新的数据并且有缓存,watch是监听数据变化执行handler回调函数没有缓存
html:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
js:
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。细想一下这个例子:
html:
<div id="demo">{{ fullName }}</div>
js:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
v-for列表渲染
我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<ul id="example-1">
<li v-for="item in items" :key="item.message">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
v-if与v-for不能同时使用
v-for和v-if不要在同一标签中使用,容易造成性能浪费,因为解析时先解析v-for再解析v-if。如果遇到需要同时使用时可以考虑写成计算属性的方式
事件修饰符
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>
vue的组件注册
Vue.component('my-component-name', { /* ... */ })
全局注册
Vue.component('my-component-name', {
// ... 选项 ...
})
局部注册
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
自定义指令
指令本质上是装饰器,是 vue 对 HTML 元素的扩展,给 HTML 元素添加自定义功能。vue 编译 DOM 时,会找到指令对象,执行指令的相关方法。
自定义指令有五个生命周期(也叫钩子函数),分别是 bind、inserted、update、componentUpdated、unbind
· 1、bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
· 2、inserted:被绑定元素插入父节点时调用。
· 3、update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较前后的绑定值。
· 4、componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
· 5、unbind:只调用一次,指令与元素解绑时调用。
组件传参方式有哪些
父传子 在父组件中通过属性的方式向子组件传参 子组件中通过props接收参数
子传父 在子组件中通过$emit调用父组件的自定义事件 在父组件的自定义事件中通过$event接收参数
非父子关系:
ref获取引用
依赖注入:provide inject
vuex
vue2(选项options) envetBus传参”;$parent父对象,$chilren子对象 $root根节点
vue插槽
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 <slot>
元素作为承载分发内容的出口。
它允许你像这样合成组件:
<navigation-link url="/profile">
Your Profile
</navigation-link>
然后你在 <navigation-link>
的模板中可能会写为:
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
当组件渲染的时候,<slot></slot>
将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML:
<navigation-link url="/profile">
<!-- 添加一个 Font Awesome 图标 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
四、路由路由模式有哪些
- hash路由
- 历史记录路由
mode:"hash"|"history"
哈希路由不依赖后端,刷新并没有问题
历史记录没有后端配置刷新会404
4.1路由原理
地址栏更新页面不刷新,监听变化切换div模拟页面的切换
哈希路由:监听onhashchange事件
历史路由:监听onpopstate
4.2路由的配置
基本配置
{path:"路径",name:"名称",component:组件}
4.2.1路由懒加载(vite打包需要二次处理
{path:"路径",name:"名称",component:()=>import(组件的地址)}
4.2.2子路由
{path:"路径",name:"名称",component:组件,children:[
{path:路径,component:组件},
4.3路由传参
4.3.1路径传参
{path:"/produce/:id",name:"名称",component:组件}
<router-link to="/produce/abc"></router-link>
$route.params.id
4.3.2.query查询传参
<route-link to="/user?name=mumu">
$route.query获取
4.3.3meta元数据传参
{path:"/user",component:xxx,meta:{hasTabs:true}}
<router-view/>
<tabs v-if="$route.meta.hasTabs"></tabs>