vue2 官方文档地址--介绍 — Vue.js (vuejs.org)
开发在浏览器调试,浏览器界面很不友好,下载一个google浏览器插件,优化调试界面,通过点击下面的链接跳转,可以直接在对应的浏览器插件扩展管理安装,安装后记得启用插件,调试的时候会用到本地文件,要在插件管理里面开启允许访问文件URL
不同给浏览器得插件设置可以参考不同浏览器插件设置
也可以在git自己下载编译
使用效果如下
新建目录,执行 npm init -y
执行 npm install vue@2.7.14
安装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>
{{userName}},你好
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
userName: 'wenyoulong'
}
})
</script>
</body>
</html>
Vue采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,如上面实例中的 {{userName}}
{{ }}
符号内,可以访问VUE实例中定义的变量,函数,并且可以访问js内置的方法函数,也可以进行四则运算,且只能放在html标签体内使用
{{ }}
在页面刷新时,会先显示表达式内容,页面加载完成后,才会变更为对应的正确数据,可以通过 v-html
或者 v-text
处理,v-html会将字符串作为html代码输出,v-text会将字符串直接输出
<body>
<div id="app">
<h1>
{{userName}},你好
<span v-html="htmlCode"></span>
<span v-text="htmlCode"></span>
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
userName: 'wenyoulong',
htmlCode: '<h1>Happy</h1>'
}
})
</script>
</body>
</html>
运行结果
v-model用于处理表单输入和应用状态之间的双向绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input v-model="message"/>
<h1>
{{userName}},你好,{{message}}
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
userName: 'wenyoulong',
message: ''
}
})
</script>
</body>
</html>
界面如图
v-on指令可以在指定元素上添加一个事件监视器,可以使用@作为缩写,用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件
如下代码使用v-on指令添加一个点击事件监视器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button v-on:click="changeUserName">戳我一下</button>
<h1>
{{userName}},你好
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
userName: 'wenyoulong'
},
methods:{
changeUserName: function(){
this.userName = 'huanhuan'
}
}
})
</script>
</body>
</html>
点击后数据变为
例如下述代码夏至只能点击一次
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click.once="onceClick">只能点一次</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
},
methods:{
onceClick:function () {
console.log('点一次')
}
}
})
</script>
</body>
</html>
调用结果如下
{{ }}
只能在元素标签体内使用,如果我们时要对HTML标签的某一个属性值做动态绑定,就需要使用v-bind实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h1>
<a v-bind:href="baidu" target="_blank">百度一下</a><br>
<a v-bind:href="myPage" target="_blank">Happy&Long</a>
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
baidu: 'http://www.baidu.com',
myPage: 'http://www.wenyoulong.com'
}
})
</script>
</body>
</html>
v-for可用于遍历数据、也可用于遍历组件
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(user, index) in users">
{{ user.userName }} - {{ index }} - {{ user.age }}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
users:[
{userName:'long',age:'1'},
{userName:'huan',age:'1'},
]
},
methods:{
}
})
</script>
</body>
</html>
结果如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(value, name) in lover">
{{ name }} - {{ value }}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
lover:{
name:'huan',
age: '1',
address: '四川'
}
},
methods:{
}
})
</script>
</body>
</html>
结果
代码中判断数组内数据,对2求余
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="n in evenNumbers">{{ n }}</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
numbers:[1,2,3,4,5]
},
computed:{
evenNumbers:function(){
return this.numbers.filter(number => {
return number % 2 === 0
})
}
}
})
</script>
</body>
</html>
输出结果
这里先说明两个元素的区别,v-show和v-if得区别就是,v-show控制的元素,会一直在dom中,通过切换display属性来控制元素的显示与否,v-if在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,v-if为false时,控制的元素会从dom中删除,为true时则重新加载。
v-show元素总会被渲染,初始化开销高;
v-if元素第一次条件为真才会渲染,切换开销高;
若元素经常被使用,则使用v-show,否则使用v-if。
使用方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click="showInput">点击我</button><br/>
<input placeholder="测试v-if" v-if="inputLoad"/><br/>
<input placeholder="测试v-show" v-show="inputDisplay"/><br/>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
inputLoad:false,
inputDisplay:false
},
methods:{
showInput:function (){
this.inputLoad = !this.inputLoad;
this.inputDisplay = !this.inputDisplay;
}
}
})
</script>
</body>
</html>
点击前dom元素如下,可以清晰看到,v-show控制的input已经加载到页面dom中,而v-if得则没有点击后两个都会显示
点击结果
此时如果在更改两个状态为false,则v-if控制的元素会从dom中删除,而v-show得则会将display改为false隐藏元素。
vue通过复用元素来尽可能得高效渲染元素
如下述代码中,切换v-if,文本框内的数据不会变动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click="changeLoginType">切换登录</button><br/>
<template v-if="loginType === 'username'">
<label>用户名</label>
<input placeholder="输入用户名">
</template>
<template v-else>
<label>密码</label>
<input placeholder="输入密码">
</template>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
loginType:'username'
},
methods:{
changeLoginType:function (){
if(this.loginType === 'username'){
this.loginType = ''
}else{
this.loginType = 'username'
}
}
}
})
</script>
</body>
</html>
在用户名输入框中输入一个值
点击切换登录发现输入的内容还在
这是因为这两个模板使用了相同的元素,input不会被替换,只是替换了placeholder
我们可以给两个input加上key来告诉vue这两个input不要复用,这样的话,每次切换,输入框都会重新加载渲染
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click="changeLoginType">切换登录</button><br/>
<template v-if="loginType === 'username'">
<label>用户名</label>
<input placeholder="输入用户名" key="name-input">
</template>
<template v-else>
<label>邮箱</label>
<input placeholder="输入邮箱" key="email-input">
</template>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
loginType:'username'
},
methods:{
changeLoginType:function (){
if(this.loginType === 'username'){
this.loginType = ''
}else{
this.loginType = 'username'
}
}
}
})
</script>
</body>
</html>
基础示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
{{reverseMessage}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
message:'WenYL Huan'
},
computed:{
reverseMessage:function (){
return this.message.split(' ').reverse().join(' ')
}
}
})
</script>
</body>
</html>
运行结果
上面例子中得代码通用可用以下代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
{{reverseMessage()}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
message:'WenYL Huan'
},
methods:{
reverseMessage:function (){
return this.message.split(' ').reverse().join(' ')
}
}
})
</script>
</body>
</html>
区别:
使用computed,是由当我们的message发生变化才会重新计算,否则都是返回之前计算好的值
使用watch同样可以实现属性值的侦听,下述代码使用watch侦听两个属性的值,若值发生变化,则执行对应的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
英语成绩<input type="number" min="0" v-model="englishScore" /> <br>
数学成绩<input type="number" min="0" v-model="mathScore" /> <br>
总成绩--{{totalScore}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
mathScore: 0,
englishScore: 0,
totalScore: 0
},
watch:{
mathScore:function (newValue,oldValue){
this.totalScore = parseFloat(newValue) + parseFloat(this.englishScore)
},
englishScore:function (newValue,oldValue){
this.totalScore = parseFloat(newValue) + parseFloat(this.mathScore)
}
}
})
</script>
</body>
</html>
同样的操作,使用computed用下面的代码即可实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
英语成绩<input type="number" min="0" v-model="englishScore" /> <br>
数学成绩<input type="number" min="0" v-model="mathScore" /> <br>
总成绩--{{computedTotalScore}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
mathScore: 0,
englishScore: 0
},
computed:{
computedTotalScore:function (){
return parseFloat(this.mathScore) + parseFloat(this.englishScore)
},
}
})
</script>
</body>
</html>
二者的区别
如果我们只是计算结果,使用computed,如果出了要计算结果还要执行一系列的方法,则使用watch
计算属性默认提供了get,我们也可以自己实现set,代码示例如下,当我们直接设置计算属性,就会调用对应的set方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
{{computedTotalScore}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
mathScore: 0,
englishScore: 0,
totalScore: ''
},
mounted() {
this.computedTotalScore = "100 100"
},
computed:{
computedTotalScore:{
get: function (){
return parseFloat(this.mathScore) + parseFloat(this.englishScore)
},
set: function (newValue){
console.log(newValue)
var scores = newValue.split(" ")
this.mathScore = parseFloat(scores[0])
this.englishScore = parseFloat(scores[1])
}
}
}
})
</script>
</body>
</html>
组件命名规则有两种
全局组件使用 Vue.component
注册,代码示例如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<click-count></click-count>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
Vue.component('click-count',{
template:'<button v-on:click="count++">点击了{{count}}次</button>',
data(){
return{
count:0
}
}
});
let vm = new Vue({
el:"#app",
data:{
},
})
</script>
</body>
</html>
局部组件通过components属性配置,代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<click-count></click-count>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
const countComponent = {
template:'<button v-on:click="count++">点击了{{count}}次</button>',
data(){
return{
count:0
}
}
}
let vm = new Vue({
el:"#app",
components: {
'click-count' : countComponent
},
data:{
},
})
</script>
</body>
</html>