Vue基础
Vue:渐进式JavaScript框架
声明式渲染->组件系统->客户端路由->集中式状态管理->项目构建
Vue的基本使用
vue的基本使用步骤:
1.需要提供标签用于填充数据
2.引入vue.js库文件
3.可以使用vue的语法完成功能
4.把vue提供的数据填充到标签里面
效果如下:
<body>
<div id="msg"></div>
<div id="msg2"></div>
<div id="app">
<div>{{msg3}}</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script>
//原生js实现hello world
var msg = "hello world";
var div = document.getElementById('msg');
div.innerHTML = msg
//jQuery实现hello world
$('#msg2').html(msg)
//Vue实现hello world
/*
vue的基本使用步骤
1.需要提供标签用于填充数据
2.引入vue.js库文件
3.可以使用vue的语法完成功能
4.把vue提供的数据填充到标签里面
*/
var vm = new Vue({
el:"#app",
data:{
msg3:"hello vue"
}
})
</script>
-
参数分析
- el:元素的挂载位置(值可以是css选择器或者DOM元素)
- data:模型数据(值是一个对象)
-
插值表达式用法
<div>{{msg3}}</div>
-
将数据填充到HTML标签中
-
插值表达式支持基本的计算操作
例如:
<div>{{1+2}}</div>
-
Vue模板语法
把数据填充到HTML标签中,即前端渲染
前端渲染方式:
- 原生js拼接字符串
- 使用前端模板引擎
- 使用vue特有的模板引擎
模板语法概述:
- 插值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
指令
指令的本质就是自定义属性,以v-开始
指令用于在表达式的值改变时,将某些行为应用到 DOM 上
v-cloak
上述例子中用插值表达式来渲染数据来实现hello world,但是当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak
指令来解决这一问题。
通过 v-cloak
指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除。
html:style+body
<style>
[v-cloak]{
display: none;
}
</style>
<body>
<div id="app">
<div v-cloak>{{msg}}</div>
</div>
</body>
js:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
/*
*/
var vm = new Vue({
el:"#app",
data:({
msg:'hello world'
})
})
</script>
数据绑定指令
-
v-text:填充纯文本
-
相比插值表达式更加简洁
<div id="app"> <div v-text = "msg"></div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var vm = new Vue({ el:"#app", data:({ msg:'hello world' }) }) </script>
-
-
v-html:填充html片段
-
存在安全问题
-
本网站内部数据可用,来自第三方的数据不可以
<div id="app"> <div v-html = "msg1"></div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var vm = new Vue({ el:"#app", data:({ msg:'hello world', msg1:"<h1>我是h1</h1>" }) }) </script>
-
-
v-pre:填充原始信息
-
显示原始信息,填过编译过程
<div id="app"> <div v-pre>{{msg}}</div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var vm = new Vue({ el:"#app", data:({ msg:'hello world', msg1:"<h1>我是h1</h1>" }) }) </script>
-
数据响应式
数据的变化会导致页面内容的变化
v-once
这个指令不需要任何表达式,它的作用就是定义它的元素或组件只会渲染一次,不再随着数据的改变而重新渲染
<body>
<div id="app">
<div>{{msg}}</div>
<div v-once>{{msg}}</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
msg:'hello world',
})
})
</script>
这里第一个div没有设置v-once
,所以在控制台修改了msg的值,自身直接被渲染;而第二个msg设置了v-once
只会被渲染一次
双向数据绑定
通过v-model来实现页面和数据的双向数据绑定
<body>
<div id="app">
<div>{{msg}}</div>
<input type="text" v-model = "msg">
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
msg:'hello world',
})
})
</script>
当input输入时,会影响后面数据的值,然后这个值又因为响应式的原因渲染到第一个div上
事件
事件基本使用
可以用 v-on
指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码
<button v-on:click="num += 1">Add 1</button>
v-on
的简写形式
<button @click="num += 1">Add 1</button>
<body>
<div id="app">
<div>{{msg}}</div>
<button v-on:click="num++">点我点我</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
msg:'hello world',
num:0
})
})
</script>
效果如下:
还可以直接使用事件函数的调用方式:
-
直接绑定函数名称
<button v-on:click="sayMe">hello</button>
-
调用函数
<button v-on:click="sayMe()">hello</button>
<body>
<div id="app">
<div>{{msg}}</div>
<button v-on:click="num++">点我点我</button>
<button v-on:click="sayMe">hello</button>
<button v-on:click="sayMe()">hello</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
msg:'hello world',
num:0
}),
methods:{
sayMe:function(){
console.log("小明");
}
}
})
</script>
效果如下:
注意vm对象的属性名别写错,我把methods写成了method就一直错
事件参数传递
如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数;如果事件绑定函数调用,那么事件对象必须作为最后一个参数显式传递,并且作为事件队形名称必须是$event
<body>
<div id="app">
<button v-on:click="num++">点我点我</button>
<button v-on:click="fn2">hello</button>
<button v-on:click="fn1(123)">hello</button>
<button v-on:click="fn2($event)">hello</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
msg:'hello world',
num:0
}),
methods:{
fn1:function(p){
console.log(p);
},
fn2:function(event){
console.log(event.target.tagName);
}
}
})
</script>
效果如下:
事件修饰符
Vue.js 为 v-on
提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。
- .stop
- .prevent
- .capture
- .self
- .once
- .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用
v-on:click.prevent.self
会阻止所有的点击,而v-on:click.self.prevent
只会阻止对元素自身的点击。
按键修饰符
还提供了针对键盘的按键修饰符
-
.enter 回车键
<input type="text" v-on:keyup.enter="fn" v-model = 'pwd'>
-
.delete 删除键
<input type="text" v-on:keyup.delete='clear' v-model = 'name'>
整体效果如下:
<body>
<div id="app">
<input type="text" v-on:keyup.delete='clear' v-model = 'name'>
<input type="text" v-on:keyup.enter="fn" v-model = 'pwd'>
<input type="button" v-on:click='fn' value="提交">
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
name:"",
pwd:""
}),
methods:{
fn:function(){
console.log(this.name,this.pwd);
},
clear:function(){
this.name = ""
}
}
})
</script>
当在用户名框内按删除键时,会触发clear函数,会清空用户名内的内容
当在密码框内按回车键时,会触发fn函数,会打印用户名和密码,因为输入的数据和后面设置的用户名和密码进行了双向数据绑定
自定义按键修饰符
每一个键盘都有一个对应值,可以通过config.keyCodes对象
来获取到
如下:
<body>
<div id="app">
<input type="text" v-on:keyup='fn' v-model = 'info'>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
info:""
}),
methods:{
fn:function(){
console.log(event.keyCode);
}
}
})
</script>
可以利用这个特性来自定义按键修饰符,或者直接定义:
<input type="text" v-on:keyup.65='fn' v-model = 'info'>
属性绑定
我们可以通过v-bind
动态地绑定一个或多个属性
<a v-bind:href="url">百度一下</a>
还有更简单的简写:通过一个:
简写
<a :href="url">百度一下</a>
整体效果如下:
<body>
<div id="app">
<input type="text" v-model = "url" value="输入网址">
<a v-bind:href="url">百度一下</a>
<a :href="url">百度一下</a>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
url:"https://www.baidu.com/"
}),
methods:{
}
})
</script>
v-model的底层实现原理分析
<input v-bind:value="msg" v-on:input='msg=$event.target.value'>
一边通过v-bind
来绑定给input属性,让msg绑定给input的value属性;一边通过v-on
来绑定给input事件,来通过event对象
实时的把输入的值修改给msg,这样形成双向绑定
效果如下:
<body>
<div id="app">
<input v-bind:value="msg" v-on:input='fn'>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:({
msg:'hello'
}),
methods:{
fn:function(event){
this.msg = event.target.value
}
}
})
</script>
样式绑定
class样式处理
- 对象语法
只要是通过v-bind
的方式来修改class属性
<body>
<div id="app">
<div class="active"></div>
<div v-bind:class="{active:isActive,error:isError}"></div>
<button v-on:click='fn'>切换</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:({
isActive:true,
isError:true
}),
methods:{
fn:function(){
//控制isActive的值在true和false直接切换
this.isActive = !this.isActive
this.isError = !isError
}
}
})
</script>
- 数组语法
<body>
<div id="app">
<div v-bind:class='[activeClass,errorClass]'>测试样式</div>
<button v-on:click='fn'>切换</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:({
activeClass:"active",
errorClass:"error"
}),
methods:{
fn:function(){
//控制isActive的值在true和false直接切换
this.activeClass = ""
}
}
})
</script>
style样式处理
- 对象语法
- 数组语法
<body>
<div id="app">
<div v-bind:style='{border:borderStyle,width:widthStyle,height:heightStyle}'>测试样式</div>
<div v-bind:style="objStyles"></div>
<button v-on:click='fn'>切换</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: ({
borderStyle: "1px solid blue",
widthStyle: "100px",
heightStyle: "200px",
objStyles: {
border: "1px solid red",
width: "500px",
height: "500px"
}
}),
methods: {
fn: function () {
this.widthStyle = "300px"
this.objStyles.width = "40px"
}
}
})
</script>
分支循环结构
分支结构
v-if
指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
- v-if
- v-else
- v-else-if
- v-show
效果如下:
<body>
<div id="app">
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else-if='score<80&&score>60'>一般</div>
<div v-else>比较差</div>
<div v-show="falg">测试v-show</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: ({
score: 61,
flag: false
}),
methods: {
}
})
</script>
v-if一组指令用于根据条件渲染数据,不符合的不渲染
v-show指令用于渲染数据根据条件具体显示不显示,带有 v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS property display
。
循环结构
我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<body>
<div id="app">
<div>列表</div>
<ul>
<li v-for='i in num'>{{i}}</li>
<li v-for='(i,index) in num'>{{i+'---'+index}}</li>
</ul>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: ({
num: [1, 2, 3, 4, 5, 6, 7, 8, 9]
}),
methods: {
}
})
</script>