认识Vue
Vuejs是一个渐进式的框架,所谓渐进式框架,就是可以将vue作为项目的一部分嵌入进去。比如说要对一个项目进行重构,如果整体进行重构的话,可能任务量非常的大。那么可以只重构某一部分,一步一步让Vue渗透整个项目,这就是渐进式。
vue的特点
- 前端路由技术,vue-router
- 状态管理,vue-x
- MVVM
- 虚拟DOM
- 可复用的组件
Vue中的MVVM
所谓MVVM,实际上是三个不同的东西:1.View 2.Model 3.vueModel
- view 视图层,也就是我们页面中的DOM元素
- Model 数据层,就是我们实例中的data
- VueModel 视图模型层,也就是我们的vue实例,他是我们视图层和数据层之间的桥梁。他做了两件事儿来将两者联系到一起,1.数据绑定,通过vue实例将data中的数据绑定到了dom上面。2.事件监听,通过监听dom元素的事件。从而对数据做出改变。
创建一个Vue实例
引入Vue.js
我使用的方式从Vue.js的官网直接下载开发版本然后复制粘贴
Vue.js的链接:Vue.js
下载好后直接用script标签在head里面引入即可。最好在head标签中引入,如果在body尾部引入可能会出现抖屏的情况。
声明一个Vue实例
引入Vue.js后,我们可以直接通过Vue这个构造函数声明一个Vue的实例。
引入vuejs的三种方式
-
通过cdn引入
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>放在head处。这是从cdn服务器中下载vuejs。这种方法可适用于你要发布这个项目的情况。 -
通过本地下载然后本地引入
这种方式可用于平时学习的情况。因为这种速度上来说应该是最快的。 -
npm安装
-
tips:vuejs 分为开发版本和生产版本。开发版本就是你开发的时候使用的。一般更大一些,包含了很多命令行警告。开发的时候可能更容易入手。另一个是生产版本,也就是你的项目要投入使用发布上线了,这个时候得考虑客户体验运行速度,就应该优化一下代码,把不必要的东西都删掉了,优化了他的大小。
<!DOCTYPE html>
<html lang="zh">
<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></title>
<script src="../vue.js"></script><!--如何引入Vue.js 通过script标签引入,而且这种方式最好放在head标签里面,放在body的尾端可能会出现抖屏的现象-->
</head>
<body>
<div id="root">{{msg}}</div>
<script>
new Vue({//声明一个Vue实例,参数是一个对象
el:"#root",//决定了这个Vue实例和谁进行绑定
data:{
msg:"hello world",//存放这个实例的变量
}
})
</script>
</body>
</html>
Vue函数的构造函数的参数时一个对象,该对象有很多属性:
- el属性
决定了该实例时和谁进行绑定,vue实例是要写在挂载的html元素的后面的。它可以传两种值,一种是字符串比如:"#app",还有一种就是HTMLElement对象,比如document.querySelector("#app"); - data属性
存放这个实例要用到的变量,data属性可以是我们直接定义出来的然后放在data里面。也可以是来自网络,我们通过请求,从服务器加载,再把这些数据放在data里面,我们的site项目其实用的很多。
3.template属性
存放vue实例的模板 - methods属性
存放vue实例的方法 - filters
这个属性比较简单就直接在这里描述叭,这里我写了一些伪代码。filters对应一个对象,里面都是充当过滤器的函数。也就是说过滤器本质上是一个函数,使用它的时候直接在需要过滤的元素后面添加|过滤器即可,过滤器函数中有一个参数,你要过滤的元素会默认传给它。
<div id="app">{{price|fun}}</div>
const app = new Vue({
el:"#app",
data:{
price:60
},
filters:
{
fun(a)
{
return a.toFixed(2)
}
}
})
挂载点模板和实例
实例
如上述代码,new Vue()就生成了一个实例
挂载点
Vue实例的el属性对应的那个DOM节点就是挂载点
模板
Vue实例有个template属性,就是模板的意思,模板的意思是挂载点里面全部内容,模板可以写在 挂载点的HTML代码内
<div id="root"><h1>hello world<h1></div>
也可以写在Vue实例的template属性里面:
new Vue({
el:"#root",
template:'<h1>hello<h1>',
data:{
msg:"hello world"
}
})
关于模板使用遇到的几个问题
- 使用模板后为什么DOM结构不存在挂载点?
<div id="root"></div>
<script>
new Vue({
el:"#root",
template:"<h1>{{msg}}</h1>",
data:
{
msg:"hello world"
}
})
</script>
得出的HTML代码是:
这是为什么呢?
原因是在最后渲染的时候Vue会用template把被挂载的元素给替换掉,所以不会出现在DOM结构里面。所以这也导致html元素和body元素不适合当挂载点
2. 如下代码:
<div id="root"></div>
<script>
new Vue({
el:"#root",
template:"{{msg}}",
data:
{
msg:"hello world"
}
})
</script>
在控制台会报错:
Component template requires a root element, rather than just text.模板组件必须有一个根元素。而且仅有一个根元素。所以我觉得刚刚那个HTML代码就是一个template的说法还是有一些欠妥:因为实际的HTML代码并不一定需要根元素比如这里就直接这样就可以实现了:
<div id="root">{{msg}}</div>
注意一个细节:仅有一个:如果我有两个根元素会怎么办呢?
<div id="root"></div>
<script>
new Vue({
el:"#root",
template:'<div>3</div><div>2</div>'
data:
{
msg:"hello world"
}
})
</script>
结果是这样的:
<div>3</div>
说明他会把第一个根元素当成根元素。
Vue实例中的数据事件和方法
vue实例中的数据和挂载点如何联系
1. 使用插值表达式
{{msg}}这种形式就是插值表达式。这个也叫mustache语法
{{}}里面不仅可以是变量,也可以是js表达式。
<h1>{{xing}}<h1>
<h1>{{ming}}<h1>
<h1>{{xing+ming}}<h1>
2. v-text指令
<div id="root" v-text="msg"></div>
它的意思是这个元素的内容就是由这个v-text来决定的,v-text后面的值是一个JS表达式,不一定是单独的变量。也可以进行拼接。
<div id="root" v-text="'fasfdsa'+msg"></div>
3.v-html指令
<div id="root" v-html="msg"></div>
v-html后面也是一个JS表达式,不一定是单独的变量。也可以进行拼接。
三者的比较
看一段代码:
<div id="root">
<p>{{msg}}</p>
<p v-text="msg"></p>
<p v-html="msg"></p>
</div>
<script>
new Vue({
el:"#root",
data:
{
msg:"<h1>hello world</h1>"
}
})
</script>
输出结果:
区别一:
v-text和{{}}会把数据原格式输出,即使数据里面有HTML标签,而v-html会把数据按照html解析,可以解析各个HTML标签。
区别二:
v-text和{{}}表达式之间的区别:
- v-text是渲染绑定元素的全部文本数据,不能渲染局部的文本数据,而{{}}插值表达式只渲染占位符的地方。举一个很简单的例子。如果我们想渲染这句话“苹果5元一斤”。我们只绑定了价格的数据,那么我们应该进行{{}}的局部渲染,而不是全局渲染。==>"苹果{{message}}元一斤"
- {{}}是会出现闪烁问题的,而v-text是不会出现闪烁问题的,这是为什么呢?
很简单:如果因为网速等方面的原因,vue.js还没有加载出来也就是和DOM元素绑定的那个vue实例还没加载出来,而{{}}这种方法就像上面他的DOM代码是这样的
<p>{{msg}}</p>
所以屏幕显示一开始是{{msg}},当实例加载出来后,显示就变成了<h1>hello world</h1>
**这个问题被称为屏幕闪烁。**可能我们平时没注意到,可以利用setTmeout放大这种情况:
setTimeout(()=>new Vue({
el:"#root",
data:
{
msg:"<h1>hello world</h1>"
}
}),10000);
怎么解决这个问题呢?
利用v-cloak这个指令,该指令的意思是,v-cloak会一直和元素进行绑定,作为元素的属性。直到该元素对应的实例编译完毕。
那么这样我们可以利用这个特点,让他在实例加载前使整个元素都被display:none,当实例加载v-cloak不再和元素绑定,又显示出来就解决了闪屏问题。css代码:
<style>
[v-cloak]
{
display: none;
}
</style>
这样就可以把实例加载前的DOM元素隐藏掉。
注意点:最好把style样式写在link标签内,或是行内,别写在@import “url”中,因为@import的样式会在页面DOM加载完成后才会去加载,闪屏问题并没有得到解决
总结:如果要解析html,就用v-html;如果就是渲染纯文本数据:v-text/{{}};渲染局部数据使用{{}}防止闪屏和v-cloak指令搭配使用。
一些其他的基本指令
- v-once.就是绑定的元素或者组件只进行一次的数据渲染。之后就不会随着数据改变而重新渲染了。
- v-pre.就是将标签中的内容原封不动的渲染到页面上不做任何的解析。
事件绑定和方法
怎么给元素绑定事件?
利用v-on:这个模板指令给元素绑定事件
<div id="root"> <h1 v-on:click="fun">{{msg}}</h1> </div>
这里就是给h1元素绑定了一个click事件。当触发事件时,应该执行fun方法,fun方法应该在哪里定义呢?
应该在Vue实例的methods属性里面
<script>
new Vue({
el:"#root",
data:{
msg:"hello world"
},
methods:{
fun:function()
{alert(123);},
func:function ()
{
this.msg="nishizhu"
}
}
})
</script>
methods属性的值是一个对象,包含了你要用到的方法的定义,注意方法里面function(){}中的this应该是这个vue实例,这个很好理解,所以要改变vue实例的数据,应该是this.msg 另外这里有一种简写形式:v-on:<===>@即@click和v-on:click一致。
vue的生命周期
Vue和人一样,都是生命周期的。都会经历生老病死的各个阶段。简单一下描述一下Vue的生命周期。
- 初始化阶段,就是我们的new Vue();做这个操作的时候,其实vue实例已经诞生,但是它的内部为我们做了很多的事儿
- 他将它create,创建出来。并且再创建前后的两个时间点做两个"记号",一个是beforeCreate,另一个是created。这是两个生命周期函数。当你到达这一阶段的时候,他会自动调用你定义的生命周期函数。
- 编译我们vue实例或者组件的template,并将其挂载到页面上。这个过程被称为mount,挂载。就是将我们编译好的template挂载到页面上的过程,这个时候new Vue()的操作才算执行完成。同时在这同样有两个狗子函数也就是“标记”。beforeMount和mounted函数。
- 更新。创建好了之后,vue实例会一直监听数据的改变。这也就是我们熟悉的响应式。数据的改变会导致页面的改变。当我们对页面做出更新时,他也有两个钩子函数,beforeUpdata和updated函数。
- 消亡。一般这个根实例是不会消亡的,但是组件会消亡。destroy。他也有两个钩子函数,beforeDestroy和destroyed