vue解决页面闪烁问题
- 我们发现访问页面时, 使用插值表达式的地方出现了闪烁问题,如何解决呢?
v-cloak
指令
- 作用: 解决插值表达式闪烁问题
- 当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak 指令来解决这一问题。
- 1) 添加样式
<style>
/* 通过属性选择器,设置 添加了v-cloak */
[v-cloak] { display: none; }
</style>
- 2) 在id为app的div中添加 v-cloak
<div class="wrap" id="app" v-cloak>
computed 计算属性
- 在Vue应用中,在模板中双向绑定一些数据或者表达式,但是表达式如果过长,或者逻辑更为复杂时,就会变得臃肿甚至难以维护和阅读,比如下面的代码:
<div>
写在双括号中的表达式太长了,不利于阅读
{{text.split(',').reverse().join(',')}}
</div>
将这段操作text.split(',').reverse().join(',') 放到计算属性中,最终返回一个结果值就可以
- computed 的作用: 减少运算次数, 缓存运算结果. 运用于重复相同的计算.
<!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>
<!--
1、计算属性可以减少运算次数,用于重复相同的计算
2、定义函数也可以实现与计算属性相同的效果,但是计算属性可以简化运算
-->
<div id="app">
<h1>{{a*b}}</h1>
<h1>{{res()}}</h1>
<h1>{{res2}}</h1>
<h1>{{res2}}</h1>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
a:10,
b:20
},
methods: {
res:function(){
return this.a + this.b;
}
},
// 使用计算属性 进行优化,减少运算次数,用于重复的运算
computed:{
res2:function(){
console.log("res2执行了")
return this.a + this.b;
}
}
})
</script>
</html>
- computed总结
- 1. 定义函数也可以实现与 计算属性相同的效果,都可以简化运算。
- 2. 不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
filter 过滤器
- 过滤器是对即将显示的数据做进一步的筛选处理,然后进行显示,值得注意的是过滤器并没有改变原来的数据,只是在原数据的基础上产生新的数据。
- 数据加工车间,对值进行筛选加工.
过滤器使用位置
- 1. 双括号插值内
{{ msg | filterA }}
msg是需要处理的数据, filterA是过滤器, | 这个竖线是管道,通过这个管道 将数据传输给过滤器进行过滤 加工操作
- 2. v-bind绑定的值的地方。
<h1 v-bind:id=" msg | filterA"> {{ msg }} </h1>
局部过滤器(需求
:
通过过滤器给电脑价格前面 添加一个符号$
)
<!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">
<!-- 使用插值表达式,调用过滤器 -->
<p>电脑价格:{{price | addIcon}}</p>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
// 局部过滤器 在vue实例中的内部创建filter
var vm = new Vue({
el:"#app",// 挂载点
data:{// model
price:200
},methods: {// 方法
},computed:{// 计算属性
},
// 局部过滤器
filters:{
// 定义处理函数
addIcon(value){
return "$" + value;
}
}
})
</script>
</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>
<!--
需求:将用户名开头字母大写
总结:
1、过滤器经常被用来处理文本格式化操作
2、过滤器使用的两个位置:{{}}插值表达式中,v-bind表达式中
3、过滤器是通过管道传输数据的
-->
<div id="app">
<p>{{user.name | changeName}}</p>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
// 在创建vue实例之前,创建全局过滤器
Vue.filter("changeName", function(value){
// 将姓名的开头字母大写
return value.charAt(0).toUpperCase() + value.slice(1);
})
var vm = new Vue({
el:"#app",
data:{
user:{name:"tom"},
}
})
</script>
</html>
总结
- 1. 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式
- 2. 过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示
watch 侦听器
- Vue.js 提供了一个方法 watch,它用于观察Vue实例上的数据变动。
- 作用: 当你有一些数据需要随着其它数据变动而变动时,可以使用侦听属性
案例演示(需求
:
监听姓名变化
,
实时显示 )
<!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">
<label for="">名:<input type="text" v-model="firstName"></label>
<label for="">姓:<input type="text" v-model="lastName"></label>
{{fullName}}
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
firstName:"",
lastName:"",
fullName:""
},
// 侦听器
watch:{
firstName:function(nval,oval){
this.fullName = nval+" "+this.lastName;
},
lastName:function(nval,oval){
this.fullName = this.firstName+" "+nval;
}
}
})
</script>
</html>
Component 组件
- 组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。
- 我们将相同的功能进行抽取,封装为组件,这样,前端人员就可以在组件化开发时,只需要书写一次代码,随处引入即可使用。
- 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树
vue
的组件有两种
:
全局组件
和 局部组件
- 全局组件
语法格式:
Vue.component("组件名称", {
template: "html代码", // 组件的HTML结构代码
data(){
//组件数据
return {}
},methods: { // 组件的相关的js方法
方法名(){ // 逻辑代码 }
}
})
注意
:
- 1. 组件名以小写开头,采用短横线分割命名: 例如 hello-Word
- 2. 组件中的data 必须是一个函数,注意与Vue实例中的data区分
- 3. 在template模板中, 只能有一个根元素
<!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">
<!-- 使用组件 -->
<lagou-header></lagou-header>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
// 定义全局组件
// 组件的命名规则: 一般用短横线进行连接 ,左边是公司名,右边是组件的作用名称
Vue.component("lagou-header",{
// template模板中 只能有一个根元素
template:"<div>html<h1 @click='hello'>{{msg}}</h1></div>",
// 组件中的data是一个函数
data(){
return {
msg:"lagou-header是组件中的数据部分"
}
},
methods:{
hello(){
alert("你好")
}
}
});
var vm = new Vue({
el:"#app",
data:{},
methods: {
},
})
</script>
</html>
- 局部组件
- 相比起全局组件,局部组件只能在同一个实例内才能被调用。局部组件的写法和全局组件差不多。 唯一不同就是:局部组件要写在Vue实例里面。
new Vue({
el: "#app",
components: {
组件名: {
// 组件结构
template: "HTML代码",
// data数据
data() {
return { msg:"xxxx" };
},
},
},
});
注意
:
- 创建局部组件,注意 components,注意末尾有 ‘s’,而全局组件是不用+ ‘s’ 的。这意味着,components 里可以创建多个组件。
<!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">
<web-msg></web-msg>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
// 创建局部组件
var vm = new Vue({
el:"#app",
components:{
// 组件名
"web-msg":{
template:"<div><h1>{{msg1}}</h1><h1>{{msg2}}</h1></div>",
data() {
return {
msg1:"开发正在进行。。。",
msg2:"开发完成。"
}
},
}
}
})
</script>
</html>
组件与模板分离
- 由于把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">
<!-- 使用组件 -->
<web-msg></web-msg>
</div>
<!-- 将模板写在HTML中,给模板一个id -->
<template id="t1">
<div>
<button @click="show">{{msg}}</button>
</div>
</template>
</body>
<script src="./js/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
components:{
"web-msg":{
template:"#t1",
data() {
return {
msg:"点击查询"
}
},methods: {
show(){
alert("正在查询");
}
},
}
}
})
</script>
</html>
总结
:
- 1. 上面这种写法,浏览器会把 html 里的 template 标签过滤掉。所以 template 标签的内容是不会在页面中展示的。直到它被 JS 中的 Vue 调用。
- 2. 在 html 中,template 标签一定要有一个 id,因为通过 id 是最直接被选中的。 data 和 methods等 参数,全部都要放到 Vue 实例里面写
Vue生命周期
1 生命周期图示
- 每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期
- 了解生命周期的好处:
- 1. 找错误
- 2. 解决需求
- 下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
2
钩子函数介绍
- 生命周期中的钩子函数
- 钩子函数:钩子函数是在一个事件触发的时候,在系统级捕获到了他,然后做一些操作
函数
|
说明
|
beforeCreate()
| 在创建Vue实例之前,可以执行这个方法. 例如 加载动画操作 |
created()
| 实例创建完成,属性绑定好了,但是DOM还没有生成 |
beforeMount()
| 模板已经在内存中编辑完成了,尚未被渲染到页面中. |
mounted()
| 内存中的模板已经渲染到页面,用户已经可以看见内容 |
beforeUpdate()
| 数据更新的前一刻 , 组件在发生更新之前,调用的函数 |
updated()
| updated执行时,内存中的数据已更新,并且页面已经被渲染 |
beforeDestroy
()
| 钩子函数在实例销毁之前调用 |
destroyed
()
| 钩子函数在Vue 实例销毁后调用 |
- 案例演示:
<!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">
<h2 id="msg">{{message}}</h2>
<button @click="next">获取下一句</button>
</div>
</body>
<script src="./js/vue.min.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
message:"时间从来不语"
},
methods: {
show(){
alert("show方法执行了")
},
next(){
this.message = "却回答了所有问题"
}
},
// beforeCreate() {
// alert("1、beforeCreate函数在组件实例化之前执行");
// console.log(this.message);
// this.show();
// },
// created() {
// alert("2、created函数执行时,组件的实例化完成,但是DOM页面还未生成");
// console.log(this.message);
// this.show();
// },
// beforeMount() {
// alert("3、beforeMount函数执行时,模板已经在内存中编辑完成了,但是还没有渲染到页面中")
// console.log(document.getElementById("msg").innerText)
// console.log("data中的数据:"+this.message);
// },
// mounted() {
// alert("4、mounted函数执行时,模板已经被渲染到页面,执行完就会显示页面")
// console.log(document.getElementById("msg").innerText)
// },
// beforeUpdate() {
// alert("5、beforeUpdate执行时,内存中的数据已经更新,但是还没有渲染到页面");
// console.log(document.getElementById("msg").innerText)
// console.log("data中的数据:"+this.message);
// },
updated() {
alert("6、updated执行时,内存中的数据已经更新了,此方法执行完显示页面")
console.log("data中的数据:"+this.message);
},
})
</script>
</html>
Vue Router 路由
1 什么是路由?
- 在Web开发中,路由是指根据URL分配到对应的处理程序。 路由允许我们通过不同的 URL 访问不同的内容。
- 通过 Vue.js 可以实现多视图单页面web应用(single page web application,SPA)
2
什么是
SPA ?
- 单页面Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
- 单页应用不存在页面跳转,它本身只有一个HTML页面。我们传统意义上的页面跳转在单页应用的概念下转变为了 body 内某些元素的替换和更新,举个例子:
- 整个body的内容从登录组件变成了欢迎页组件, 从视觉上感受页面已经进行了跳转。但实际上,页面只是随着用户操作,实现了局部内容更新,依然还是在index.html 页面中。
- 单页面应用的好处:
- 1. 用户操作体验好,用户不用刷新页面,整个交互过程都是通过Ajax来操作。
- 2. 适合前后端分离开发,服务端提供http接口,前端请求http接口获取数据,使用JS进行客户端渲染。
3
路由相关的概念
- router :
- 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用(SPA)变得易如反掌 ,router 就相当于一个管理者,它来管理路由。
- route:
- router相当于路由器, route就相当于一条路由.比如: Home按钮 => home内容, 这是一条route,news按钮 => news内容, 这是另一条路由。
- routes :
- 是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, {about按钮 => about 内容}]
- router-link组件:
- router-link 是一个组件,是对标签的一个封装. 该组件用于设置一个导航链接,切换不同 HTML内容。 to 属性为目标地址, 即要显示的内容
- router-view 组件:
- 路由导航到指定组件后,进行渲染显示页面
4 使用路由
- 1) Vue.js 路由需要载入 vue-router 库
//方式1: 本地导入
<script src="vue-router.min.js"></script>
//方式2: CDN
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
- 2) 使用步骤
- 1. 定义路由所需的组件
- 2. 定义路由 每个路由都由两部分 path (路径) 和component (组件)
- 3. 创建router路由器实例 ,管理路由
- 4. 创建Vue实例, 注入路由对象, 使用$mount() 指定挂载点
Vue 的$mount()为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作、判断等),之后要手动挂载上。new Vue时,el和$mount并没有本质上的不同。
- 3) HTM代码
<body>
<!--
1、router 是VUE中路由管理器对象,用来管理路由
2、route 是路由对象,一个路由就对应了一条访问路径,一组路由用routes
3、每个路由对象,都有两部分:path路径,component组件
4、router-link 是对a标签的封装,通过to属性指定链接
5、router-view 路由访问到指定的组件,进行页面展示
-->
<div id="app">
<h1>渣浪.com</h1>
<p>
<!-- 添加超链接 ,router-link 组件来进行导航,to属性指定链接 -->
<router-link to="/home">go to home</router-link>
<router-link to="/news">go to news</router-link>
</p>
<!-- 路由的出口,路由匹配到组件之后,要渲染到这里 -->
<router-view></router-view>
</div>
</body>
- 4) JS代码
<!-- 导入vue 与 router库 -->
<script src="./js/vue.min.js"></script>
<script src="./js/vue-router.min.js"></script>
<script>
// 定义路由所需的组件
const home = {template:"<div>首页 花边新闻</div>"};
const news = {template:"<div>新闻 新闻联播</div>"};
// 定义路由 每个路由有两部分 path(路径),component(组件)
const routes = [
{path:"/home",component:home},
{path:"/news",component:news}
];
// 创建路由管理器实例
const router = new VueRouter({
routes:routes
});
// 创建Vue实例 ,将rooter注入到vue实例中,让整个应用都拥有路由的功能
var vm = new Vue({
router
}).$mount("#app");// 代替el
</script>
- 5) 路由总结
- 1. router是Vue中的路由管理器对象,用来管理路由.
- 2. route是路由对象,一个路由就对应了一条访问路径,一组路由用routes表示
- 3. 每个路由对象都有两部分 path(路径)和component (组件)
- 4. router-link 是对a标签的封装,通过to属性指定连接
- 5. router-view 路由访问到指定组件后,进行页面展示