Vue.js的学习

基础入门

初识Vue

前端技术的发展

前端技术的发展: 前端技术发展及现状

什么是Vue

Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。

Vue的优势

1 轻量级
2 数据绑定
3 指令
4 插件

开发环境

1 Visual Studion Code编译器
优点:

  • 轻巧极速,占用系统资源较少
  • 具备语法高亮显示,智能代码补全,自定义快捷键和代码匹配等功能
  • 跨平台
  • 主题界面的设计比较人性化
  • 提供了丰富的插件

2 Vue的下载与引用
Vue核心文件有2个版本,分别是开发版本和生产版本
生产版本是压缩后的文件,平常引用的是开发版本
在代码开头的注释中查看版本号:
在这里插入图片描述
在上述代码中,2.7.14就是Vue核心文件的版本号
当在HTML网页中使用Vue时,使用script标签引入Vue.js即可
在这里插入图片描述
3 git-bash命令行工具
git-bash是git中提供的一个命令行工具,类似于Windows系统内置的cmd命令行工具。
4 Node.js环境
Node.js是一个基于Chrome V8引擎的JavaScript运行环境,它可以让JavaScript运行在服务器端。
5 npm包管理工具
npm(Node.js Package Manager)是一个Node.js的包管理工具,用来解决Node.js代码部署问题。在安装Node.js时会自动安装相应的npm版本,不需要单独安装。
6 Chrome浏览器和vue-devtools拓展
Chrome浏览器是开发和调试Web项目的工具
vue-devtools是一块基于Chrome浏览器的拓展,用于调试Vue应用,只需下载官方压缩包,配置Chrome浏览器的拓展应用程序即可。
7 Hello World案例
在这里插入图片描述

打包工具

1 安装webpack
2 webpack简单使用
3 构建Vue项目
项目目录结构:

目录结构说明
build项目构建(webpack)相关代码
config配置文件目录
node_modules依赖模块
src源码目录
static静态资源目录
test初始测试目录
index.html首页入口文件
package.json项目配置文件
README.md项目说明文档

开发基础

Vue实例

创建Vue实例

在这里插入图片描述
对Vue实例进行配置,常用的选项有:

选项说明
dataVue实例数据对象
methods定义Vue实例中的方法
components定义子组件
computed计算属性
filters过滤器
el唯一根标签
watch监听数据变化
el唯一根标签

在创建Vue实例时,el为唯一根标签,class或id选择器可用来将页面结构与Vue实例对象vm中的el绑定。

data初始数据

Vue实例的数据对象为data,Vue会将data属性转化为getter,setter,从而让data的属性能够响应数据变化。
Vue实例创建之后,可以通过vm.$data访问原始数据对象。Vue实例也代理了data对象上的所有属性,因此访问vm.name就相当于访问vm.data.name。

methods定义方法

methods属性用来定义方法,通过Vue实例可以直接访问这些方法。在定义的方法中,this指向Vue实例本身。定义在methods属性中的方法可以作为页面中的事件处理方法使用,当事件执行后,执行相应的事件处理方法。
在这里插入图片描述

computed计算属性

Vue提供了一种更通用的方式来观察和响应Vue实例上的数据变动,当有一些数据需要随着其他数变动而变动时,就需要使用computered计算属性。在事件处理方法中,this指向的Vue实例的计算属性结果会被缓存起来,只有依赖的响应式属性变化时,才会重新计算,返回最终结果。
在这里插入图片描述
上面案例中,默认商品数量是0件,总价格是0元。单击增加数量按钮时,商品数量加1,总价格会在当前的价格基础上增加20;单击减少数量按钮时,商品数量减1,总价格会在当前价格的基础上减少20。

watch状态监听

Vue中的事件处理方法是根据当前用户所需自行定义的,它可以通过单击事件,键盘事件等触发条件来触发,但不能自动监听当前Vue实例的状态变化。为了解决上述问题,Vue提供了watch状态监听功能,只需监听当前Vue实例中的数据变化,就会调用当前数据所绑定的事件处理方法。
在这里插入图片描述
watch成功监听了表单元素中的内容变化

filters过滤器

在前端网页开发中,通过数据绑定可以将data数据绑定到页面中,页面中的数据经过逻辑层处理后展示最终的结果。数据的变化除了在Vue逻辑层进行操作外,还可以通过过滤器来实现。过滤器用于对数据进行格式化,如字符串首字母改大写,日期格式化等。

  • 在插值表达式中使用过滤器
    通过“{data}”语法,可以将data中的数据插入到页面中,该语法就是插值表达式。在插值表达式中还可以使用过滤器来对数据进行处理,语法为"{{ data | filter }}"
    在这里插入图片描述

  • 在v-bind属性绑定中使用过滤器

Vue数据绑定

Vue中数据绑定功能极大地提高了开发效率

绑定样式
  • 绑定内联样式
    在Vue实例中定义的初始数据data,可以通过v-bind将样式数据绑定到DOM元素
    在这里插入图片描述
    使用v-bind绑定样式时,Vue做了专门的增强,表达式结果的类型除了字符串之外,还可以是对象或数组
  • 绑定样式类
    样式类是以类名定义元素的样式
    在这里插入图片描述
内置指令

Vue为开发者提供了内置指令,通过内置指令就可以用简洁的代码实现复杂的功能。

指令说明
v-model双向数据绑定
v-on监听事件
v-bind单向数据绑定
v-text插入文本内容
v-html插入内容包含HTML的内容
v-for列表渲染
v-if条件渲染
v-show显示隐藏
  • v-model
    主要实现数据双向绑定,通常用在表单元素上,例如input,textarea,select等。
    在这里插入图片描述
    浏览器显示在这里插入图片描述
    更改浏览器中的数据,浏览器底部中的Vue显示变化;类比:更改浏览器底部的数据,文本框中的数据也会发生相对应的变化。在这里插入图片描述

  • v-text
    是在DOM元素内部插入文本内容
    在这里插入图片描述

  • v-html
    v-html是在DOM元素内部插入HTML标签内容
    在这里插入图片描述
    v-html与v-text不同的是,v-html的内容是HTML结构

  • v-bind
    可以实现属性单向数据绑定

单向绑定
把Model绑定到View,当更新Model时View就会自动更新。因此,我们不需要再通过生命JJavaScript代码进行额外的DOM操作。
双向绑定
把Model绑定到View的同时,也将View绑定到Model上。这样,View就会自动更新;反之,如果用户更新了View,Model的数据也自动被更新了。

  • v-on
    是事件监听,直接与事件类型配合使用。
    在这里插入图片描述

  • v-for
    可以实现页面列表渲染,常用来循环数组
    在这里插入图片描述

  • v-if和v-show

v-if用来控制元素显示或隐藏,属性为布尔值。
v-show可以实现与v-if同样的效果,但是v-show是操作元素的display属性,而v-if会对元素进行删除和重新创建,所以v-if在性能上不如v-show。

在这里插入图片描述

Vue事件

Vue事件监听
  1. 在触发事件时执行JavaScript代码
    在这里插入图片描述

  2. 使用按键修饰符监听按键
    在监听键盘事件时,经常需要检查常见的键盘。为了方便开发,Vue允许为v-on添加按钮修饰符来监听按钮,如Enter,空格,Shift和PageDown等。
    以Enter键为例:
    在这里插入图片描述
    单击input输入框使其获得焦点,然后按Enter键,可以在控制台看到"表单提交"结果,说明键盘事件绑定成功并且执行。

事件修饰符

事件修饰符是自定义事件行为,配合v-on指令来使用,写在事件之后,用”.“符号连接,如”v-on:click.stop“表示阻止事件冒泡。常见的事件修饰符有:

修饰符说明
.stop阻止事件冒泡
.prevent阻止默认事件行为
.capture事件捕获
.self将事件绑定到自身,只有自身才能触发
.once事件指触发一次
  1. .stop阻止事件冒泡
    默认事件的传递方式是冒泡,所以同一事件类型会在元素内部和外部触发,有时会造成事件的错误触发,所以需要使用.stop修饰符阻止事件冒泡
    在这里插入图片描述
    单击”冒泡事件“,控制台会同时出现显示"我是被单击元素事件"和”我是父元素单击事件“,说明子元素和父元素绑定的事件处理方法同时触发
    刷新后,单击”阻止事件冒泡“按钮,会出现"我是被单击元素事件",说明冒泡行为已成功被阻止

  2. .prevent阻止事件默认行为
    HTML标签具有自身特性,例如,a标签被单击时会自动跳转。在实际开发中,如果a标签的默认行为与事件发生冲突,此时可以使用.prevent修饰符来阻止a标签的默认行为。
    在这里插入图片描述
    单击"阻止默认行为"链接,页面不会发生跳转
    单击”不阻止默认行为”,页面会进行相对应的跳转

  3. .capture事件捕获
    事件捕获的执行顺序是由外部结构向内部结构执行,与事件冒泡的顺序相反。
    在这里插入图片描述

  4. .self 自身触发
    事件修饰符.self用来实现DOM元素本身触发事件
    在这里插入图片描述
    单击b区域时,只有doThis()方法被执行
    单击d区域时,doThis()方法和doParent()方法会一次执行

  5. .once 只触发一次
    事件修饰符.once用于阻止事件多次触发,只触发一次

在这里插入图片描述
单击"只执行一次"按钮,控制台中输出"我是当前元素单击事件且执行一次";当多次单击"只执行一次"按钮时,控制台的输出结果没有任何变化。

注意;时间修饰符可以控制事件按照一定规则触发,在使用修饰符时,书写的顺序很重要。例如:v-on:click.prevent.self会阻止所有的单击,而v-on:click.self.prevent只会阻止对元素本身的单击。

Vue组件

Vue可以进行组件化开发,组件是Vue的基本结构单元,开发过程中使用起来非常方便灵活,只需按照Vue规范定义组件,将组件渲染到页面即可。组件能实现复杂的页面结构,提高代码的可复用性。

什么是组件

组件是构成页面中独立结构单元,能够减少重复代码的编写,提高开发效率,减低代码之间的耦合程度,使项目更易维护和管理。组件主要以页面结构的形式存在,不同的组件也具有基本的交互功能,根据业务逻辑实现复杂的项目功能。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>什么是组件</title>
    <script src="../../vue.js"></script>
</head>
<body>
    <div id="app">
       <my-component></my-component>
       <my-component></my-component>
       <my-component></my-component>
    </div>
</body>

<script>
    <!--vue.component表示注册组件的API,my-component组件名称-->
    Vue.component('my-component',{
        data(){
            return{
                count: 0
            }
        },
        <!-- template组件模板-->
        template:'<button v-on:click="count++">被单击{{count}}次</button>'
    })
    var vm = new Vue({el:'#app'});
</script>
</html>

利用Vue组件功能可以非常方便地服用页面代码,实现一次定义,多次使用的效果。

局部注册组件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>局部注册事件</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
    <my-component></my-component>
</div>

</body>

<script>
    var com1 = {
        template: '<p>我是vm实例中的局部组件</p>'
    }
    var vm = new Vue({
        el:'#app',
        <!--注册局部注册事件-->
        components:{myComponent:com1}
    })
</script>
</html>

注册组件时,只需将组件在components内部完成定义即可。

template模板

template模板是用字符串保存的,这种方式不仅容易出错,也不适合编写复杂的页面逻辑。实际上,模版滴嘛是可以写在html结构中的,这样有利于在编辑器中显示代码提示和高亮显示,不仅改善了开发体验,也提高了开发效率。
Vue提供了< template >标签来定义结构的模板,可以在标签中书写在HTML代码,然后通过id值绑定到组件内的template属性上。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>template模板</title>
    <script src="../../vue.js"></script>
</head>
<body>
   <div id="app">
       <p>{{title}}</p>
       <my-component></my-component>
   </div>
   <template id="tmp1">
       <p>{{title}}</p>
   </template>
</body>
<script>
    Vue.component('my-component',{
        template:'#tmp1',
        data() {
            return{
                title:'我是组件的title',
            }
        }
    })
    var vm = new Vue({
        el:'#app',
        data: {
            title: '我是vm实例的title'
        }
    })
</script>
</html>

在全局注册组件时,组件接收的配置选项,与创建Vue实例时的配置选项基本相同,都可以使用methods来定义方法。组件内部具有自己的独立作用域,不能直接被外部访问。

组件之间的数据传递

在Vue中,数据传递通过props属性和$emit方式来实现。

  1. prop传值
    props即道具,用来接受父组件中定义的数据,其值为数组,数组中父组件传递的数据信息。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>props传值</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
    <my-parent name="title"></my-parent>
</div>

</body>

<script>
    Vue.component('my-parent',{
        props:['name'],
        template:'<div>我是父组件{{name}}</div>'
    })
    var vm = new Vue({
        el:'#app'
    })
</script>
</html>

props是以从上到下的单项数据流传递,且父组件的props更新会向下流动到子组件中,但是反过来不行。

  1. $emit传值
    $emit能够将子组件中的值传递到父组件中。 $emit可以触发父组件中定义的事件,组件的数据信息通过传递参数的方式来完成。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>$emit传值</title>
    <script src="../../vue.js"></script>
</head>
<body>

<div id="app">
  <parent></parent>
</div>
<template id="child">
    <div>
        <button @click="click">Send</button>
        <input type="text" v-model="message">
    </div>
</template>


</body>
<script>
  Vue.component('parent',{
    template:'<div> <child @childfn="transContent"></child>子组件传来的值:{{message}} </div>',
    data(){
      return{
        message:''
      }
    },
    methods:{
      transContent(payload){
        this.message = payload
      }
    }
  })

  //child组件
  Vue.component('child',{
    template: '#child',
    data() {
      return{
        message:'子组件的消息'
      }
    },
    methods: {
      click(){
        this.$emit('childfn',this.message);
      }
    }
  })
  var vm = new Vue({el:'#app'})
</script>
</html>
组件切换

登录组件和注册组件的切换
组件切换有两种方式:v-if 和组件的is属性来实现,使用is属性匹配组件的名称。
v-if组件实现登录和注册组件切换

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件切换</title>
    <script src="../../vue.js"></script>
</head>
<body>

<div id="app">
    <a href="#" @click.prevent="flag=true">登录</a>
    <a href="#" @click.prevent="flag=false">注册</a>
    <login v-if="flag"></login>
    <register v-else></register>
</div>


</body>
<script>
    Vue.component('login',{
        template:'<div>登录页面</div>'
    })
    Vue.component('register',{
        template:'<div>注册页面</div>'
    })
    var vm = new Vue({
        el:'#app',
        data:{
            flag:true
        }
    })
</script>
</html>

is属性来实现登录和注册组件切换

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用is属性匹配组件</title>
    <script src="../../vue.js"></script>
</head>
<body>

<div id="app">
  <a href="#" @click.prevent="comName='login'">登录</a>
  <a href="#" @click.prevent="comName='register'">注册</a>
  <component v-bind:is="comName"></component>
</div>
</body>


<script>
  Vue.component('register',{
    template:'<div>注册页面</div>'
  })
  Vue.component('login',{
      template:'<div>登录页面</div>'
  })
  var vm = new Vue({
    el:'#app',
    data:{
      comName:''
    }
  })
</script>
</html>

is属性值绑定了data中的comName,< a >标签用来修改comName的值.从而切换对应的组件

Vue的生命周期

Vue实例为生命周期提供了回调函数,用来在特定的情况下触发,贯穿Vue实例化的整个过程,这给用户在不同阶段添加自己的代码提供了机会。每个Vue实例在被创建时都要经过一系列的初始化过程,如初始数据监听,编译模板,将实例挂载到DOM并在数据变化时更新DOM等。

钩子函数

钩子函数用来描述Vue实例从创建到销毁的整个生命周期

钩子说明
beforeCreate创建实例对象之前执行
Created创建实例对象之后执行
beforeMount页面挂载成功之前执行
mounted页面挂载成功之后执行
beforeUpdate组件更新之前执行
updated组件更新之后执行
beforeDestory实例销毁之前执行
destroyed实例销毁之后执行
实例创建
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>实例对象创建</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
  {{msg}}
</div>
</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{
      msg:'张三'
    },
      beforeCreate (){
          console.log('实例创建之前')
          console.log(this.$data.msg)
      },
      created (){
          console.log('实例创建之后')
          console.log(this.$data.msg)
    }
  })
</script>
</html>

在这里插入图片描述

beforeCreate钩子函数输出msg时出错,这是因为此时数据还没有被监听,同时页面没有被挂载对象。而created 钩子函数执行时,数据已经绑定到了对象实例,但是还没有挂载对象。

页面挂载
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>实例对象创建</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
  {{msg}}
</div>
</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{
      msg:'张三'
    },
      beforeCreate (){
          console.log('实例创建之前')
          console.log(this.$data.msg)
      },
      created (){
          console.log('实例创建之后')
          console.log(this.$data.msg)
    }
  })
</script>
</html>

在这里插入图片描述
在挂在之前,数据对并没有被关联到$el对象上,所有页面无法展示页面数据;在挂载之后,就获得了msg数据,并通过插值语法展示到页面中

数据更新
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据更新</title>
    <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
  <div v-if="isShow" ref="div">test</div>
  <button @click="isShow=!isShow">更新</button>
</div>
</body>

<script>
  var vm = new Vue({
    el:'#app',
    data:{
      isShow:false//初始值为false表示元素隐藏
    },
    beforeUpdate(){
      console.log('更新之前')
      console.log(this.$refs.div)
    },
    updated(){
      console.log('更新之后')
      console.log(this.$refs.div)
    }

  })
</script>
</html>

更新之前:
在这里插入图片描述
更新之后:
在这里插入图片描述

数据销毁

生命周期的最后阶段是数据销毁,会执行beforeDestory和destoryed钩子函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>实例销毁</title>
  <script src="../../vue.js"></script>
</head>
<body>
<div id="app">
  <div ref="div">test</div>
</div>

</body>
<script>
  var vm = new Vue({
    el:'#app',
    data:{
      msg:'张三'
    },
    beforeDestroy (){
      console.log('销毁之前')
      console.log(this.$refs.div)
      console.log(this.msg)
      console.log(vm)
    },
    destroyed (){
      console.log('销毁之后')
      console.log(this.$refs.div)
      console.log(this.msg)
      console.log(vm)
    }
  })
</script>
</html>

vm实例在 beforeDestroy和destroyed函数执行时都存在,但是销毁之后获取不到页面中的div元素。所有,实例销毁以后无法操作DOM元素。

全局API

使用Vue.component()方法来注册自定义组件,这个方法其实就是一个全局API。在Vue中还有很多常用的全局API:

Vue.directive
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>directive指令</title>
  <script src="../vue.js"></script>
</head>
<body>
<!--用于页面初始化,控制input文本框是否自动获得焦点-->
<div id="app">
<!--给input标签设置自定义指令v-focus,初始值为true-->
  <input type="text" v-focus="true">
</div>

<script>
    //注册了一个全局自定义指令v-focus
    Vue.directive('focus',{
        //被绑定的元素插入到DOM中,在insert()钩子函数中进行判断
        //该函数有两个参数,第1个参数el表示当前自定义指令的元素,第2个参数binding表示指令的相关信息
    inserted(el,binding){
        //判断binding.value的值,也就是标签中的v-focus的值,如果为true则获得焦点,反之不会获得焦点
      if(binding.value){
        el.focus()
      }
    }
  })

  var vm = new Vue(
      {el: '#app'}
  )
</script>
</body>
</html>
Vue.use

主要用于在Vue中安装插件,通过插件可以为Vue添加全局功能。插件可以是一个函数或对象,如果是对象,必须提供install()方法,用来安装插件;如果是一个函数,则该函数将被当成install()方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>use</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app" v-my-directive></div>
</body>
<script>
    //定义一个MyPlugin(自定义插件)对象
    let MyPlugin={}
    //编写插件对象的install方法,install()方法有两个参数,第1个参数Vue是Vue构造器,第2个参数options是一个可选的配置对象
    MyPlugin.install = function (Vue,options){
        console.log(options)
        //在插件中为Vue添加自定义指令
        Vue.directive('my-directive',{
            bind(e1,binding){
                //为自定义指令v-my-directive绑定的DOM元素设置style样式
                e1.style = 'width:100px;height:100px,background-color:#ccc;'
            }
        })
    }
    //调用Vue.use()方法安装插件,在第1个参数中传入插件对象MyPlugin,第2个参数传入可选配置
    Vue.use(MyPlugin,{
        someOption:true
    })
    var vm = new Vue({
        el:'#app'
    })
</script>
</html>

在这里插入图片描述

Vue.use会自动阻止多次安装同一插件,因此,在同一个插件上多次调用Vue.use时官方实际只会被安装一次。另外,Vue.js官方提供的一些插件在检测到Vue是可访问的全局变量时,会自动调用Vue.use()。

Vue.extend

用于基于Vue构造器创建一个Vue子类,可以对Vue构造器进行拓展。有一个options参数,表示包含组件选项的对象。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>extend</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app1">
    app1:{{title}}
</div>

<div id="app2">
    app2:{{title}}
</div>

</body>

<script>
    //Vue.extends()方法返回的是Vue的子类
    var Vue2 = Vue.extend({
        //为新创建的Vue2实例添加data数据,由于此时Vue2实例还未被创建,所有需要把数据写在函数的返回值中
        data(){
            return {
                title:'hello'
            }
        }
    })
    var vm1 = new Vue({el:'#app1'});
    var vm2 = new Vue2({el:'#app2'});
</script>
</html>

在这里插入图片描述

app1对应Vue的实例vm1,app2对应Vue2实例vm2,从运行结果可以看出,在vm2中添加初始数据hello,vm1不受影响。并且在控制台中会看到title属性未定义的提示。

Vue.set

核心具有一套响应式系统,简单来说就是通过监听数据层的数据变化,当数据改变时,通知视图也自动更新。Vue.set用于向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>set</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <div>{{a}}</div>
    <div>{{obj.b}}</div>
</div>

</body>
<script>
    var vm = new Vue({
        el:'#app',
        //根数据对象,根数据对象可以驱动试图改变
        data :{
            a:'我是根级响应式属性a',
            obj:{}
        }
    })
    //使用Vue构造器提供的set()方法为对象obj添加响应式数据,第1个参数vm.obj表示目标对象,第2个参数b表示属性名,第3个参数是属性值
    Vue.set(vm.obj,'b','我是Vue.set添加的响应式属性obj.b')
</script>
</html>

注意:Vue不允许动态添加根级响应式属性,因此必须在data中预先声明所有根级响应式属性

Vue.mixin

用于全局注册一个混入(Mixin),它将影响之后创建的每一个Vue实例。该接口主要是提供给插件作者使用,在插件中向组件注入自定义的行为。该接口不推荐在应用代码中使用。
使用Vue.mixin为Vue实例注册created()函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mixin</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">

</div>
</body>
<script>
    Vue.mixin({
        created(){
            var myOption = this.$options.myOption;
            if(myOption){
                console.log(myOption.toUpperCase())
            }
        }
    })
    var vm = new Vue({
        myOption:'hello vue!'
    })
</script>
</html>

在这里插入图片描述

实例属性

实例属性是指Vue实例对象的属性
例如:vm.$data就是一个实例属性,用来获取vm实例中的数据对象。

vm.$props

接受传递的数据:接收上级组件向下传递的数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>实例属性$props</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <!--父组件-->
    <my-parent></my-parent>
</div>
<!--父组件模板-->
<template id="parent">
    <div>
        <h3>手机信息搜索</h3>
<!--        父组件input文本框通过v-model指令绑定brand值-->
        手机品牌:<input type="text" v-model="brand">
        <!--子组件-->
        <!--v-bind绑定子组件的brand-->
        <my-child v-bind:name="brand"></my-child>
    </div>
</template>

<!--子组件模板-->
<template id="child">
    <ul>
        <li>手机品牌:{{show.brand}}</li>
        <li>手机型号:{{show.type}}</li>
        <li>市场价格:{{show.price}}</li>
    </ul>
</template>
</body>
<script>
    Vue.component('my-parent',{
        template:'#parent',
        data() {
            return{
                brand:''
            }
        }
    })

    Vue.component('my-child',{
        template:'#child',
        //定义手机信息
        data() {
            return{
                content:[
                    {brand:'华为',type:'Mate20',price: 3699},
                    {brand:'苹果',type:'iPhone7',price: 2949},
                    {brand:'三星',type:'Galaxy S8+',price: 3299},
                    {brand:'vivo',type:'Z5x',price: 1698},
                    {brand:'一加',type:'OnePlus7',price: 2999},
                    {brand:'360',type:'N7 Pro',price: 1099},
                    {brand:'oppo',type:'Reno',price: 2599}
                ],
                show:{
                    brand:'',
                    type:'',
                    price:''
                }
            }
        },
        //接收父组件传入的name属性
        props:['name'],
        watch:{
            name(){
                if(this.name){//this.name相当于this.$props.name
                    var found = false;
                    this.content.forEach((value,index)=>{
                        if(value.brand === this.name){
                            found = value
                        }
                    })
                    this.show = found ? found :{brand:'',type:'',price:''}
                }else{
                    return
                }
            }
        }
    })
    var vm = new Vue({
        el:'#app',
        data:{}
    })
</script>
</html>

在这里插入图片描述

vm.$options

创建自定义选项:自定义属性的值可以是数组,对象,函数,通过vm.$options来获取

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm.$options</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <p>{{base}}</p>
    <p>{{noBase}}</p>

</div>
</body>
<script>
    var vm = new Vue({
        el:'#app',
        //自定义数据,与data不同的是,它不具有响应式特性
        customOption:'我是自定义数据',
        data:{
            base:'我是基础数据'
        },
        //在实例创建完成后开始执行
        created(){
            //通过实例对象$options属性获取到customOption自定义数据,然后赋值给实例对象的noBase响应属性
            this.noBase = this.$options.customOption
        }
    })
</script>
</html>

在这里插入图片描述

vm.$el

用来访问vm实例使用的根DOM元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm.$el</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <p>我是根标签结构</p>
</div>

</body>
<script>
    var vm = new Vue({
        el:'#app',
    })
    //通过vm.$el获取到DOM对象后,将innerHTML属性修改为新的内容"我是替换后的div标签"
    vm.$el.innerHTML = '<div>我是替换后的div标签</div>'
</script>
</html>

在这里插入图片描述

vm.$children

用来获取当前实例的直接子组件

注意:$children并不保证顺序,也不是响应式的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm.$children</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <!--button按钮绑定了单击事件-->
    <button @click="child">查看子组件</button>
    <my-component></my-component>
</div>

</body>
<script>
    //注册my-component自定义组件
    Vue.component('my-component',{
        template: '<div>myComponent</div>'
    })
    var vm = new Vue({
        el:'#app',
        methods:{
            child(){
                //将this.$children输出到控制台中
                console.log(this.$children)
            }
        }
    })
</script>
</html>

在这里插入图片描述
通过this.$children可以得到当前实例的所有子组件实例集合

vm.$root

用来获取当前组件树的根Vue实例,如果当前实例没有父实例,则获取到的是该实例本身。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm.$root</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <my-component></my-component>
</div>

</body>
<script>
    Vue.component('my-component',{
        template:'<button @click="root">查看根实例</button>',
        methods:{
            root(){
                //在控制台输出this.$root
                console.log(this.$root)
                //用于判断this.$root和vm.$root是否为同一实例对象
                console.log(this.$root === vm.$root)
            }
        }
    })
    var vm = new Vue({
        el:'#app'
    })
</script>
</html>

在这里插入图片描述

vm.$slots

Vue中的组件中使用template模板定义HTML结构,为了方便使用template公共模板结构,Vue提出了插槽(Slots)的概念,插槽就是定义在组件内部的template模板,可以通过¥slots动态获取。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm.$slots</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <!--在my-component组件内容内添加了"你好",该内容只有通过插槽才能显示在页面,否则不会显示-->
    <my-component>您好
        <!--使用template模板结构来定义插槽,template命名通过v-slot来完成-->
       <template v-slot:second>
          <div>内部结构</div>
       </template>
    </my-component>
</div>
<template id="first">
    <div>
        <!--启用了插槽-->
        <slot></slot>
        <!--编写slot元素启用指定name值的插槽-->
        <slot name="second"></slot>
    </div>
</template>
</body>
<script>
    Vue.component('my-component',{
        template:'#first'
    })
    var vm = new Vue({
        el:'#app'
    })
    // 在控制台查看插槽内容
    console.log(vm.$children[0].$slots.second[0].children[0].text)
</script>
</html>

在这里插入图片描述

vm.$attrs

可以获取组件的属性,但其获取的属性不包括class,style以及被声明的props的属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm.$attrs</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <!--为<my-component>组件设置了id属性为test-->
    <my-component id="test"></my-component>
</div>
</body>
<script>
    //注册<my-component>组件
    Vue.component('my-component',{
        //给按钮绑定了单击事件showAttrs
        template:'<button @click="showAttrs">查看属性</button>',
        methods:{
            //事件处理方法用来输出组件的this.$sttrs属性
            showAttrs(){
                console.log(this.$attrs)
            }
        }
    })
    var vm = new Vue({
        el:'#app'
    })
</script>
</html>

在这里插入图片描述

全局配置

在开发环境下,Vue提供了全局配置对象,通过配置对象可以实现生产信息提示,警告忽略等人性化处理。

productionTip

当在网页中加载vue.js(开发版本)文件时,浏览器的控制台会出现英文的提示信息,提醒用户"您正在开发模式下运行Vue,在为生产部署时,请确保打开生产模式"。如果要打开生产模式,使用Vue.mi.js文件代替vue.js文件即可。

silent

Vue全局被指对象时,silent可以取消Vue日志和警告,值类型为boolean,默认值为false,设为true表示忽略警告和日志,否则不忽略。

devtools

在Vue全局配置中可以对该工具进行配置,将Vue.config.devtools设为true表示允许调试,否则不允许调试。

组件进阶

在Vue中,组件是对结构的抽象,组件可复用性很强,每个组件拥有自己的作用域,区域之间独立工作互不影响,从而降低了代码的耦合度。Vue还可以对组件的选项轻松完成合并,让组件的功能变得灵活,使用起来更加方便。

minxins混入

mixins是一种分发Vue组件中可复用功能的方式。mixins对象可以包含任何组件选项,当组件使用mixins时,将定义的mixins对象引入组件中即可使用,mixins中的所有选项将会混入到组件自己的选项中。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>混合元素</title>
    <script src="../vue.js"></script>
</head>
<body>
</body>
<script>
    //定义myMixin对象,组件中的mixins属性用来配置组件选项,其值为自定义选项
    var myMixin = {
        created(){
            this.hello()
        },
        methods:{
            hello(){
                console.log('hello from mixin!')
            }
        }
    }
    //通过Vue.extend()创建实例构造器Component
    var Component = Vue.extend({
        //将自定义的myMixin对象混入到Component中
        mixins:[myMixin]
    })
    //通过new方式完成组件实例化
    var compenent = new Component();
</script>
</html>

在这里插入图片描述

render渲染

在Vue中可以使用Vue.render()实现对虚拟DOM的操作。在Vue中一般使用template来创建HTML,但这种方式可编程性不强,而使用Vue.render()可以更好地发挥JS的编程能力。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>render</title>
    <script src="../vue.js"></script>
</head>
<body>
<div id="app">
    <my-component>成功渲染</my-component>
</div>
</body>
<script>
    Vue.component('my-component',{
        //定义渲染函数render(),该函数接收createElement参数,用来创建元素
        render(creatElement){
            //creatElement()函数有3个参数,第1个参数表示创建p元素,
            // 第2个参数为配置对象,
            // 第3个参数为插槽内容"成功渲染",插槽内容可以通过$slot来获取
            return creatElement('p',{
                style:{
                    color:'red',
                    fontsize:'16px',
                    backgroundColor:'#eee'
                }
            },this.$slots.default)
        }
    })
    var vm = new Vue({
        el:'#app'
    });
</script>
</html>

在这里插入图片描述

createElement创建元素

render()函数的返回值中需要调用createElement()函数来创建元素。createElement()函数返回的并不是一个实际的DOM元素,它返回的其实是一个描述节点,用来告诉Vue在页面上需要渲染什么样的节点。这个描述的节点也可以称为虚拟节点。而"虚拟DOM"是对由Vue组件树建立起来的整个VNode树的称呼。
creatElement()函数的使用非常灵活,它的第一个参数可以是一个HTML标签名或组件选项对象,第2个参数是可选的,可以传入一个与模板中属性对应的数据对象,第3个参数是由creatElement()构建而成的子级虚拟节点,具体可以参考Vue的官方文档。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>createElement</title>
    <script src="../vue.js"></script>
</head>
<body>

<div id="app">
    <!--在my-component组件中通过v-slot的方式定义header,content,footer插槽-->
    <my-component>
        <template v-slot:header>
            <div style="background-color: #fff;height: 50px">
                这里是导航栏
            </div>
        </template>

        <template v-slot:content>
            <div style="background-color: #eee;height: 50px">
                这里是图书展示信息
            </div>
        </template>

        <template v-slot:footer>
            <div style="background-color: #aaa;height: 50px">
                这里是底部信息
            </div>
        </template>
    </my-component>
</div>

</body>
<script>
   Vue.component('my-component',{
       render(createElement){
           //使用this.$slot获取插槽,然后通过createElement()处理后渲染到页面中
           return createElement('div',[
               createElement('header',this.$slots.header),
               createElement('content',this.$slots.content),
               createElement('footer',this.$slots.footer)
           ])
       }
   })
   var vm = new Vue({
       el:'#app'
   })
</script>
</html>

在这里插入图片描述

Vue过渡和动画

Vue路由

Vuex状态管理

Vue开发环境

服务器端渲染

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪碧不加奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值