思路逐渐清晰:VUE全解(上)持续更新中~~~💖!

540 阅读12分钟

我的GitHub主页

前言:学习了Vue全解之后,也陆续做了两个项目,一个是高仿的C-node社区,一个是一个记账的web-app,做完之后,深觉应该回过头来整理Vue的知识,果然,在整理的时候又发现了很多需要注意的点!!温故而知悉!😄😄😄

Vue全解(上)

一、Vue实例

1.1. 创建实例并且访问

访问Vue实例的属性,都是以$开头的,比如 app.$el

访问data中的实例,直接用app.msg

1.2 生命周期钩子

created Vue实例创建完成,还未挂载

mounted 刚刚挂载

beforeDestory 实例销毁之前,用于解绑

1.3 文本插值

{{ xxx }},或者三元运算符,但是不能写表达式if什么的

<span v-text="apple"></span>

二、指令和事件

v-html:解析HTML

<span v-html="banana"></span>  //banana是实例data中的一个对象

//以下是vue实例的内容

let app= new Vue({
    el:'#app',
    data:{
      date:new Date(),
      apple:"苹果",
      banana:'<span style="color: yellow">香蕉</span>',
      className:'transred',
      count:0
    },
    methods:{
      add(){
        this.count+=1
      }
    }
  })

v-bind:绑定活的属性

比如当某个div的class不是写死的时候,而是从data中获取来的,这个时候这个属性就是活的了,可以从其他组件传过来,可简写为 :

<div v-bind:class="className"></div>
<div :class="className"></div>

// Vue实例data中的 className:'transred'

<style>
    .transred{
        background-color: red;
    }
</style>

v-on: 绑定事件监听

当我们点击按钮时,按钮上的数字+1,点一次+一次,可用@代替

<h3>v-on指令:绑定事件监听</h3>
  <button v-on:click="add">{{ count }}</button>
  <button @click="add">{{ count }}</button>

三、计算属性

所有vue实例中的数据,都可以在计算属性中直接使用。 getter 和setter 属性,如果默认啥也不写,就直接接function函数,那么他就是getter属性 如果是调用方法的话,只要页面重新渲染,方法就会执行,不许要渲染就不需要重新执行 计算属性:计算属性变与不变,只取决于依赖的数据变化。 何时使用:使用哪一种取决你你是否需要缓存, 当遍历大数组和做大量计算时,应当使用 计算属性,除非你不希望得到缓存。

四、v-bind以及class与style的绑定

应用场景: DOM 元素经常会动态地绑定一些 class 类名或 style 样式

4.1 了解bind指令

v-bind的复习

  1. 链接的 href 属性和图片的 src 属性都被动态设置了,当数据变化时,就会重新渲染。
  2. 在数据绑定中,最常见的两个需求就是元素的样式名称 class 和内联样式 style 的动态绑定,它们也是 HTML的属性,因此可以使用 v-bind 指令。我们只需要用 v-bind计算出表达式最终的字符串就可以,不过有时候表达式的逻辑较复杂,使用字符串拼接方法较难阅读和维护,所以 Vue.js 增强了对 class 和 style 的绑定。

4.2 绑定 class 的几种方式

4.2.1 对象语法

  • 给 v-bind:class 设置一个对象,可以动态地切换 class,* 值对应true ,false
  • 当 class 的表达式过长或逻辑复杂时,还可以绑定一个计算属性,这是一种很友好和常见的
  • 用法,一般当条件多于两个时, 都可以使用 data 或 computed
<div :class="{ divStyle:isActive}">
//对象的第一个键名代表class名,第二个代表是否显示的布尔值

4.2.2 数组语法

当需要应用多个 class 时, 可以使用数组语法 , 给:class 绑定一个数组,应用一个 class列表:

  1. 数组语法绑定class类
<div :class="['css类名1','css类名2']">数组语法</div>
  1. 数组中嵌套对象
<div :class="['css类名1', 'css类名2', {css类名3: true|false}]"> 数组中嵌套对象</div>

注意对象里面的css类名不用加单引号,和上一节用法是一致的

  1. 我们利用数组语法,实现需求:为文字增加颜色,并点击按钮实现颜色的切换。

4.3 绑定内联样式

使用 v­bind:style (即:style ) 可以给元素绑定内联样式,方法与 :class 类似,也有对象语法和数组语法,看起来很像直接在元素上写 CSS:

演示

绑定style,实现点击按钮,字号变大

效果展示

注意 : css 属性名称使用驼峰命名( came!Case )或短横分隔命名( kebab-case)

五、Vue中的内置指令

5.1基本指令

5.1.1 v-cloak 的用法

一般与display:none进行结合使用作用:解决初始化慢导致页面闪动的最佳实践

5.1.2 v-once 的用法

定义它的元素和组件只渲染一次

<span v-onve>{{oncedata}}</span>

5.1.3 v-if、v-show的用法

实现一个简单的需求:当分数大于90为优秀,大于80小于90为良好,以此类推。最后条件不包含的情况(else)为不及格。

<div id="app">
    语文分数 
  <label>
    <input type="text" v-model.number="gride" placeholder="请输入成绩进行判断">
  </label>
  <p v-if="gride>=90">优秀</p>
  <p v-else-if="(gride>=60)&&(gride<90)">良好</p>
  <p v-else-if="gride>=0">未及格</p>
  <p v-else>未输入</p>
  {{gride}}
</div>

不像if-elseif-else条件判断可以做多组条件判断,v-show只能做互斥条件判断(像是硬币正反面,要么是正面,要么是反面)。通常用于切换页面内容的显示。

v-if 和 v-show 的区别?

v-show指令能实现的效果,v-if系列指令都能实现。二者在实现原理上区别呢?

  • v-if系列指令,每次执行都会重新创建DOM节点,重新渲染节点元素。注意下面动态图中,左侧每次输入分数变化时,右侧的div节点都重新创建。
  • v-show指令不影响DOM节点的创建(Dom节点一定会被创建),只是通过css样式“display:none”控制该dom节点是否显示出来。注意下面动态图中,不会去重新创建h1节点,只是改变样式。

所以对于需要频换切换的页面元素v-show的性能会更好一些。

5.4 v-for 遍历数组-对象-数值序列

方应杭曾经说过:我与重复不共戴天!!!

v-for一定是写在要便利的元素上,v-for后接等号

六、Vue中表单的绑定

6.1 v-model

一、本节说明

前面的章节我们学习了v-bind指定,可以通过模型数据去影响视图。我们都知道VUE是支持双向数据绑定的,那么视图是如何影响数据的呢?那就要学到我们这一节的内容v-model。v-model可以将表单输入绑定到对应的模型数据。

二,效果分析

我们通过v-model实现一个简单的需求

  • 通过表单input绑定模型数据message,表单数据变化data.message也发生变化
  • 然后通过Mustache表达式,将变化之后的message数据显示到视图页面上

三、 深入理解

v-model实际上是一个语法糖,也就是简写,他实际上包含了两个操作:

  1. v-bind绑定value属性
  2. v-on监听表单元素的输入事件,并改变数据 所以,下面的两种写法实现的效果是一致的。

6.2 v-model绑定多选框和单选框

在绝大多数的表单操作中,我们不只要收集文本输入的数据,我们还可能用到单选和多选。通常,实现单选和多选有以下的方式:

  • 第一种:input标签type=radio实现单选和type=checkbox实现的多选
  • 第二种:select标签-option标签实现的单选与多选

6.3 v-model绑定select

上一小节我们使用 v-model 指令,绑定input标签type=radio和type=checkbox,分别实现了单选和多选的视图向模型数据的绑定。 这一节我们使用select标签和option标签,结合v-model实现单选和多选的视图向模型数据的绑定。

  • v-model绑定模型数据mvp,实现单选效果
  • v-model绑定模型数据allDefensiveTeam,结合multiple属性实现多选效果
  • 多选选项的模型数据为数组类型
  • 可以为单选及多选设置默认值,即:默认的勾选项

6.4 v-model的修饰符

  • v-model.lazy 修饰符:默认情况下,input输入会实时影响v-model绑定的数据。加上lazy修饰符,只有当输入框失去焦点会输入回车的时候,才会去改变v-model绑定的数据。
  • v-model.number 修饰符:默认情况下,输入框中输入的无论是数字还是字母,都会被当做字符串处理。加上number修饰符,输入内容会被当做数值类型处理。
  • v-model.trim修饰符:可以自动去掉输入内容左右两边的空格
  <label>
    <input   type="text" v-model.lazy="name">
  </label>
  <h3>球星的名字是: {{name}},typeof识别的类型为: {{typeof name}}</h3>

7.组件化开发

7.1 组件的使用方法

  1. 注册组件
  2. 全局组件,权限太大,容错降低
Vue.component('my-component',{
  template:`<div>我是全局组件的内容</div>`
})
  1. 局部注册
const bpp= new Vue({
  el:'#bpp',
  components:{
    'son-component':{
      template: `<div>我是子组件bpp的局部组件</div>`

}
  }
})

4.html受限 <table>里面的标签只能有<tr> <td> <tbody>,如果我们在里面加上我们的子组件,会发现,这个组件没在<table>里面,反而跳到了他的前面 5.当遇到table标签的时候,使用is组件突破限制

7.2 使用组件的奇技淫巧

  1. 推荐使用小写字母加 - 进行命名(必须) child, my-componnet命名组件
  2. template中的内容必须被一个DOM元素包括 ,也可以嵌套
  3. 在组件的定义中,除了template之外的其他选项—data,computed,methods
  4. data必须是一个方法

7.3 父组件给子组件传递消息

  1. 在组件中使用props来从父亲组件接收参数,注意,在props中定义的属性,都可以在组件中直接使用
  2. props来自父级,而组件中data return的数据就是组件自己的数据,两种情况作用域就是组件本身,可以在templatecomputedmethods中直接使用
  3. props的值有两种,一种是字符串数组,一种是对象,本节先只讲数组
  4. 可以使用v-bind动态绑定父组件来的内容
<body>
<div id="app">
  <child-component :msg1="message"></child-component>
  <child-component msg2="小可爱是谁呀"></child-component>
</div>

<script>
  const app = new Vue({
    el:"#app",
    data:{
      message:'我是来自父组件的数据'
    },
    components:{
      'child-component':{
        props:['msg1','msg2'],
        template:`
        <h3>{{msg1}}</h3>
        <h3>{{msg2}}</h3>
        `
      }
    }
  })
</script>
</body>

7.4关于props的单项数据流

解释 : 通过 props 传递数据 是单向的了, 也就是父组件数据变化时会传递给子组 件,但是反过来不行。

一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改。这种情况可以在组件 data 内再声明一个数据,引用父组件的 prop

  • 步骤一:注册组件
  • 步骤二:将父组件的数据传递进来,并在子组件中用props接收
  • 步骤三:将传递进来的数据通过初始值保存起来,再去使用。

另一种情况就是 prop 作为需要被转变的原始值传入。这种情况用计算属性就可以了

  • 步骤一:注册组件
  • 步骤二:将父组件的数据传递进来,并在子组件中用props接收
  • 步骤三:将传递进来的数据通过计算属性进行重新计算

7.5 传递数据的数据验证

验证的 type 类型可以是:

String Number Boolean Object Array Function

7.7 组件通信

7.7.1子组件给父组件传

经典案例:父组件的余额,子组件里面的按钮可以修改余额

案例解析:

当子组件中的按钮被点击的时候,得使用%emit 触发 change事件,并把需要传递的数据跟上

直接甩代码(重点的步骤我都画了线)

  1. 第一步:自定义事件(直接在父组件里面,change事件就是我自定义的事件)
  2. 第二步:在子组件中用$emit触发事件,第一个参数是事件名,后边的参数是要传递的数据
  3. 第三步:在自定义事件中用一个参数来接受,如上图接收的数据value就是子组件传递过来的count

7.7.2子组件之间的传递

要从组件A传数据给B组件

  1. 第一步:在根组件的data中定义一个bus中介

  2. 第二步:当我们点击A组件中的按钮时,A组件执行一个方法,这个方法里面就包含着:

    首先this.$root会拿到这个bus中介,然后bus中介就去提交这个lalala事件,并且触发这个事件,lalala被触发之后就会把this.xxx这个数据给传递过去,传到哪呢,先传到根组件中!!

handle(){
      this.$root.bus.$emit('lalala',this.aaa)
        }
  1. 第三步:然后在B组件中,Vue实例创建的时候,就要去监听这个lalala事件,然后在这个事件中接收一个参数,这个参数就是传过来的数据
created(){
          this.$root.bus.$on('lalala',function (value){
            return( alert(value))
          })
          }

7.7.3父链$parent

Vue.component('child-component',{
    template:'<button @click="setFatherData">通过点击我修改父亲的数
    据</button>',
    methods:{
      setFatherData:function () {
      this.$parent.msg = '数据已经修改了'
      }
    }
})

7.7.4子链$refs

提供了为子组件提供索引的方法,用特殊的属性ref为其增加一个索引,就像这样

const app = new Vue({
    el:'#app',
    data:{
      msg:'数据还未修改',
      formchild:'还未拿到'
    },
    methods:{
      getChildData:function () {
      //用来拿子组件中的内容 ---- $refs
      this.formchild = this.$refs.a.msg;
      }
    }
})

7.7.5插槽的简单简绍和作用域

抽取共性,保留不同。将共性定义在组件里面,将差异暴露为插槽。这句话我们下文来重点理解。

1.单个插槽

直接演示

<body>
<div id="app">
 <my-children> 我是父组件插入进来的内容!</my-children>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.5.16/vue.js"></script>
<script>
  let app = new Vue({
    el:"#app",
    components:{
      'my-children':{
        template:`
          <div style="border: 2px solid red;">\
             <slot>\
             如果父组件没有插入内容,就显示我
             </slot>\
          </div>`
      }
    }
  })
</script>
</body>

效果就是:子组件的模板中标签包裹的内容,被替换为父组件使用子组件标签中间的内容————我是父组件插入进来的内容

2.具名插槽

具名插槽:顾名思义,就是有名字的插槽,有了名字之后,子组件就可以用多个不同名字的插槽,那父组件传内容的时候,就有了一一对应的关系!岂不美哉!!!

直接演示!

3.作用域插槽

  1. 第一步现在子组件中定一个slot,这个slot里面写上需要传递的数据,

  1. 然后再父组件的模板中,定义一个 slot-scop, 然后用我们后面的变量名.xxx 获取数据 只能拿到除了name 之外的 其他属性

4.组件的高级用法--动态组件

VUE给我们提供 了一个元素叫component

  • 作用是: 用来动态的挂载不同的组件
  • 实现:使用is特性来进行实现的

5. .sync

如果你想给一个初始的值,然后呢,你还想在它更新的时候。拿到最新的值,那一般就用 .sync

<template>
  <div>
  	<Type :value="a" @update.value="a变化函数" />
  </div>
</template>

可以直接写为

<Type :value.sync="a"/>

由于本人水平有限,如有描述不准确的地方请给我留言,欢迎交流~