大家好,又见面了,我是你们的朋友全栈君。
1. vue简介
1.1 vue是什么
Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
1.2 vue的特点
1) 遵循 MVVM 模式
2) 编码简洁, 体积小, 运行效率高, 适合移动/PC 端开发
3) 它本身只关注 UI, 可以轻松引入 vue 插件或其它第三库开发项目
1.3 与其它前端js框架的关联
1) 借鉴 angular 的模板和数据绑定技术
2) 借鉴 react 的组件化和虚拟 DOM 技术
1.4 vue拓展插件
-
vue-cli: vue 脚手架
-
vue-resource(axios): ajax 请求
-
vue-router: 路由
-
vuex: 状态管理
-
vue-lazyload: 图片懒加载
-
vue-scroller: 页面滑动相关
-
mint-ui: 基于 vue 的 UI 组件库(移动端)
-
element-ui: 基于 vue 的 UI 组件库(PC 端)
2. 基本使用
2.1 hello world
<body>
<!--
1. 引入Vue.js
2. 创建Vue对象
el : 指定根element(选择器)
data : 初始化数据(页面可以访问)
3. 双向数据绑定 : v-model
4. 显示数据 : {
{xxx}}
-->
<!--模板-->
<div id="test">
<input type="text" v-model="msg"><br><!--指令-->
<input type="text" v-model="msg"><!--指令-->
<p>hello {
{msg}}</p><!--大括号表达式-->
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({ // 配置对象 options
// 配置选项(option)
el: '#test', // element: 指定用vue来管理页面中的哪个标签区域
data: {
msg: 'world'
}
})
</script>
</body>
2.2 调试工具
在Chrome或Firefox浏览器的扩展插件仓库里搜vue devtool,安装Vue.js devtools.
打开vue项目,在控制台选择vue,操作组件查看信息变化。
2.3 vue的MVVM
MVVM分为三个部分:分别是M(Model,模型层 ),V(View,视图层),VM(ViewModel,V与M连接的桥梁,也可以看作为控制器) 1、 M:模型层,主要负责业务数据相关; 2、 V:视图层,顾名思义,负责视图相关,细分下来就是html+css层; 3、 VM:V与M沟通的桥梁,负责监听M或者V的修改,是实现MVVM双向绑定的要点;
MVVM支持双向绑定,意思就是当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改,反之修改V层则会通知M层数据进行修改,以此也实现了视图与模型层的相互解耦。
3. 模块语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 HTML 解析器解析。
双大括号表达式
语法: {
{exp}}
功能: 向页面输出数据 ,可以调用对象的方法
指令一:强制数据绑定
功能: 指定变化的属性值
完整写法: v-bind:xxx=’yyy’ //yyy 会作为表达式解析执行
简洁写法: :xxx=’yyy’
指令二:绑定事件监听
1) 功能: 绑定指定事件名的回调函数
完整写法 | 整洁写法 |
---|---|
v-on:keyup=’xxx’ | @keyup=’xxx’ |
v-on:keyup.enter=’xxx’ | @keyup.enter=’xxx’ |
案例演示
<div id="app">
<h2>1. 双大括号表达式</h2>
<p>{
{content}}</p>
<p>{
{content.toUpperCase()}}</p>
<h2>2. 指令一: 强制数据绑定</h2>
<a v-bind:href="url">访问指定站点1</a><br>
<a :href="url">访问指定站点2</a><br>
<h2>3. 指令二: 绑定事件监听</h2>
<button v-on:click="test">点我</button>
<button @click="test2('詹姆斯')">点我</button>
<!--<button @click="test2(content)">点我</button>-->
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
content: 'NBA I Love This Game',
url: 'http://www.baidu.com'
},
methods: {
test () {
alert('湖人总冠军!')
},
test2 (content) {
alert('你好,'+content);
}
}
})
</script>
效果如下:
点击链接都能跳转,点击按钮都能触发alert事件。
4.计算属性和监听属性
4.1 计算属性computed
在vue应用中,在模板中双向绑定一些数据或者表达式,但是表达式如果过长,或者逻辑更为复杂时,就会变得臃肿甚至难以维护和阅读。所以在遇到复杂的逻辑时应该使用计算属性。
-
computed计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量改变时,计算属性也会跟着改变;
-
computed根据一个现有数据去生成一个新数据,并且这两个数据会永久的建立关系,还会建立缓存,当无关数据改变的时候,不会重新计算而是直接使用缓存中的值;
-
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。
<div id="app">
<p>原始字符串: {
{ message }}</p>
<p>计算后反转字符串: {
{ reversedMessage }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Runoob!'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
},
methods: {
reversedMessage2: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
4.2 监听属性watch
1) 通过 vm 对象的$watch()或 watch 配置来监视指定的属性
2) 当属性变化时, 回调函数自动调用, 在函数内部进行计算
<div id="demo">
姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
姓名(单向): <input type="text" placeholder="Full Name" v-model="fullName"><br>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({
el: '#demo',
data: {
firstName: 'A',
lastName: 'B',
fullName: 'A-B'
},
watch: {
// 配置监视firstName
firstName: function (value) { // 相当于属性的set
console.log('watch firstName', value);
// 更新fullName2 this相当于vm对象
this.fullName = value + '-' + this.lastName
}
}
});
// 监视lastName
vm.$watch('lastName', function (value) {
console.log('$watch lastName', value);
// 更新fullName2
this.fullName = this.firstName + '-' + value
})
</script>
我们有这样一个功能,我们可以输入姓和名,然后另一个输入框要实时拼接姓和名。我们可以用watch机制来实现。
我们监视姓和名两个变量,每次有改变,则自动触发watch对应的方法,执行逻辑。
4.3 computed setter
computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
<div id="demo">
姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
姓名(双向): <input type="text" placeholder="Full Name3" v-model="fullName"><br>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
const vm = new Vue({
el: '#demo',
data: {
firstName: 'A',
lastName: 'B'
},
// 计算属性配置: 值为对象
computed: {
fullName: {
// 当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
get() {
console.log('fullName3 get()')
return this.firstName + '-' + this.lastName
},
// 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
set(value) {
console.log('fullName3 set()', value)
// 更新firstName和lastName
const names = value.split('-')
this.firstName = names[0];
this.lastName = names[1];
}
}
}
})
</script>
效果如下:
5.样式绑定
class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。
5.1 class
class属性绑定有三种情况:
<p :class="myClass">xxx是字符串</p>
<p :class="{classA: hasClassA, classB: hasClassB}">xxx是对象</p>
<p :class="['classA', 'classB']">xxx是数组</p>
<!--点击更新按钮 第二个p标签会实现classA和classB样式的来回切换 -->
<button @click="update">更新</button>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
myClass: 'classA',
hasClassA: true,
hasClassB: false,
activeColor: 'red',
fontSize: '20px'
},
methods: {
update () {
this.hasClassA = !this.hasClassA;
this.hasClassB = !this.hasClassB;
}
}
})
</script>
5.2 内联样式
我们可以在 v-bind:style 直接设置样式:
<div id="app">
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">湖人总冠军</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
activeColor: 'green',
fontSize: 30
}
})
<script type="text/javascript">
以上实例div为:
<div style="color: green; font-size: 30px;">湖人总冠军</div>
也可以直接绑定到一个样式对象,让模板更清晰:
<div id="app">
<div v-bind:style="styleObject">湖人总冠军</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
styleObject: {
color: 'green',
fontSize: '30px'
}
}
})
<script type="text/javascript">
v-bind:style 可以使用数组将多个样式对象应用到一个元素上:
<div id="app">
<div v-bind:style="[baseStyles, overridingStyles]">湖人总冠军</div>
</div>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
baseStyles: {
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight': 'bold'
}
}
})
<script type="text/javascript">
6. v-if和v-show
相同点:v-if与v-show都可以动态控制dom元素显示隐藏
不同点:v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css–display:none,dom元素还在。
如果需要频繁切换使用 v-show 较好
<div id="demo">
<p v-if="ok">表白成功</p>
<p v-else>表白失败</p>
<hr>
<p v-show="ok">求婚成功</p>
<p v-show="!ok">求婚失败</p>
<button @click="ok=!ok">切换</button>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
ok: true,
}
})
</script>
页面渲染如下:
我们也可以用v-else-if进行链式调用
<div id="app">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
type: 'C'
}
})
</script>
7. 列表渲染
7.1 列表展示
我们可以用 v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<ul id="example-1">
<li v-for="item in items" :key="item.message">
{
{ item.message }}
</li>
</ul>
<script>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
</script>
在 v-for
块中,我们可以访问所有父作用域的 property。v-for
还支持一个可选的第二个参数,即当前项的索引。
<ul>
<li v-for="(p, index) in persons" :key="index">
{
{index}}--{
{p.name}}--{
{p.age}}
</li>
</ul>
<script>
new Vue({
el: '#demo',
data: {
persons: [
{name: 'Tom', age:18},
{name: 'Jack', age:17},
{name: 'Bob', age:19},
{name: 'Mary', age:16}
]
}
</script>
你也可以用 of
替代 in
作为分隔符,因为它更接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
7.2 列表更新和删除
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:
-
push()
-
pop()
-
shift()
-
unshift()
-
splice()
-
sort()
-
reverse()
下面基于上面的代码演示一下:
<button @click="deleteP(index)">删除</button>
<button @click="updateP(index, {name:'Cat', age: 16})">更新</button>
methods: {
deleteP (index) {
this.persons.splice(index, 1)
// 调用的不是原生数组的splice(), 而是一个变异(重写)方法
// 1. 调用原生的数组的对应方法
// 2. 更新界面
},
updateP (index, newP) {
console.log('updateP', index, newP)
this.persons.splice(index, 1, newP)
},
addP (newP) {
this.persons.push(newP)
}
}
7.3 显示过滤/排序后的结果
有时,我们想要显示一个数组经过过滤排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。
我们实现一个案例:展示姓名和年龄的数组列表。同时可以按照姓名筛选和年龄排序。
<div id="demo">
姓名:<input type="text" v-model="searchName">
<ul>
<li v-for="(p, index) in filterPersons" :key="index">
{
{index}}--{
{p.name}}--{
{p.age}}
</li>
</ul>
<div>
<button @click="setOrderType(2)">年龄升序</button>
<button @click="setOrderType(1)">年龄降序</button>
<button @click="setOrderType(0)">原本顺序</button>
</div>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
searchName: '',
orderType: 0, // 0代表不排序, 1代表降序, 2代表升序
persons: [
{name: 'Tom', age:18},
{name: 'Jack', age:17},
{name: 'Bob', age:19},
{name: 'Mary', age:16},
{name: 'Tim', age:16},
]
},
computed: {
filterPersons () {
// 取出相关数据
const {searchName, persons, orderType} = this;
let arr = [...persons];
// 过滤数组
if(searchName.trim()) {
arr = persons.filter(p => p.name.indexOf(searchName)!==-1)
}
// 排序
if(orderType) {
arr.sort(function (p1, p2) {
if(orderType===1) { // 降序
return p2.age-p1.age
} else { // 升序
return p1.age-p2.age
}
})
}
return arr
}
},
methods: {
setOrderType (orderType) {
this.orderType = orderType
}
}
})
</script>
效果图如下:
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/136043.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...