语法规则
前端渲染
渲染有几种方式:原生js、js模板、Vue模板语法
原生js
使用字符串拼接
js模板语法
Vue.js 模板语法概述
Vue.js 是一个用于构建用户界面的渐进式框架,其模板语法非常灵活和直观。Vue 的模板语法基于 HTML,可以通过指令、插值和特殊属性来实现数据绑定和事件处理。以下是 Vue.js 2 的模板语法的主要概念和示例。
1. 插值(Interpolation)
插值用于在模板中显示数据,可以使用双大括号 {``{ }}
进行文本插值,或者使用 v-bind
进行属性插值。
html
<div id="app">
<p>{{ message }}</p>
<p v-bind:title="title">Hover to see the title</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!',
title: 'This is a title'
}
})
</script>
2. 指令(Directives)
指令是带有 v-
前缀的特殊特性,用来在模板中做响应式数据绑定。常用指令包括 v-if
, v-for
, v-show
, v-model
, v-bind
, v-on
等。
- 条件渲染 :
v-if
,v-else-if
,v-else
html
<div id="app">
<p v-if="seen">Now you see me</p>
<p v-else>Now you don't</p>
</div>
<script>
new Vue({
el: '#app',
data: {
seen: true
}
})
</script>
- 列表渲染 :
v-for
html
<div id="app">
<ul>
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
]
}
})
</script>
- 事件处理 :
v-on
html
<div id="app">
<button v-on:click="sayHello">Click me</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
sayHello: function() {
alert('Hello, Vue!');
}
}
})
</script>
- 双向绑定 :
v-model
html
<div id="app">
<input v-model="message" placeholder="Edit me">
<p>Message is: {{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
})
</script>
3. 修饰符(Modifiers)
修饰符是以半角句号 .
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent
, .stop
, .capture
, .self
, .once
, .native
, .number
, .trim
。
html
<div id="app">
<form v-on:submit.prevent="onSubmit">
<button type="submit">Submit</button>
</form>
</div>
<script>
new Vue({
el: '#app',
methods: {
onSubmit: function() {
alert('Form submitted!');
}
}
})
</script>
4. 计算属性和侦听器
- 计算属性 :用来对模板中复杂逻辑进行计算并返回结果,类似于
data
属性,但会基于其依赖项缓存结果。
html
<div id="app">
<p>Reversed message: {{ reversedMessage }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
computed: {
reversedMessage: function() {
return this.message.split('').reverse().join('');
}
}
})
</script>
- 侦听器:用于监听数据属性的变化并执行相应的操作。
html
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
},
watch: {
message: function(newVal, oldVal) {
console.log('Message changed from', oldVal, 'to', newVal);
}
}
})
</script>
以上是 Vue.js 2 模板语法的基本介绍和一些示例代码。这些概念和指令使得 Vue.js 非常灵活和易于使用,适用于各种规模的应用开发。
- 插值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
指令
什么是指令:
- 什么是自定义属性
- 指令的本质就是自定义属性
- 指令的格式:以v-开始(比如V-cloak)
v-clock指令用法
在频繁刷新的时候可能会出现插值表达式,造成用户体验不好
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<style type="text/css">
[v-clock]{
display:none;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div v-clock>{{msg}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// v-clock指令用法
// 1.提供样式
// [v-clock]{
// display:none;
// }
// 2.在插值表达式所在的标签添加v-cloak指令
var vm =new Vue({
el:'#app',
data:{
msg:'HelloWord'
}
});
</script>
</body>
</html>
使用v-clock就可以不显示插值表达式,刷新页面直接出来数据
背后原理:
先通过样式隐藏内容,在内存中进行值的替换,替换好之后在显示最终的结果。
v-text 纯文本信息 v-html(容易遭遇跨站脚本攻击) v-pre 填充原始信息
v-once:如果显示的信息后期不需要再修改可以使用,可以提高性能。
v-model 双向绑定
MVVM设置思想
M(model)
V(view)
VM(View-Model)
重点是双向绑定
事件绑定
v-on指令语法 当然因为经常使用还提供一种简写方法@
当然在vue中我们可以给时间绑定一个方法写在,methods里面
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<style type="text/css">
[v-clock]{
display:none;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div>{{num}}</div>
<div>
<button v-on:click="num++">增加</button>
<button @click="num++">点击1</button>
<button @click="handle">点击1</button>
<button @click="handle()">点击1</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm =new Vue({
el:'#app',
data:{
num:0
},
methods:{
handle:function (){
//这里的this是vue的实例对象
console.log(this)
this.num++
}
}
});
</script>
</body>
</html>
事件参数传递
1.如果时间直接绑定函数名称,那末默认会传递事件对象作为时间函数的第一个函数
2.如果事件绑定函数调用,事件对象必须作为最后一个参数显示传递,必须对象名称必须$event
javascript
<button @click="handle($event)">点击1</button>
事件修饰符
按键修饰符
自定义按键修饰符
全局config.keyCodes对象
Vue.config.keyCodes.f1 = 112;
自定义按键修饰符名字是自定义的,但是对应的值必须是按键对应event对象中keyCode值
Vue.config.keyCodes.aaa = 65
Vue动态处理属性
v-bind指令用法
跳转
缩写形式
跳转
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<style type="text/css">
[v-clock]{
display:none;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<a v-bind:href="url">百度</a>
<button @click="handle"></button>
//v-model事件双向绑定其实就是使用了v-bind:value,和@input
<div>{{msg}}</div>
<input type="text" v-bind:value="msg" @input="handle">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm =new Vue({
el:'#app',
data:{
url:'http://www.baidu.com',
msg:'hello'
},
methods:{
handle:function (event){
//修改url地址
this.url='https://www.imooc.com/';
this.msg = event.target.value;
}
}
});
</script>
</body>
</html>
样式绑定
控制类名
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<style type="text/css">
.active{
border: 1px solid red;
width: 100px;
height: 100px;
}
.error{
background-color: orange;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div v-bind:class="{active: isAcrive,error: isError}"></div>
<button @click="handle">切换</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm =new Vue({
el:'#app',
data:{
url:'http://www.baidu.com',
msg:'hello',
isAcrive:true,
isError:true
},
methods:{
handle:function (){
//控制isActive在true和false之间切换
this.isAcrive = !this.isAcrive;
}
}
});
</script>
</body>
</html>
style样式处理
分支循环结构
- v-if
- v-else
- v-else-fi
- v-show
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<style type="text/css">
[v-clock]{
display:none;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div v-if="score>=90">优秀</div>
<div v-else-if="score<90&&score>=80">良好</div>
<div v-if="score<80&&score>=60">一般</div>
<div v-else>比较差</div>
<div v-show="flag">11</div>
<button @click="handle">取反</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm =new Vue({
el:'#app',
data:{
score:76,
flag:false
},
methods:{
handle:function (){
this.flag = !this.flag
}
}
});
</script>
</body>
</html>
循环结构
在Vue中如果有对象遍历最好加上key这样的话就不会报错,唯一的key
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue</title>
<style type="text/css">
[v-clock]{
display:none;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div>水果列表</div>
<ul>
<li v-for="item in fruits">{{item}}</li>
<li v-for="(item,index) in fruits">{{item + '____'+ index}}</li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm =new Vue({
el:'#app',
data:{
fruits:['apple','organg','banana']
},
methods:{
}
});
</script>
</body>
</html>
Vue的常用特性
- 表单操作
- 自定义指令
- 计算属性
- 过滤器
- 监听器
- 生命周期
表单操作
表单修饰符
- number:转化为数值
- trim:去掉开始和结尾的空格
- lazy:将input时间切换为change事件
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<input type="text" v-model.number="age">
<input type="text" v-model.trim="text">
<input type="text" v-model.lazy="msg">
<div>{{msg}}</div>
<button @click="handle">点击</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
age:'',
text:'',
msg:''
},
methods:{
handle:function (){
console.log(this.age+1)
console.log(this.text)
}
}
})
</script>
</body>
</html>
自定义指令
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<input type="text" v-focus>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.directive('focus',{
inserted:function (el){
//el表示指令绑定的元素
el.focus();
}
})
var vm = new Vue({
el:'#app',
data:{
},
methods:{
}
})
</script>
</body>
</html>
inserted是钩子函数,当dom绑定的时候使用运行
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<input type="text" v-colors="msg">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
//自定义指令带参数
Vue.directive('colors',{
bind:function (el,bind){
el.style.backgroundColor = bind.value.color;
//通过携带参数来控制指令的一些具体行为
}
});
var vm = new Vue({
el:'#app',
data:{
msg:{
color:'orange'
}
},
methods:{
}
})
</script>
</body>
</html>
局部指令
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<input type="text" v-colors="msg">
<input type="text" v-focus>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
//自定义指令带参数
var vm = new Vue({
el:'#app',
data:{
msg:{
color:'orange'
}
},
methods:{
},
directives:{
colors:{
bind:function (el,bind){
el.style.backgroundColor = bind.value.color;
//通过携带参数来控制指令的一些具体行为
}
},
focus:{
inserted:function (el){
el.focus();
}
}
}
})
</script>
</body>
</html>
局部指令应用范围是有所限制的,全局指令是没有限制的
计算属性computed
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<div>{{reversString}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'Hello '
},
methods:{
},
//计算属性,让模板变得更加简单
computed:{
reversString:function (){
return this.msg.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
计算属性computed和methods方法存在什么差异
**
缓存特性在比较耗时的计算节省性能,计算属性他是基于依赖来做缓存的,当发布存在缓存机制。
计算属性依赖:data
侦听器
数据变化时异步或者开销比较大
侦听器用法
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div>
<span>名</span>
<span>
<input type="text" v-model="firstName">
</span>
</div>
<div>
<span>名</span>
<input type="text" v-model="lastName">
</div>
<div>{{msg}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
firstName:'Jim',
lastName:'Green',
msg:''
},
watch:{
firstName: function (val){
this.msg = val + '' + this.lastName;
},
lastName: function (val){
this.msg = this.firstName + '' + val;
}
}
})
</script>
</body>
</html>
监听器属性的方法必须和数据里面的方法名称一致,这样的监听才可以实现
监听器应用场景
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div>
<span>用户名:</span>
<span>
<input type="text" v-model.lazy="uname">
</span>
<span>{{tip}}</span>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//1.采用监听器用户名称变化
//2.调用后台接口验证
//3.根据验证结果调整提示信息
var vm = new Vue({
el:'#app',
data:{
uname:'',
tip:''
},
methods:{
checkName:function (uname){
//调用接口,但是可以使用定时任务方式模拟接口调用
var that = this;
setTimeout(function (){
if (uname == 'admin'){
that.tip = '用户名存在请更换一个';
}else{
that.tip = '用户名可以使用';
}
},2000)
}
},
watch:{
uname:function (val){
//调用后台接口验证用户名合法性
this.checkName(val);
//修改提示信息
this.tip = '正在验证。。。';
}
},
})
</script>
</body>
</html>
过滤器
作用:格式化数据,比如将字符串格式化到首字母大写,将日期格式化为指定的格式等。
自定义过滤器
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<div>{{ msg | upper}}</div>
<div>{{msg | upper | lower}}</div>
<div :abc="msg| upper">测试数据</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//过滤器
// Vue.filter('upper',function (val){
// return val.charAt(0).toUpperCase()+val.slice(1);
// });
// Vue.filter('lower',function (val){
// return val.charAt(0).toLowerCase()+val.slice(1);
// });
var vm = new Vue({
el:'#app',
data:{
msg:''
},
filters:{
upper: function (val){
return val.charAt(0).toUpperCase()+val.slice(1);
}
}
});
</script>
</body>
</html>
带参数的过滤器
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="app">
<div>{{date | format('yyyy-MM-dd')}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//过滤器
Vue.filter('format',function (val,arg){
if (arg == 'yyyy-MM-dd'){
var ret = '';
ret += val.getFullYear()+'-'+(val.getMonth()+1) + '-' + val.getDate();
console.log(ret)
return ret;
}
console.log(1)
})
var vm = new Vue({
el:'#app',
data:{
date:new Date()
},
});
</script>
</body>
</html>
生命周器
主要阶段
- 挂载(初始化相关属性)
- beforeCreate
- created
- beforeMount
- mounted
- 更新(元素或组线的变更操作)
- beforeUpdate
- updated
- 销毁(销毁相关属性)
- beforeDestroy
- destroyed
Vue实例产生会经过8个生命周期
Vue中对于数组的新概念
变异方法(修改原始数据)
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
替换数组(形成新的数组)
- filter()
- concat()
- slice()
变异方法都会影响到数组的原始数据,替换方法不会影响到数组的原始数据他会形成一个新的数组。
修改响应式数据
- Vue.set(vm.items,indexOfltem,newValue)
- vm.$set(vm.items,indexOfItem,newValue)
1.参数一表示要处理的数组名称
2.参数2表示要处理的数组索引
3.参数3表示要处理的数组的值