Vue基础

介绍

vue.js是目前前端web开发最流行的工具库,由尤雨溪在2014年2月发布的。

另外几个常见的工具库:react.js /angular.js/jQuery

官方网站:

​ 中文:https://cn.vuejs.org/

​ 英文:https://vuejs.org/

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

vue.js目前有1.x、2.x和3.x 版本,我们学习2.x版本的。

jquery的定位是获取元素完成特效
vue的定位是方便操作和控制数据完成特效

下载安装

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

基本使用

1. vue的使用要从创建Vue对象开始
   var vm = new Vue();
   
2. 创建vue对象的时候,需要传递参数,是json对象,json对象对象必须至少有两个属性成员
var vm = new Vue({
    el:"#app",
    data: {					# 存放数据
        数据变量:"变量值",
        数据变量:"变量值",
        数据变量:"变量值",
    },
    methods: {				# 存放函数方法
        myAlert(){
            alert(123);
        }
    }

});
   
   el:设置vue可以操作的html内容范围,值一般就是css的id选择器。
   data: 保存vue.js中要显示到html页面的数据。
   
3. vue.js要控制器的内容范围,必须先通过id来设置。
  <div id="app">
      <h1>{{message}}</h1>
      <p>{{message}}</p>
  </div>

# 三个注意事项
1.变量名必须是唯一的,一个页面有多个vue对象,每个对象对应一个功能
2.js里面所有的变量和语法都是区分大小写的
3.script标签的位置

vue.js的MVVM思想

MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式。

Model 指代的就是vue对象的data属性里面的数据。这里的数据要显示到页面中。

View 指代的就是vue中数据要显示的HTML页面,在vue中,也称之为“视图模板” 。

ViewModel 指代的是vue.js中我们编写代码时的vm对象了,它是vue.js的核心,负责连接 View 和 Model,保证视图和数据的一致性,所以前面代码中,data里面的数据被显示中p标签中就是vm对象自动完成的。

2011-05-03 14h43_20

  • 数据驱动视图
<script>
    window.onload = function(){		   
        var vm = new Vue({		# 创建vm对象, VM
            el: "#app",
            data: {				# M
                name:"大标题",
                age:16,
            },
        })
    }
</script>

<div id="app">					# V
        <h1>{{name}}</h1>
        <p>{{age}}</p>
        <input type="text" v-model="name">
</div>

在浏览器中可以在 console.log通过 vm对象可以直接访问el和data属性,甚至可以访问data里面的数据

console.log(vm.$el)     # #box  vm对象可以控制的范围
console.log(vm.$data);  # vm对象要显示到页面中的数据
console.log(vm.$data.message);  # 访问data里面的数据
console.log(vm.message);# 这个 message就是data里面声明的数据,也可以使用 vm.变量名显示其他数据,message只是举例.

模版语法

Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。

在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

插值

文本插值{{}}或者指令v-text

<span>{{ msg }}</span>
<span v-text='msg'></span>
<span v-once>{{ msg }}</span>
# {{}} 和v-text等价
# 无论何时,绑定的数据对象上 msg变量发生了改变,插值处的内容都会更新。
# 如果使用了指令v-once则数据仅仅执行一次插值,当数据改变时,插值处的内容不会更新

原始HTML:指令v-html

<p>{{ rawHtml }}</p>
<p v-html="rawHtml"></p>	# rawHtml: '<a href="https:\\www.baidu.com">点我</a>'
# 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html

标签属性v-bind

双大括号语法不能作用在HTML标签的属性上,如果需要动态绑定标签属性数据,使用指令v-bind

<a v-bind:href="url" v-bind:title="title">{{ txt }}</a>
        
data:{
    title: '百度一下',
    url: 'https://www.baidu.com',
    txt: '百度'
},

对于布尔型的属性绑定的对象需要时布尔值的变量,此外也可以绑定自定义属性。

<button v-bind:disabled="isButtonDisabled">Button</button>
# 如果 isButtonDisabled 的值是 null、undefined 或 false,则disabled属性不会生效

补充

# 双大括号内可以使用变量、表达式、函数等合法的js语法,以下都是合法的
    {{ number + 1 }}
    {{ ok ? 'YES' : 'NO' }}
    {{ message.split('').reverse().join('') }}
    <div v-bind:id="'list-' + id"></div>
# 但是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
    <!-- 这是语句,不是表达式 -->
    {{ var a = 1 }}
    <!-- 流控制也不会生效,请使用三元表达式 -->
    {{ if (ok) { return message } }}

指令

指令是带有 v- 前缀的特殊 属性。指令的值通常是单个JS表达式(v-for 是例外情况)。

指令的职责:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

插值指令v-textv-html

v-text和双大括号的作用一样,都是插值普通文本,直接渲染,类似js的innerText
v-html既能插值普通文本,又能插入html的标签,相当于js的innerHTML

插值指令v-model

在表单输入框中显示数据要使用`v-model`来完成数据显示
<input type="text" v-model="txt">
<textarea name="" id="" cols="30" rows="10" v-model="txt"></textarea>

# 使用v-model把data里面的数据显示到表单元素以后,一旦用户修改表单元素的值,则data里面对应数据的值也会随之发生改变,甚至,页面中凡是使用了这个数据都会发生变化。

总结

  • 在双标签中显示数据要通过{{ }}来完成数据显示,双括号中还可以支持js表达式和符合js语法的代码,例如函数调用
  • 如果要输出html代码,则不能使用双打括号,要使用v-html来插值;v-html必须在html标签里面作为属性写出来
  • 在表单输入框中显示数据要使用v-model来完成数据显示

绑定指令v-bind

v-bind简写为:

# v-bind的作用就是绑定,动态的将标签属性值和数据变量绑定到一块,实现操作属性、样式、class类等
# 属性
<a v-bind:href="url" v-bind:title="title">{{ txt }}</a>
        
# class类
<h1 :class="值">元素</h1>  值可以是字符串、对象、对象名、数组
<p v-bind:class="isActive">{{ msg }}</p>	# isActive: 'active'
<p v-bind:class="{active: isActive}">{{ msg }}</p>	# isActive: true
<p v-bind:class="myCls">{{ msg }}</p>		# myCls:{'red': false, 'greed': true,}
<p :class="[mycls1, mycls2]">第三个段落</p>	# 批量给元素增加多个class样式类
    
# 样式
# 格式1,值是json对象,对象写在元素的:style属性中
<div :style="{color: activeColor, fontSize: fontSize + 'px' }"></div>
    data: {
             activeColor: 'red',
             fontSize: 30
         }
# 格式2:值是对象变量名,对象在data中进行声明
<div v-bind:style="styleObject"></div>
    data: {
            styleObject: {
                color: 'red',
                fontSize: '13px'
            }
		}
# 格式3:值是数组
<div v-bind:style="[style1, style2]"></div>
    data: {
        style1:{
            color:"red"
        },
        style2:{
            background:"yellow",
            fontSize: "21px"
        }
    }

条件指令v-ifv-show

v-if和v-show都是用于条件性的渲染某一块内容,即它俩的相同的点后面值都是布尔型的
v-if和v-show不同点在于:
	v-if是真正的渲染,即如果条件不成立则直接将dom节点从dom树种销毁,而v-show则是通过style样式来隐藏标签
    v-if后面可以接v-else-if和-v-else,不过需要同时连续使用,分开则无效
    
<h4 v-if="num==1">one</h4>
<h1 v-else-if="num==2">two</h1>
<h4 v-else>three</h4>

<h4 v-show="num==1">one</h4>


# 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
# 因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

循环指令v-for

在vue中,可以通过v-for指令可以将一组数据渲染到页面中,数据可以是数组或者对象。

# 循环数组
<ul>
    <!--第一个元素是数据,第二个元素是索引下标-->
    <li v-for="(book, index) in book_list">第{{ index+1}}本图书:{{book.title}}</li>
</ul>

# 循环对象
<ul>
    <!--第一个元素是值,第二个元素是键-->
    <li v-for="value, attr in book">{{attr}}:{{value}}</li>
</ul>

# 进循环数据值,不要索引或者键
<li v-for="book in book_list">{{book.title}}</li>
<li v-for="value in book">{{value}}</li>

事件指令v-on简写为:@

简单事件处理逻辑直接写在字符串里面即可

<button v-on:click="num++">按钮</button>   <!-- v-on 是vue1.x版本的写法 -->
<button @click="num+=5">按钮2</button>

复杂事件处理逻辑,单独写一个函数放在methods中通过函数名调用执行

<button v-on:click="greet">Greet</button>

methods: {
    greet(){
        alert('Hello ' + this.name + '!')
    }
}
    
# 总结
1. 使用@事件名来进行事件的绑定
   语法:
      <h1 @click="num++">{{num}}</h1>

2. 绑定的事件的事件名,全部都是js的事件名:
   @submit   --->  onsubmit
   @focus    --->  onfocus
   @blur     --->  onblur
   @click    --->  onclick

Vue对象属性功能

过滤器

自定义过滤器用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:

 <p>{{ money|RMB}}</p>
<input type="text" :value="msg|myUpper">

data:{money: 4.12317,msg: 'hello world'},
    # 过滤器放在filters内
    filters:{
        RMB(money) {
            return money.toFixed(2) + 'RMB'
        },
        myUpper(msg){
            return msg.toUpperCase()
        }
}

定义过滤器的方式有两种。

使用Vue.filter()进行全局定义

Vue.filter("RMB1", function(v){
  	//就是来格式化(处理)v这个数据的
  	if(v==0){
    		return v
  	}
  	return v+"元"
})

在vue对象中通过filters属性来定义

var vm = new Vue({
  el:"#app",
  data:{},
  filters:{
    RMB2:function(value){
      if(value==''){
        return;
      }else{
      	return '¥ '+value;
      }
    }
	}
});

计算属性和监听器

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。所以,对于任何复杂逻辑,你都应当使用计算属性

<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
    
# 计算器放在computed内
data: {message: 'Hello'},
computed: {
    reversedMessage: function () {
        // `this` 指向 vm 实例
        return this.message.split('').reverse().join('')
    }
}

方法与计算属性的异同

  • 同一函数定义为一个方法或者计算属性,并且两种方式的最终结果确实是完全相同。
  • 然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
  • 也就是说函数涉及的参数没有改变时,调用计算属性不会执行而是直接返回结果;而方法则是再执行一边。
  • 计算属性最大的优点:可以产生缓存,如果数据没有发生变化则直接从缓存中取数据。

侦听属性,可以帮助我们侦听data某个数据的变化,从而做相应的自定义操作。

侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。

<button @click="num++">点赞({{num}})</button>
# 监听器都放在watch内
watch:{
    num(){
        console.log(this.num);
    }
}
    
# 此外,num()还可以接受两个参数,分别标签改变后的值和改变前的值
num(v1, v2){
    console.log('修改后'+v1, '修改前'+v2);
}

深度监听

当我们想要监听一个对象或者一个数组中数据元素的变化时,普通的监听无法满足要求,需要使用深度监听

<!--监听students数组内元素属性的变化--->
<div id="app">
    <h3>{{ students[0].name }}</h3>
    <button @click="students[0].age++">修改年龄</button>
</div>

<script>
    var vm = new Vue({
        el:"#app",
        data:{
            students: [
                {name: 'jack', age: 18}
            ]
        },
        watch:{				
            students: {		// 深度监听用法:对象内deep和handler
                deep: true,
                handler: function (newV, oldV) {
                    console.log(newV);
                }
            }
        }
    });
</script>

vue对象的生命周期

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>局部过滤器</title>
    <script src="vue.js"></script>
</head>
<body>
    <div id="app">
        <p @click="num++">{{num}}</p>
    </div>
    <script>
        var vm = new Vue({
            el:"#app",
            data:{
                num: 10,
            },
            // beforeCreate(){
            //     console.log("----vm对象初始化完成之前自动执行的代码----");
            //     console.log(this.$el);
            //     console.log(this.$data);
            // },
            created(){ // 这里主要实现到服务端获取页面数据[ajax]
                console.log("----vm对象初始化完成以后自动执行的代码----");
                console.log(this.$el); // 没有查找到vm需要控制的元素
                console.log(this.$data); // 已经把data模型中的数据注入到vm对象里面作为属性了
            },
            // beforeMount(){
            //     console.log("----vm数据渲染到html模板之前执行的代码----");
            //     console.log(this.$el); // 没有查找到vm需要控制的元素
            // },
            mounted(){ // 修改页面的内容[页面特效]
                console.log("----vm数据渲染到html模板之后执行的代码----");
                console.log(this.$el); // 没有查找到vm需要控制的元素
            },
            // beforeUpdate(){
            //     console.log("----数据更新了,渲染之前执行的代码------");
            //     console.log(this.num);
            //     console.log(this.$el.innerHTML);
            // },
            // updated(){
            //     console.log("----数据更新了,渲染之后执行的代码------");
            //     console.log(this.num);
            //     console.log(this.$el.innerHTML);
            // },
            // 销毁vm对象 vm.$destroy()
            beforeDestroy(){
                console.log("--- 当vm对象被销毁之前,会自动执行这里的代码 ---");
                console.log( this );
            },
            destroyed(){
                console.log("--- 当vm对象被销毁以后,会自动执行这里的代码 ---");
            }
        });
    </script>
</body>
</html>


# 总结
在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
mounted阶段就是在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
另一个就是created,这个阶段就是在 vue对象创建以后,把ajax请求后端数据的代码放进 created

阻止事件冒泡和刷新页面

事件冒泡:指代js中子元素的事件触发以后,会导致父级元素的同类事件一并被触发到。

事件冒泡有好处,也有坏处。

好处:如果能正确利用这种现象,可以实现事件委托,提升特效的性能

坏处:如果没有正确使用,则会导致不必要的bug出现。

使用.stop.prevent

<div id="app">
    <div class="box1" @click="alert('box1')">
        <!-- @click.stop来阻止事件冒泡 -->
        <div class="box2" @click.stop.prevent="alert('box2')"></div>  
	</div>
    
    <form action="#">
        <input type="text">
        <input type="submit">
        <!-- @click.prevent来阻止表单提交 -->
        <input type="submit" value="提交02" @click.prevent=""> 
    </form>
</div>

补充1:js阻止事件冒泡

box2.onclick = function(event){
     alert("点击了box2");
     console.log(event);
     event.stopPropagation();	// 原生js阻止事件冒泡
 }

补充2:js事件委托,将事件绑定给父标签

// 可以通过事件委托来提升性能
var ul = document.getElementById("app");
ul.onclick = function(event){
 // 事件最初的触发元素
 var self = event.target;
 console.log(self.innerHTML)
}
posted @ 2020-06-17 23:38  the3times  阅读(191)  评论(0)    收藏  举报