Vue学习

官网文档:https://cn.vuejs.org/v2/guide/

vue下载:https://cdn.staticfile.org/vue/2.2.2/vue.min.js

1.Vue的引入:

<script src="vue.min.js"></script>

2.Vue的数据绑定,MVVM模式(Model-View-ViewModel)

注意:所写的Vue的view必须都包含在定义的id内,即el:“#app”,都在这个id内

html

 <!-- 创建一个view -->
 <!-- 利用双大括号实现文本插值 -->
    <div id="app">
        {{mess}}
    </div>
js

//创建一个model
var messData = {
    "mess": "我是一段文本"
}

// 创建一个 Vue 实例或 "ViewModel"
// 它连接 View 与 Model
new Vue({
    el: "#app",//就是上面绑定视图层的id
    data: messData
})


写法也可以改成下面这种,合并在一起写:

new Vue({
    el: "#app",
    data: {
        "mess": "我是一段文本"
    }
})

使用Vue的过程就是定义MVVM各个组成部分的过程的过程。

  1. 定义View
  2. 定义Model
  3. 创建一个Vue实例或"ViewModel",它用于连接View和Model

3.双向绑定示例

 <!-- 创建一个view -->
  <!-- input这里,通过v-model实现双向数据绑定,这里input的值实时改变,p的值也会实时改变,注意这里v-model插入的值,不需要用大括号包起来 -->

    <div id="app">
         <p>{{mess}}</p>
        <input type="text" v-model="mess">
    </div>

将mess绑定到文本框,当更改文本框的值时,<p>{{ mess}}</p> 中的内容也会被更新。同时改变mess的值,input文本框的值也会改变

 

4.Vue.js的常用指令

文档:https://cn.vuejs.org/v2/api/#%E6%8C%87%E4%BB%A4

上面用到的v-model是Vue.js常用的一个指令,那么指令是什么呢?

Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。

Vue.js提供了一些常用的内置指令,接下来我们将介绍以下几个内置指令:

  • v-if指令
  • v-show指令
  • v-else指令
  • v-else-if 指令
  • v-for指令
  • v-bind指令
  • v-on指令
  • v-model  双向数据绑定
  • v-once  只渲染元素和组件一次
  • v-html  解析带有html标签的文本

 v-if指令

v-if是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:

v-if="expression"

expression是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式。例如:

<div id="app">
            <h1>Hello, Vue.js!</h1>
            <h1 v-if="yes">Yes!</h1>
            <h1 v-if="no">No!</h1>
            <h1 v-if="age >= 25">Age: {{ age }}</h1>
            <h1 v-if="name.indexOf('jack') >= 0">Name: {{ name }}</h1>
        </div>

 注意:所有的数据绑定Vue都支持使用  JavaScript 表达式  例如上面使用的三元表达式,indexOf,split 等等使用都是支持的

这里v-if,可以是bool属性,也可以用来做运算

 var vm = new Vue({
            el: '#app',
            data: {
                yes: true,
                no: false,
                age: 28,
                name: 'keepfool'
            }
        })

可以直接打印出:
console.log(vm.yes)--->true

注意:v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。

 

v-show指令

v-show也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style属性。

他跟上面v-if的作用上功能是类似的,区别是v-if为false的时候,这个dom结构不会存在,但是v-show为false的时候,dom还是存在的,不过是display:none了

把以上v-if的地方改成v-show,对比下他们的odm结构

v-if                                                                                              v-show                             

 

在页面展示出来的效果都是一样的:

 

v-else指令

可以用v-else指令为v-ifv-show添加一个“else块”。

注意:

(1).v-else元素必须立即跟在v-ifv-show元素的后面——否则它不能被识别。

(2).v-else元素是否渲染在HTML中,取决于前面使用的是v-if还是v-show指令。
(3).只有当v-if和v-show为false时,才会走v-else。如果v-if是true时,后面的v-else不会渲染到HTML中;v-show为tue,后面的v-else会渲染到HTML了,但是display:none 隐藏掉了

 

   <div id="app">
        <h1 v-if="yes">Yes!</h1>
        <h1 v-else>No!</h1>
        <h1 v-show="age >= 25">Age: {{ age }}</h1>
        <h1 v-show="name.indexOf('jack') >= 0">Name: {{ name }}</h1>
    </div>

 

var vm = new Vue({
    el: '#app',
    data: {
        yes: false,
        no: false,
        age: 28,
        name: 'keepfool'
    }
})

v-for指令

v-for指令基于一个数组渲染一个列表,它和JavaScript的遍历语法相似:可以遍历数组对象,数组,对象,数字

v-for="item in items"

items是一个数组,item是当前被遍历的数组元素。

注意:

(1).这里需要遍历多个li的时候,直接v-for绑定在li上,如果绑定在ul上,会渲染多个ul包裹一个li的结构

(2).v-for="item in items" 。in前面的是自定义的for的value, in后面的是遍历的变量名

(3)v-for 还支持一个可选的第二个参数,即当前项的索引。<div v-for="(value, name) in object"></div>

         且支持传入第三个参数<div v-for="(value, name, index) in object"></div>

(4).你也可以用 of 替代 in 作为分隔符  。    <div v-for="item of items"></div>

     可以支持遍历 对象,数组,一个数值,例如遍历10这个值,遍历数值的时候,最小下标是1,例如遍历时,渲染出来的是1-10

(5).为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性:<div v-for="item in items" v-bind:key="item.id"></div>,设置成key值的话必须是唯一的,不推荐使用index来作为key,可以是时间戳加上一个自增的数字

 <div id="app">
        <ul>
            <li v-for="item in arr">{{item.name}}</li>
            <!-- <li v-for="item in arr1">{{item}}</li> -->
            <!--<li v-for="value in pageCount">{{value}}</li>-->
        </ul>
    </div>
var vm = new Vue({
    el: '#app',
    data: {
        arr: [
            { name: 'zhaosan', age: 18 },
            { name: 'lsi', age: 5 },
            { name: 'ww', age: 18 },
            { name: 'xiao', age: 6 }
        ],
        arr1: [1, 3, 4, 5, 6],
        pageCount: 10
    }
})
v-for="(item, index) in items"  传入第二个参数,当前项的索引

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>

var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

在 v-for 里使用对象

可以传入第三个参数,拿到属性名,属性值,索引

还可以用第三个参数作为索引:
 <div id="app">
        <ul id="example-2">
            <li v-for="(value, index,indexs) in object">
                {{ value }} - {{ index }} - {{ indexs }}
            </li>
        </ul>
    </div>

var vm = new Vue({
    el: "#app",
    data: {
        parentMessage: 'Parent',
        object: {
            title: 'How to do lists in Vue',
            author: 'Jane Doe',
            publishedAt: '2016-04-10'
        }
    }
})

建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

<div v-for="item in items" v-bind:key="item.id">
  <!-- 内容 -->
</div>

避免 v-if 和 v-for 用在一起

这里假如需要操控数据,例如给arr增加一项,则可以通过以下写法:

 vm.arr.push({ name: '我我我', age: 100})

则,arr就变成了5项数据了

 

 

v-bind指令

v-bind指令可以在其名称后面带一个参数,中间放一个冒号隔开,这个参数通常是HTML元素的特性(attribute),例如:v-bind:class, v-bind:title 是加属性的

 

v-bind:argument="expression"

例如:以下实现给元素绑定一个active的class,这里实现的给1-3的li下面的a加上了active的class

 <div id="app">
        <ul class="pagination">
            <li v-for="n in pageCount">
                <a href="javascripit:void(0)" v-bind:class="activeNumber >= n  ? 'active' : ''">{{ n }}</a>
            </li>
        </ul>
    </div>
var vm = new Vue({
    el: '#app',
    data: {
        activeNumber: 3,
        pageCount: 10
    }
})

效果如下:

div id="app-2">
  <span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
  </span>
</div>

 

var app2 = new Vue({
  el: '#app-2',
  data: {
    message: '页面加载于 ' + new Date().toLocaleString()
  }
})

 

假如需要将一个对象的全部属性,都通过v-bind绑定上去,写法如下:

如果你想把一个对象的所有属性作为 prop 进行传递,可以使用不带任何参数的 v-bind (即用 v-bind 而不是 v-bind:prop-name)

html:

 <div id="app">
        <p v-bind="todo">wenben</p>

    </div>


js:

var vm = new Vue({
    el: "#app",
    data: {
        todo: {
            text: 'Learn Vue',
            isComplete: 'false'
        }
    }
})

效果:

 

v-on指令

v-on指令用于给监听DOM事件,它的用语法和v-bind是类似的,例如监听<a>元素的点击事件:

<a v-on:click="doSomething">

有两种形式调用方法:绑定一个方法(让事件指向方法的引用),或者使用内联语句。

注意:

(1).事件和方法要写在methods中

(2).事件中的this指向的就是new出来的这个vue对象

  <div id="app">
       <div>
            <!--click事件直接绑定一个方法-->
           <button v-on:click="clickMe">我是一个按钮</button>

            <!--click事件使用内联语句-->
           <button v-on:click="clickThis('hello')">我是一个</button>

       </div>
    </div>

 

var vm = new Vue({
    el: '#app',
    data: {
        activeNumber: 3,
        pageCount: 10
    },
    // 在 `methods` 对象中定义方法
    methods: {
        clickMe: function() {
            // 方法内 `this` 指向 vm
            console.log(this.activeNumber)
        },
        clickThis: function(msg) {
            console.log(msg)
        }
    }
})

v-bind和v-on的缩写

Vue.js为最常用的两个指令v-bindv-on提供了缩写方式。v-bind指令可以缩写为一个冒号,v-on指令可以缩写为@符号。

<!--完整语法-->
<a href="javascripit:void(0)" v-bind:class="activeNumber === n + 1 ? 'active' : ''">{{ n + 1 }}</a>
<!--缩写语法-->
<a href="javascripit:void(0)" :class="activeNumber=== n + 1 ? 'active' : ''">{{ n + 1 }}</a>

<!--完整语法-->
<button v-on:click="greet">Greet</button>
<!--缩写语法-->
<button @click="greet">Greet</button>

v-model

预期:随表单控件类型不同而不同。

限制

  • <input>
  • <select>
  • <textarea>
  • components

修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。

  • .lazy - 取代 input 监听 change 事件
  • .number - 输入字符串转为有效的数字
  • .trim - 输入首尾空格过滤
html:

  <div id="app">
        <p>{{msg}}</p>
        <!--.lazy 取代 input 监听 change 事件 input的msg改变了,但是上面p中的内容不会跟着变 -->
        <input v-model.lazy="msg" >
        <!-- .number 输入的是数字时,会将输入类型转化为数字类型;数字是文字等字符串则无效 -->
        <input v-model.number="msg" >
        <!--.trim 会去除输入时两头的空格  -->
        <input v-model.trim="msg" >
    </div>

js:

let vm = new Vue({
    el: '#app',
    data: {
        msg:'aa',
        age:18,
        trims:'wenben'
    }
});

 

v-once

文档:https://cn.vuejs.org/v2/api/#v-once

  • 不需要表达式
  • 只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。当数据改变时,插值处的内容不会更新。
例:当修改input框的值时,使用了v-once指令的p元素不会随之改变,而第二个p元素时可以随之改变的
html:

<div id="app">
		<p v-once>{{msg}}</p>  //msg不会改变
		<p>{{msg}}</p>
		<p>
			<input type="text" v-model = "msg" name="">
		</p>
	</div>
	


js:

let vm = new Vue({
			el : '#app',
			data : {
				msg : "hello"
			}
});

v-html

  • 双大括号会将数据解释为普通文本,而非 HTML 代码,解析不了标签,样式等
  • 语法: v-html='mess' 
html:
 <div id="app">
        <p id="a">Using mustaches: {{ rawHtml }}</p>
        <p>Using v-html directive: </p>
    </div>

js:

let vm = new Vue({
    el: '#app',
    data: {
        rawHtml: '<span style="color:red">利用vue添加了插入一个span 元素</span>' //元素内数据代码 message
    }
});

以上效果如下:标签没有被解析,而是直接输出了

解决方法就是:

通过 v-html="rawHtml",输出真正的HTML

html:
 <div id="app">
        <p id="a" v-html="rawHtml">Using mustaches: {{ rawHtml }}</p>
        <p>Using v-html directive: </p>
    </div>

js:

let vm = new Vue({
    el: '#app',
    data: {
        rawHtml: '<span style="color:red">利用vue添加了插入一个span 元素</span>' //元素内数据代码 message
    }
});

效果如下:

 

 

5.组件化应用构建 

Vue.component ()定义组件:一个组件本质上是一个拥有预定义选项的一个 Vue 实例

注意:

(1).定义的组件名称跟使用时要一致,

(2).定义组件 Vue.component  必须写在 new Vue的前面,否则不生效

(3).组件是可复用的,例如这里通过 Vue.component定义了一个my-comp的组件后,在视图中可以多次使用,而且互不干扰

  (4).组件注册可以是 全局注册 和 局部注册

(5).单个根元素,每个组件必须只有一个根元素。

<div id="app">
       <!--my-comp就是在vue中定义的组件名称  -->
      <my-comp></my-comp>
      <my-comp></my-comp>
      <my-comp></my-comp>
    </div>
//my-comp:定义的组件名称
Vue.component('my-comp',{
    template:'<p>我是一个组件的内容</p>'
})

var vm=new Vue({
    el:"#app",
    data:{

    }
})

上面定义的组件文本是写死的,那怎么可以动态渲染这个组件呢

方法:这里通过v-bind,将属性绑定上,然后在定义的component组件中,通过props属性,将定义的属性拿到,传给组件

   <div id="app">
        <!--my-comp就是在vue中定义的组件名称  -->
        <my-comp v-for="item in groceryList" v-bind:title="item" v-bind:ids="item.id">
            
        </my-comp>
    </div>
//my-comp:定义的组件名称
Vue.component('my-comp',{
    props:['title','ids'],
    template:'<div>{{title.text}}<p>{{ids}}</p></div>'
})

new Vue({
    el: "#app",
    data: {
        groceryList: [
            { id: 0, text: '蔬菜' },
            { id: 1, text: '奶酪' },
            { id: 2, text: '随便其它什么人吃的东西' }
        ]
    }
})

效果:

还可以: 以下实现点击,自动加1的效果 

    <div id="app">
        <!--my-comp就是在vue中定义的组件名称  -->
        <my-comp>
            
        </my-comp>
    </div>

   
//my-comp:定义的组件名称
Vue.component('my-comp',{
  data:function(){
    return {
        count:0
    }
  },
    template:'<div v-on:click="count++">这是{{count}}的值</div>'
})

注册组件的方式:

全局注册:

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

new Vue({ el: '#app' })


局部注册:

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

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

 

使用 prop 传递数据:

在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。

Vue.component('child', {
  // 声明 props
  props: ['message'],
  // 就像 data 一样,prop 也可以在模板中使用
  // 同样也可以在 vm 实例中通过 this.message 来使用
  template: '<span>{{ message }}</span>'
})

<child message="hello!"></child>


结果:hello!

HTML 特性是不区分大小写的。所以,当使用的不是字符串模板时,camelCase (驼峰式命名) 的 prop 需要转换为相对应的 kebab-case (短横线分隔式命名):

Vue.component('child', {
  // 在 JavaScript 中使用 camelCase
  props: ['myMessage'],
  template: '<span>{{ myMessage }}</span>'
})

<!-- 在 HTML 中使用 kebab-case -->
<child my-message="hello!"></child>

如果你使用字符串模板,则没有这些限制。

因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

data: function () {

  return {

    count: 0

    }

}

当需要传参比较复杂时的处理:

当需要传递多个参数时,这样写会很复杂:

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:title="post.title"
  v-bind:content="post.content"
  v-bind:publishedAt="post.publishedAt"
  v-bind:comments="post.comments"
></blog-post>

改写:

<blog-post
  v-for="post in posts"
  v-bind:key="post.id"
  v-bind:post="post"
></blog-post>

Vue.component('blog-post', {
  props: ['post'],
  template: `
    <div class="blog-post">
      <h3>{{ post.title }}</h3>
      <div v-html="post.content"></div>
    </div>
  `
})

Vue.extend():另一种注册组件的方法

文档:https://segmentfault.com/a/1190000012826671

 html:
<my-comp></my-comp>


js:
定义组件方法1:

Vue.component('my-comp',{
    template:'<p>我是直接定义的模板</p>'
})
new Vue({
    el: "#app",
    data: {

    }
})




定义组件方法2:使用Vue.extend()定义组件

var comp=Vue.extend({
     template:'<p>我是直接定义的模板</p>'
})

Vue.component('my-comp',comp);

new Vue({
    el: "#app",
    data: {

    }
})

$mount:用于挂载

文档:https://segmentfault.com/a/1190000012826671

注意:

(1).通过$mount挂载后,会直接替换掉当前的dom;

   (2). $mount(),参数可以是一个class或者id。 跟视图中的对应上就可以

(3).这种用法, 不需要new Vue 都可以直接使用

html:

<div id="app">
        <p>我是11</p>
        <div id="mount-point"></div>
   </div>





js:

var Profile =Vue.extend({
     template:'<p>我是直接定义的模板</p>'
})
new Profile().$mount('#mount-point')

 

结果是:

局部注册

你不必把每个组件都注册到全局。你可以通过某个 Vue 实例/组件的实例选项 components 注册仅在其作用域中可用的组件:

html:

  <div id="app">
        <my-component></my-component>
    </div>

js:

var Child = {
  template: '<div>A custom component!</div>'
}

new Vue({
  el:"#app",
  components: {
    // <my-component> 将只在父组件模板中可用
    'my-component': Child
  }
})

这里组件使用,对于一些特殊的DOM标签,需要注意:

像 <ul>、<ol>、<table>、<select> 这样的元素里允许包含的元素有限制,而另一些像 <option> 这样的元素只能出现在某些特定元素的内部。

这种特殊的标签,自定义组件 <my-component> 会被当作无效的内容,因此会导致错误的渲染结果。变通的方案是使用特殊的 is 特性:

错误写法:

 <table id="app">
         <my-component></my-component> 
      </table>

正确写法:通过is绑定

 <table id="app">
        <tr is="my-component"></tr>

</table>

 

js:

var Child = {
  template: '<div>A custom component!</div>'
}

new Vue({
  el:"#app",
  components: {
    // <my-component> 将只在父组件模板中可用
    'my-component': Child
  }
})

 

应当注意,如果使用来自以下来源之一的字符串模板,则没有这些限制:

  • <script type="text/x-template">
  • JavaScript 内联模板字符串 (例如:template: '...')
  • .vue 组件 (.vue)

因此,请尽可能使用字符串模板。

 

6.css过渡&动画

文档:https://cn.vuejs.org/v2/guide/transitions.html

以下实现一个点击按钮,显示,隐藏的效果,并且加了过渡效果

(1).过渡

css:
   <style>
    .fade-enter-active,
    .fade-leave-active {
        transition: opacity .5s;
    }

    .fade-enter,
    .fade-leave-to {
        opacity: 0;
    }
    </style>


html:
注意这里transition这里的name ,这里fade会被替换成fade-enter,fade-leave等等,跟上面的css类名对应
  <div id="demo">
        <button v-on:click="show=!show">按钮</button>
        <transition name="fade">
            <p v-if="show">显示</p>
        </transition>
    </div>

js:
new Vue({
    el: '#demo',
    data: {
        show: true
    }
})

过渡的类名

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

  3. v-enter-to2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

  4. v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

  6. v-leave-to2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="my-transition">,那么 v-enter 会替换为 my-transition-enter

(2).CSS 动画

CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。但是他们类名使用都是一样的

css:用到animation实现动画效果

.bounce-enter-active {
  animation: bounce-in .5s;
}
.bounce-leave-active {
  animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(1);
  }
}

Object.freeze()

这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

var obj = {
  foo: 'bar'
}

//Object.freeze(obj),这样操作后,视图中改变foo的值会报错
Object.freeze(obj)

new Vue({
  el: '#app',
  data: obj
})

 Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来

vm.$  后面跟的就是vm的属性,区别于其他的

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

console.log(data)===等同于 console.log(vm.$data)

$watch:当定义的值改变的时候触发

html:

 <div id="app">
      <button v-on:click="{{a++}}">加值</button>
    </div>

js:

var vm = new Vue({
    el: '#app',
    data: {
        a:11
    }
})

vm.$watch('a', function(newValue, oldValue) {
    console.log(newValue)
    console.log(oldValue)
    // 这个回调将在 `vm.a` 改变后调用
})

7.生命周期钩子

 created :实例被创建之后自动立即执行

var vm = new Vue({
    el: '#app',
    data: {
        obj: {
            yes: 'shi',
            no: "false",
            age: 28,
            name: 'keepfool'
        }

    },
    created:function(){
          // `this` 指向 vm 实例
        console.log(this.obj.name)
    }
})

//这里页面加载的时候,直接注册的实例,所以页面加载的时候,直接打印出了 'keepfool'
created就是加载实例的时候,直接调用

也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mountedupdated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例。

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

created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。

mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

如:数据初始化一般放到created里面,这样可以及早发请求获取数据,

如果有依赖dom必须存在的情况,就放到mounted(){this.$nextTick(() => { /* code */ })}里面

window.onload=function(){
            let vm=new Vue({
                el:'#itany',
                data:{
                    msg:'welcome to itany'
                },
                methods:{
                    update(){
                        this.msg='欢迎来到南京网博!';
                    },
                    destroy(){
                        // this.$destroy();
                        vm.$destroy();
                    }
                },
                beforeCreate(){
                    alert('组件实例刚刚创建,还未进行数据观测和事件配置');
                },
                created(){  //常用!!!
                    alert('实例已经创建完成,并且已经进行数据观测和事件配置');
                },
                beforeMount(){
                    alert('模板编译之前,还没挂载');
                },
                mounted(){ //常用!!!
                    alert('模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示');
                },
                beforeUpdate(){
                    alert('组件更新之前');
                },
                updated(){
                    alert('组件更新之后');
                },
                beforeDestroy(){
                    alert('组件销毁之前');
                },
                destroyed(){
                    alert('组件销毁之后');
                }
            });
        }

8.计算属性(computed)

文档:https://cn.vuejs.org/v2/guide/computed.html

当我们需要在模板中有计算的时候,可以直接运用js的语法计算,但是当这种计算比较频繁时,这样写比较麻烦,写在计算函数中就比较方便,运用计算属性 computed

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

改成下面写法: 

属性调用的时候,不需要(),直接写属性名就可以

 

html:
   <div id="app">
        <p>{{trims}}</p>
        <p>{{jisuan}}</p>
    </div>

js:

let vm = new Vue({
    el: '#app',
    data: {
        trims: 'wen-ben'
    },
  //定义计算属性
    computed: {
         // 在computed里定义方法,使用的时候直接写方法名
        jisuan: function() {
            return this.trims.split('').reverse().join('')
        }
    }
});

效果如下:

如果是需要对后台请求回来的数据进行处理:

//list.js
computed: {
      timeHandle: function() {
       //这里需要加个闭包的写法,来传入参数
        return function(time) {
          return time.substr(5, 5).replace(/-/g, '.');
        }

      }
    },


html
//这里调用computed里面的计算函数来处理这个时间的输出

  <div class="lis_con">
       <h1>{{item.sGameName}}</h1>
       <span class="btn-go"></span>
       <p>{{timeHandle(item.sDate)}}-{{timeHandle(item.eDate)}}</p>
  </div>

计算属性computed的getter和setter:  

<div id="root">
    {{fullName}}
</div>
<script>
    var vm=new Vue({
        el: "#root",
        data: {
            firstName: 'Dell',
            lastName: 'Lee',
            fullname: 'Dell Lee'
        },
        computed:{
            fullName:{
                get: function () {
                    return this.firstName+" "+this.lastName
                },
                set: function (value) {
                    var arr=value.split(" ");
                    this.firstName=arr[0];
                    this.lastName=arr[1];
                }
            }
        }
     
    })

同样的效果,我们也可以通过在methods中写一个方法来实现,方法调用的时候需要加() reversedMessage()

<p>Reversed message: "{{ reversedMessage() }}"</p>


methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

他们的区分是:

  • 属性计算,只在计算的属性发生改变时才会执行,不改变的话则读取的缓存; 方法则每次渲染都会执行

参考:https://www.cnblogs.com/zzliu/p/10778008.html

计算属性 vs 侦听属性

vue中有watch来计算属性,以上这种,我们通过computed,侦听属性更方便

Vue中computed和watch的区别

计算属性computed : 

1. 支持缓存,只有依赖数据发生改变,才会重新进行计算

2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化

3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过的数据通过计算得到的

4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed

5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

 

侦听属性watch:

1. 不支持缓存,数据变,直接会触发相应的操作;

2.watch支持异步;

3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;

4. 当一个属性发生变化时,需要执行对应的操作;一对多;

与computed对比,watch更加适用于监听某一个值的变化并做对应的操作,比如请求后台接口等,而computed适用于计算已有的值并返回结果

1.如果一个数据依赖于其他数据的简易计算处理的,那么使用computed比较合适。
2.如果需要在某个数据变化时做一些事情,使用watch来观察这个数据变化

watch: {

    number (newVal, oldVal) {//有两个参数,改变后的值,改变前的值

     console.log('number has changed: ', newVal)

   }

}

 

 

9. Class 与 Style 绑定

绑定 HTML Class

(1)对象语法:   

  • 使用对象;例:v-bind:class='{active:classA}'
  • 三元表达式
  • 直接定义一个对象的形式绑定class :例  v-bind:class="classObject"
  • 计算属性来实现 
html:
 <div id="app">
       <p v-bind:class='{active:classA}'>对象语法 绑定class</p>
       <p v-bind:class='{active:classA,active1:classB}'>对象语法 绑定多个class</p>
       <p v-bind:class='classA?"active":""'>三元绑定class</p>
       <p v-bind:class="classObject">内联定义class</p>
    </div>

js:

var vm = new Vue({
    el: "#app",
    data: {
        classA: false,
        classB: true,
        classObject: {
            active: true,
            'text-danger': true
        }
    }
})

通过计算属性来实现绑定class:

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

(2)数组语法

  • 直接定义一个数组
  • 也可以结合三元表达式一起用
  • 结合对象一起用
html:
<div id="app">
        <div v-bind:class="[active,ups]">数组绑定的方式</div>
        <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
        <div v-bind:class="[{ active: isActive }, errorClass]"></div>
</div>

js:

var vm=new Vue({
    el:"#app",
    data:{
        active:"classA",
        ups:"on"
    }
})

(3).用在组件上

当在一个自定义组件上使用 class 属性时,这些类将被添加到该组件的根元素上面。

Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})

<my-component class="baz boo"></my-component>

HTML 将被渲染为:

<p class="foo bar baz boo">Hi</p>

绑定内联样式

v-bind:style

对象语法

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

data: {
  activeColor: 'red',
  fontSize: 30
}

数组语法

 

10.条件渲染

用 key 管理可复用的元素

只需添加一个具有唯一值的 key 属性即可:

这里的需求是切换这两个 template,input的值也需要相互独立,各不影响

template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

11.数组更新检测

变异方法 

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

替换数组

例如:filter()concat() 和 slice() ,它们不会改变原始数组,而总是返回一个新数组

注意事项

由于 JavaScript 的限制,Vue 不能检测以下数组的变动:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

同样,还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 现在是响应式的

vm.b = 2
// `vm.b` 不是响应式的

可以先定义,后赋值,则可以是响应式的

 

对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性

但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。例如,对于:

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})

你可以添加一个新的 age 属性到嵌套的 userProfile 对象:

Vue.set(vm.userProfile, 'age', 27)

你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:

vm.$set(vm.userProfile, 'age', 27)

有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性

vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

12.事件处理

事件修饰符

在事件处理程序中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop等同于JavaScript中的event.stopPropagation(),防止事件冒泡
  • .prevent等同于JavaScript中的event.preventDefault(),用于取消默认事件,防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)
  • .capture :与事件冒泡的方向相反,事件捕获由外到内,捕获冒泡
  • .self :只会触发自己范围内的事件,不包含子元素
  • .once :只会触发一次
  • .passive:2.3.0 新增 ,不阻止事件的默认行为
<!-- 阻止单击事件继续传播 -->
<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>

 (1).stop

已下效果,点击button的时候,会冒泡到外层包着的两层div的事件,所以会看到控制台打印(1)inner,(2)inner,(3)inner,但是如果我们想要的只想触发button的事件的话,则用.stop    <button @click.stop="inner">click</button>


<!-- HTML -->
<div id="demo">
    <div @click="outer" style="padding: 20px;background-color:deepskyblue">
      <div  @click="middle" style="padding: 10px;background-color: darkcyan">
          <button @click="inner">click</button>
      </div>
    </div>
</div>

<!-- JS -->
    var demo = new Vue({
        el: '#demo',
        methods: {
            inner: function () {
                console.log ('(1)inner')
            },
            middle: function () {
                console.log ('(2)middle')
            },
            outer: function () {
                console.log ('(3)outer')
            }
        }
    })

(2).prevent

某些标签拥有自身的默认事件,比如<a>标签点击后会进行页面的跳转。这类默认事件虽然是冒泡后开始的,但不会因为stop而停止执行。阻止执行这类预设的行为,.prevent就派上用场了。例如已下,加上 .prevent后,就不会跳转了

 <a href="http://www.baidu.com" @click.prevent>点击跳转</a>

(3).capture

对比于上面的.stop(),将中间层的点击事件加上.capture修饰符

 <div @click="outer" style="padding: 20px;background-color:deepskyblue">
      <div @click.capture="middle" style="padding: 10px;background-color: darkcyan">
          <button @click="inner">click</button>
      </div>
     </div>

带修饰符的从外到内依次执行,然后再按正常顺序执行触发的事件。

(4).self

将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响。对比与上面的stop案例,给中间层加上.self,这个时候点击button的时候,发现 (2)inner没有打印出来,只有点中间层的时候,才会打印(2)inner

(5).once

加上once修饰符以后事件只触发一次,但是不影响事件的冒泡,上层的事件仍然会被触发

例如上面的,给button加上.once后,一直点击,发现 (1)inner 只打印了一次,但是(2)inner,(3)inner每次点击都会打印

(6).passive

这里涉及到一个问题,为什么需要告诉浏览器不阻止事件的默认行为?
原因是这样的,浏览器只会在每次触发监听器的时候,才去判断这次是否有调用preventDefault()来阻止默认行为。这样的判断,在某些场景下会影响交互,像用户通过手势滑动页面时,就没法迅速滚动了,而使用.passive就可以提前告诉浏览器,我们没有用preventDefault阻止默认动作,你也不用反复去判断了,从而提高性能解决卡顿。

不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你想阻止事件的默认行为。

13.按键修饰符

例如:监听键盘 enter键时的keyup事件
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

如果想监听所有键盘的keyup事件,则:
<input v-on:keyup="submit">

按键码

keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。用法是:<input v-on:keyup.13="submit">

记住所有的keyCode比较困难,为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

鼠标修饰符

鼠标修饰符用来限制处理程序监听特定的滑鼠按键。常见的有:

  • .left:鼠标左键
  • .middle:鼠标中间滚轮
  • .right:鼠标右键

修饰键

可以用如下修饰符开启鼠标或键盘事件监听,使在按键按下时发生响应:

  • .ctrl 例:<div @click.ctrl="doSomething">Do something</div>,表示点击,且按住ctrl键才触发doSomething事件
  • .alt
  • .shift
  • .meta

 

14.表单输入绑定

你可以用 v-model 指令在表单 <input><textarea> 及 <select> 元素上创建双向数据绑定。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值