Vue基础(一)

初识Vue

特点

  • 遵循 MVVM 模式
  • 编码简洁,体积小,运行效率高,适合 移动/PC 端开发
  • 它本身只关注 UI,可以轻松引入 vue 插件或其它第三方库开发项目
  • 采用组件化模式,提高代码复用率、且让代码更好维护
  • 声明式编码,让编码人员无需直接操作DOM,提高开发效率
  • 使用虚拟DOMDiff算法,尽量复用DOM节点

与其他前端 JS 框架的关联

  • 借鉴 angular 的 模板 和 数据绑定 技术
  • 借鉴 react 的 组件化 和 虚拟DOM 技术

Vue 扩展插件

  • vue-cli:vue 脚手架
  • vue-resource(axios):ajax 请求
  • vue-router:路由
  • vuex:状态管理(它是 vue 的插件但是没有用 vue-xxx 的命名规则)
  • vue-lazyload:图片懒加载
  • vue-scroller:页面滑动相关
  • mint-ui:基于 vue 的 UI 组件库(移动端)
  • element-ui:基于 vue 的 UI 组件库(PC 端

引入Vue.js

本地引入
 
CDN引入
<!-- 1. 引用 Vue -->
<!-- Vue CDN - 提供 Vue 服务 -->
<script src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>

创建Vue对象

  1. 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
  2. root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;
  3. root容器里的代码被称为【Vue模板】;
  4. Vue实例和容器是一一对应的;
  5. 真实开发中只有一个Vue实例,并且会配合着组件一起使用;
  6. {{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
  7. 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新

//创建Vue实例
new Vue({
el:'#root', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name:'张三',
address:'合肥'
}
})

el和data的两种写法

  1. el有2种写法

(1) new Vue时候配置el属性。

(2) 先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。

const v = new Vue({
data:{
name:'张三'
}
})
v.$mount('#root') //第二种写法 */
  1. data有2种写法
  • 对象式

data:{ name:'张三' }

  • 函数式
data(){
console.log('@@@',this) //此处的this是Vue实例对象
return{
name:'张三'
}
}

如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。

  1. 一个重要的原则

由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例

理解Vue的MVVM实现

MVVM 的核心是 ViewModel 层,它就像是一个中转站(value converter),负责转换 Model 中的数据对象来让数据变得更容易管理和使用,该层向上与视图层进行双向数据绑定,向下与 Model 层通过接口请求进行数据交互,起呈上启下作用。

View 层

View 是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建,模板代码(不是静态页面) (两个语法:指令,大括号表达式)。

Model 层

Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,主要围绕数据库系统展开。

ViewModel 层

viewModel: 视图模型(Vue的实例)

  • Dom Listeners (Dom 监听)
  • Data Bindings (数据绑定)

MVVM

模型model指的是后端传递的数据,视图view指的是所看到的页面。

视图模型viewModel是 mvvm 模式的核心,它是连接 view 和 model 的桥梁。它有两个方向:

模型转化成视图,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定视图转化成模型,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听

这两个方向都实现的,我们称之为数据的双向绑定

Vue模板语法

Vue的模板语法分为两种,分别是:

  • 【插值语法】{{ }}双大括号表达式 (“Mustache”语法)【一个】
    • 对象:{{ {name: 'jack'} }} //{name: 'jack'}
    • 字符串 {{ 'Hello World!' }} //Hello World!
    • 布尔值: {{ isTrue == -1 }} //true
    • 三元表达式: {{ isTrue ? '正确' : '错误' }}//正确
  • 【指令语法】指令(以v-开头的自定义标签属性)【很多】

文本v-text与v-html

v-text

  1. 作用:向其所在的节点中渲染文本内容。
  2. 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。

v-html

  1. 作用:向指定节点中渲染包含html结构的内容。
  2. 与插值语法的区别:
  • (1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
  • (2).v-html可以识别html结构。v-html有安全性问题,容易遭受XSS攻击

属性单向数据绑定v-bind

  • 语法:v-bind:href ="xxx" 或简写为 :href ="xxx"
  • 特点:数据只能从 data 流向页面

属性双向数据绑定v-model

  • 语法:v-mode:value="xxx" 或简写为 v-model="xxx"
  • 特点:数据不仅能从 data 流向页面,还能从页面流向 data

指令语法:绑定事件监听v-on:

  • v-on:click='xxx' v-on:keyup='xxx(参数)'

条件渲染指令

  • v-if="表达式"
  • v-else-if="表达式"
  • v-else="表达式"

适用于:切换频率较低的场景。 特点:不展示的DOM元素直接被移除。 注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。

  • v-show

v-show="表达式" 适用于:切换频率较高的场景。 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

v-if是控制元素是否加载到页面上(有性能开销) v-show是控制元素的显示与隐藏 (初始创建时加载一次)

computed 计算属性与watch监听属性

计算属性 computed

computed属性对象中定义计算属性的方法,在页面中使用{{方法名}}来显示计算的结果

  1. 定义:要用的属性不存在,要通过已有属性计算得来。
  2. 原理:底层借助了Objcet.defineproperty方法提供的gettersetter
  3. get函数什么时候执行?
    1. 初次读取时会执行一次。
    2. 当依赖的数据发生改变时会被再次调用

<input v-model="full" ><br>
<input v-model="first" > <br>
<input v-model="second" >
data(){
return{
first:'美女',
second:'姐姐'
}
},
computed:{
full:{
get(){ //回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值
return this.first + ' ' + this.second
},
set(val){ //监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据
let names = val.split(' ')
this.first = names[0]
this.second = names[1]
}
}
}

computed 计算属性值是函数时,默认使用get方法。如果属性值是属性值时,属性有一个get和set方法,当数据发生变化时会调用set方法。

  • get 方法:first 和 second 改变时,会调用 get 方法,更新 full 的值。
  • set 方法:修改 full 的值时,会调用 set 方法,val 是 full 的最新值。

计算属性缓存

我们通过方法,拼接数据,也可以实现该效果,一个页面内,数据有可能多次使用,我们把 computed 和 method 两个方法放一起实现,并把这个数据在页面内多次引用,试看以下效果。

data(){
return{
first:'美女',
second:'姐姐'
}
},
computed:{
full:function(){
console.log('computed')
return this.first + ' ' + this.second
}
},
methods:{
fullt(){
console.log('方法')
return this.first + ' ' + this.second
}
}
运行结果为:
computed
方法
方法
方法
方法
方法

优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。

监视属性 watch

通过vm对象的$watch()watch配置来监视指定的属性,当属性变化时, 回调函数自动调用, 通俗地讲,就是检测 data 内声明的数据。不仅可以监测简单数据,还可以监测对象或对象属性。

通过vm.$watch监视

vm.$watch('isHot',{
immediate:true, //初始化时让handler调用一下
//handler什么时候调用?当isHot发生改变时。
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
})
  • immediate:true, //初始化时让handler调用一下
  • deep:true//监测对象内部值改变(多层)
  • handler(oldVal,newVal)//handler什么时候调用?当isHot发生改变时

深度监视:

Vue中的watch默认不监测对象内部值的改变(一层)。

深度监听虽然可以监听到对象的变化,但是无法监听到具体的是哪个属性发生变化了。

//正常写法
isHot:{
// immediate:true, //初始化时让handler调用一下
// deep:true,//深度监视
handler(newValue,oldValue){
console.log('isHot被修改了',newValue,oldValue)
}
}

计算属性与监视属性的区别

  • computed 监控的数据在 data 中没有声明,watch数据必须在 data 中声明或 props 中数据
  • computed 不支持异步,当 computed 中有异步操作时,无法监听数据的变化
  • computed 具有缓存,页面重新渲染,值不变时,会直接返回之前的计算结果,不会重新计算,watch没有缓存,页面重新渲染时,值不改变时也会执行

应用场景

  • 当需要进行数值计算,并且依赖于其它数据时,应该使用 computed ,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。
  • 当需要在数据变化时执行异步操作或开销较大的操作时,应该使用 watch

【补充】两个重要的小原则:

  1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
  2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

阅读剩余
THE END