vue学习简单入门

1、MVVM思想

  • M:即Model,模型。包括数据和一些基本操作。
  • V:即View,视图。页面渲染结果。
  • VM:即View-Model,模型与视图间的双向操作。(无需开发人员干涉)

在MVVM之前,开发人员从后端获取到需要的数据模型,然后通过DOM操作Model渲染到View中。而后当用户操作视图,我们还需要通过DOM获取到View中的数据,然后同步到Model中去。

而MVVM中的VM就是要做这样的事情:把DOM操作完全封装起来,开发人员不用再关心Model和View之间是如何影响的。

2、Vue简介

官网: https://cn.vuejs.org/

3、入门案例

4、概念

1)、创建Vue实例

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<div id="app">
    <h1>{{a}}</h1>
    <button v-on:click="b">点击</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            a: 666
        },
        methods: {
            b() {
                this.a--;
            }
        }
    })
</script>
</body>
</html>

1、new 出来的vue实例管控这 id选择器为app的标签,整个div。
2、想要给这个div绑定一些数据,我们就要将所有的数据写在vue对象的另一个属性data里面。由于未来可能有很多的数据,所以我们写成一个对象{},这样很多的key-value都能用。
3、在标签体里面我们可以使用vue的插值表达式: {{}} 就可以从数据data里面取出key的value。
4、现在数据变,视图就会变目前是一个单向的过程。
5、这么强大的功能,我们只需要让vue管控这个元素,而元素里面的所有东西,我们都可以使用vue更强大的功能,更简化的语法。

创建vue实例(new),关联页面的模板,将自己的数据(data)渲染到关联的模板上。这个渲染过程是自动的。而且,只要data里的数据发生变化,那么模板也会跟着变。我们把这个过程称为响应式。

我们还可以通过指令,来简化对DOM的操作。比如:我们要双向绑定,我们使用v-model,点击事件的时候可以使用v-on,也可以绑定自定义的方法等。

声明的方法要放在vue的methods属性对象里面。

在方法中使用data中的数据,要用this.xx的方式。

总结:

  • el:绑定元素;
  • data:封装数据;
  • methods:封装方法;
  • ... vue对象还有很多属性,上面3个最常用。

2)、插值表达式

①、说明

格式:{{表达式}}

  • 该表达式支持js语法,可以调用js内置函数(但是必须要有返回值)。
  • 表达式必须有返回结果。
  • 可以直接获取vue实例中定义的数据和函数。

如:{{msg}}、{{1+1}}、{{func()}}、{{1+1=2?正确:错误}}

②、插值闪烁

使用{{}}这种方式在网速较慢的时候会出现问题。在数据未加载完成时,页面会显示原始的{{}},加载完毕后才显示正确数据,我们称它为插值闪烁。

F12开发者模式下,模拟网速慢,Network 可以调成slow 3G,就可以看到效果。

缺点:{{}}插值表达式只能用在标签体里面,如果标签的属性也要调用vue中定义的数据或函数,就不能使用{{}}插值表达式了。

那么,我们如何给属性动态的绑定vue实例定义的值呢?

3)、Vue指令

①、单向绑定: v-bind

{{}}只能给标签体绑定值,而给标签的属性绑定值则使用v-bind指令。

使用:

  • v-bind:属性名="数据"
  • :属性名="数据"

对标签的class和style属性的增强:

我们只需要写一个对象,然后这个对象的某个属性值跟vue实例中的数据进行绑定。

如: :class='{active:isActive,textDanger:hasError}'
如: :style='{color:color1,fontSize:size}'

②、双向绑定: v-model

v-model一般用于表单项、自定义组件。只有它们才需要双向绑定。

我们只需要将元素的跟模型里面的某一个属性进行绑定,以后我们页面输入框值变了,我们data中属性的值就会跟着变。而且,属性的值变化了,输入框里的值对应也会跟着变。这就是双向绑定的过程。

在我们日常开发中,我们都是使用v-model将我们表单里面的某一项跟数据进行绑定,这样我们实时来获取值也会很方便。

③、事件处理: v-on

我们用v-on绑定事件,我们可以直接对data里面的数据进行操作,而我们用jquery等框架则是不可以的。

使用:

  • v-on:事件名="方法名"
  • @事件名="方法名"

事件修饰符:

阻止事件的默认行为,如事件冒泡等,可以使用事件修饰符。

事件修饰符,是由点开头的指令后缀来表示的。

  • .stop:阻止事件冒泡到父元素。
  • .prevent:阻止默认事件发生。
  • .capture:使用事件捕获模式
  • .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
  • .once:只执行一次。

按键修饰符:

在监听键盘事件时,我们经常需要检查常见的键值。Vue允许为v-on在监听事件时添加按键修饰符。

// 只有在keyCode为13的时候调用vm.submit()
<input v-on:keyup.13="submit"/>

记住所有的keyCode比较困难,所以Vue为所有常见的键值取了别名。

//同上
<input v-on:keyup.enter="submit"/>

//缩写语法
<input @keyup.enter="submit"/>

全部的按键别名

  • .ctrl
  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

④、单向绑定:v-text 和 v-html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<div id="app">

    <span v-html="msg"></span>
    <span v-text="msg"></span>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            msg: '<h1>hello</h1>'
        }
    })
</script>
</body>
</html>

  • v-html:不会对html标签进行转义,直接会在浏览器中显示标签。
  • v-text:会对html标签进行转义。
  • 这2个指令都是单向绑定的。

⑤、遍历循环:v-for

  • 1、显示user信息: v-for="item in items"
  • 2、获取数组下标: v-for="(item,index) in items"
  • 3、遍历对象:
    v-for="value in obj"
    v-for="(value,key) in obj"
    v-for="(value,key,index)in obj"
  • 4、遍历的时候都加上 :key来区分不同的数据,可以提高vue渲染的效率。

⑥、判断与显示:v-if 和 v-show

  • v-if:顾名思义,条件判断。当得到的结果为ture时,所在的元素才会被渲染。
  • v-show:得到的结果为true时,所在的元素才会被显示。(相当于设置了display:none)

1、经常与v-if一起使用的还有:v-else、v-else-if。
2、v-if与v-for搭配使用时,v-if的优先级是低于v-for的。也就是v-for先遍历,拿到遍历的对象再根据v-if判断。

4)、计算属性

某些结果是基于之前的数据实时计算出来的,这种情况我们可以利用计算属性来完成。

计算属性computed是vue实例中的一个属性,所有需要动态计算的属性,都可以在写在这里。

它的特点是:该属性依赖的任意一个值发生变化,都会触发它的重新计算。

5)、侦听器

侦听器(watch),也是vue实例的一个属性。watch可以让我监控一个值的变化,从而做出相应的反应。

6)、过滤器

过滤器(filters)也是vue实例的一个属性,它是一个方法,它可以把要过滤的值当做参数传入进来,进行逻辑处理。

过滤器常用来处理文本格式的操作。过滤器可以用在2个地方:

  • ① 双花括号插值
  • ② v-bind表达式

过滤器如果写在vue实例里面,则是一个局部过滤器,它只可以在当前的vue实例中可以使用。如果要创建全局的过滤器写法是: Vue.filter(..);

7)、组件化

在项目开发过程中,往往在不同的页面中,会使用相同的部分,为了让这些重复的部分方便复用,我们就可以把它作为组件。

在vue里,所有的vue实例都是组件。我肯可以通过组件之间的灵活组合,完成更强大的功能。

例如:你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其他的像导航链接、博文之类的组件。

①、全局声明一个组件:

Vue.component('my-component-name', {
  // ... 选项 ...
})

这些组件是全局注册的。也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。比如:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

在所有子组件中也是如此,也就是说这三个组件在各自内部也都可以相互使用。

②、局部声明一个组件:

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

然后在 components 选项中定义你想要使用的组件:

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。

注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:

var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...

或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  // ...
}

注意在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

用在模板中的自定义元素的名称
包含了这个组件选项的变量名

说明: 组件的data() 是一个方法的返回。为什么呢?因为这样,我们每声明一个组件、每使用一个组件,它的数据都是调用这个方法而返回的一个新对象。那么每一个组件的数据,统计都是独立统计的。而如果返回以前的data的话,那么任何一个组件返回的对象都是同一个实例,那么就导致一处修改其他地方也会跟着修改,这样就达不到组件复用的效果了。

总结:

  • 组件其实也是一个vue实例,因此它在定义时也会接收:data、methods、生命周期函数等。
  • 不同的是,组件不会与页面元素进行绑定,否则就无法复用了。因此没有#el元素。
  • 但是组件渲染需要html模板,所以增加了template属性,值就是html模板。
  • 全局组件定义完毕,任何vue实例都可以直接在html中通过组件名来使用该组件。
  • data必须是一个函数,不再是一个对象。

8)、生命周期钩子函数

每个vue实例在被创建时都呀经历一系列的初始化过程:创建实例、装载模板、渲染模板等等。

为了简化开发,vue在生命周期中的每个状态都设置了钩子函数(也是监听函数)。每当vue实例处于不同的生命周期时,对应的生命周期函数就会被触发。

测试各个生命周期函数的执行时机:

created 钩子可以用来在一个实例被创建之后执行代码:

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

在实例生命周期的不同阶段被调用,如 mounted、updated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例

不要在选项属性或回调上使用箭头函数,
比如 created: () => console.log(this.a) 或vm.$watch('a', newValue => this.myMethod())。
因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,
经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

9)、vue的Live Template

<template>
    <div></div>
</template>

<script>
    //这里可以导入其他文件,如:组件、工具js、第三方插件js、json文件、图片文件等
    //例如:import [组件名称] from [组件路径];

    export default {
        //import引入的组件需要注入到对象中才可以使用
        components: {},
        //父子组件传递数据
        props: {},
        data(){
            //这里存放数据
            return {};
        },
        //计算属性,类似于data概念
        computed: {},
        //侦听器,监听data中的数据变化
        watch: {},
        //方法集合
        methods: {

        },
        //生命周期 - 创建完成(可访问当前this实例)
        created() {},
        //生命周期 - 挂载完成(可访问DOM元素)
        mounted(){

        },
        //生命周期 - 创建之前
        beforeCreated(){},
        //生命周期 - 挂载之前
        beforeMount(){},
        //生命周期 - 创建之前
        beforeCreated(){},
        //生命周期 - 更新之前
        beforeUpdate(){},
        //生命周期 - 更新之后
        updated(){},
        //生命周期 - 销毁之前
        beforeDestroy(){},
        //生命周期 - 销毁完成
        destroyed(){},
        //如果页面有keep-alive缓存功能,这个函数a会触发
        activated(){},

    }

</script>

<style lang="scss" scoped>
/*@import url(); 引入公共的css类*/

</style>

posted @ 2020-04-27 16:58  直角漫步  阅读(616)  评论(0编辑  收藏  举报