vuejs2
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
sublime text3 安装vue插件
支持VueJS语法高亮显示插件vue syntax hightlight
https://github.com/henjue/vue-for-idea.git
https://github.com/postalservice14/vuejs-plugin
1.0 html文件中引入vue
*.html文件中引入vue:
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者:
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
2.0 声明式渲染和vue命令
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
Hello Vue!
我们已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。我们要怎么确认呢?打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 app.message
的值,你将看到上例相应地更新。
bind/baɪnd/捆绑
v-bind
特性被称为指令。指令带有前缀v-
,以表示它们是 Vue 提供的特殊特性。
vue命令格式:v-“命令名” = ‘命令值’,v-once数据被赋值后无论绑定的数据被如何修改都不会引起该绑定元素的更新
2.1 文本插值使用双大括号语法 {{js表达式}}
-
在vue示例绑定的DOM中,可以使用双大括号语法进行文本插值
-
双大括号{{}}语法内部可以使用js表达式:变量、三元运算符、基本运算
-
双大括号语法,将插值内容自动转化为文本节点,避免XSS攻击
<div id=app>
声明式渲染
<h2 v-once>title{{title}}</h2><!--虎扑体育-->
<div>title{{title}}</div><!--title虎扑体育-->
<p>{{msg}} msg: vue.data.msg</p><!--hello world msg: vue.data.msg-->
<p>三元运算符:{{num > 6 ? '大' : '小'}}</p><!--三元运算符:小-->
<p>运算:{{num + 15}}</p><!--运算:21-->
<pre>
{{htmlStr}}<!-- <div>hello world</div>-->
</pre>
2.2 属性插值 v-bind:属性名=“js表达式”
处理用户输入
<input v-bind:placeholder="holderStr">
<input v-bind:placeholder="usepsd? '请输入密码':'请输入用户名'">
</div>
{{msg}}在#app外使用无效
2.3 实例化vue 绑定页面元素
var vm = new Vue({
el: '#app',// css选择器 绑定页面中的元素,该元素就会被转化为Vue根示例,在该DOM中可以使用Vue示例的方法属性语法等
data: {
// data 是vue中用来存放数据的配置选项,data必须是一个纯对象其中包含一个或多个键值对
// Vue 将会递归将 data 的属性转换为 getter/setter (当属性发生改变时响应式的更新页面ui)
// 通过vue示例对象 vm.$data 获取到其中的数据
msg: 'hello world',
num: 6,
title: '虎扑体育',
htmlStr: '<div>hello world</div>',
holderStr: "测试属性插值",
usepsd: true
}
})
// document.body.innerHTML += '<h1>hello world</h1>'
console.log(vm.$data, vm.msg)// 'hello world'
v-bind:属性名
可以缩写为:属性名
<span :class="className">v-bind</span>
2.4 v-html属性将原生html节点插入页面中
该方法会引起xss攻击,所以要注意不要将该方法暴露给用户(v-html自带v-bind)
<p v-html="htmlstr"></p><!--使用v-html-->
2.5 双向绑定 v-model=“vue中属性”
实现数据双向改变
该方法只适用于表单元素,首先通过v-bind将对应的data与input的value进行绑定
,给input添加修改事件当value发生改变时修改vue的对应data数据
<input v-model="value">{{value}}
var vm = new Vue({
el: "#app",
data: {
htmlstr: '<span style="color:red">使用v-html</span>',
className: 'demo',
value: 'hello'
}
})
4.0 computed计算属性和Watch观察者
例子: 如果页面中需要一些对vue示例data进行某种操作的数据,可以通过js表达式对data进行处理
但是如果页面中多处地方都需要该操作或者数据处理过于复杂,写在文本或属性插值中会让代码变得繁杂
下面例子中 h2 p div 等标签需要同样的操作,我们发现我们在项目中创建了多个重复的代码,vue为我们提供
了两种解决方法
方法一 计算属性 computed
方法二 观察者 watch
解决重复多余的代码变得简单
4.1计算属性computed
computed /kəm’pju:tid/计算
reverse/rɪ’vɜːs/相反的
join/dʒɒɪn/连接
<div id="app">
实现反转字符串:
<input v-model=str>
<h2>{{str.split('').reverse().join('')}}</h2>
<h3>{{str.split('').reverse().join('')}}</h3>
<h4>{{str.split('').reverse().join('')}}</h4>
<h5>计算属性:{{reverseStr}}</h5>
<h6>计算属性:{{reverseStr}}</h6>
</div>
var vm = new Vue({
el: '#app',//绑定页面元素
data: {
str: 'hello world'
},
computed: {
// 计算属性是Vue配置选项computed中定义的必须带return值的函数,
// 函数名就是计算属性名,使用时与普通属性相同
// 字符串反转的计算属性
reverseStr() {
// 在当前计算属性中用到的data或者其他计算属性,会被作为依赖,计算属性会监听这些依赖
// 当依赖改变时,计算属性会重新计算
return this.str.split('').reverse().join('')
}
}
})
4.1.1 案例:外卖10元起送显示高亮
还剩10元显示灰色,满10元或大于10元立即购买
pay/peɪ/付款
enough/ɪ’nʌf/足够price /praɪs/价格
样式
.pay {
width: 100px;
text-align: center;
height: 40px;
line-height: 40px;
background-color: #ccc;
color: #fff;
}
.enough {
background-color: #38a6ff;
color: #fff;
}
结构
<div id='price'>
<input type="number" min="0" v-model="totalPrice">
总价:{{totalPrice}}
<div :class="payClass">{{payDesc}}</div>
</div>
实例化vue
new Vue({
el: '#price',
data: {
minPrice: 10, // 最小起送价10元
totalPrice: 0 // 输入框双向绑定改变值
},
computed: {// 计算属性 监听totalPrice的值的变化做出改变
payDesc() {// 计算支付
let result = `还差${this.minPrice}元起送`
if (this.totalPrice < this.minPrice && this.totalPrice !== 0) {
result = `还差${this.minPrice - this.totalPrice}元起送`
} else if (this.totalPrice >= this.minPrice) {
result = '立即购买'
}
return result// 返回值
},
payClass() {// 支付样式
let result = this.totalPrice >= this.minPrice ? 'pay enough' : 'pay'
return result
}
}
})
4.1.2 计算属性get和set方法
get 获取值
set 赋值
反转字符串的功能
<div id="get-set">
<input v-model="str">
<input v-model="impStr">
</div>
当第一个输入框输入值时,第二个输入框同时获取第一个输入框的值。
当第二个输入框输入值时,同时它的值将会赋值给第一个输入框。
计算属性应用在第二个输入框中impStr: {get(){},set(){}} 监听str
new Vue({
el: '#get-set',
data: {
str: 'hello'
},
computed: {
// 如果要手动的设置计算属性的get 和 set值 需要将计算属性写成对象
// 在对象中设置get set方法
impStr: {// 应用在要获取的地方
get() {// 获取该计算属性的值 get带return值的函数
return this.str.split('').reverse().join('')
},
// 给计算属性赋值会执行该函数 set不需要return值
set(value) {// value当前输入框的值 反向赋值给原str
console.log(value)
this.str = value.split('').reverse().join('')
}
}
}
})
第二个输入框要动态获取第一个输入框的值 get
第一个输入框要动态获取第二个输入框的值 set
实现名称补全功能
<div id="app">
姓:<input v-model="lastName">李
名:<input v-model="firstName">小龙
全名:<input v-model="fullName">李 小龙
</div>
new Vue({
el: '#app',
data: {
lastName: '',
firstName: '',
},
computed: {
fullName: {
get() {
return this.lastName + ' ' + this.firstName
},
set(fullname) {
let nameArr = fullname.split(' ')
this.lastName = nameArr[0]
this.firstName = nameArr[1]
}
}
}
})
4.2 观察者watch配置
<div id="watch">
<input v-model="str">
{{str}}反转{{reverseStr}}
</div>
new Vue({
el: "#watch",
data: {
// str: 'hello world'
str: '',
reverseStr: ''
},
watch: {// 创建Vue示例时配置选项,该选项给属性添加一个观察者函数,
// 当检查到对应属性发生改变时,观察者函数将会被执行
// watch观察函数名必须与观察的属性名保持一致
str(newVal, oldVal) {
// 该函数自带两个参数 newVal(被观察属性改变之后的属性值),oldVal(被观察属性改变之前的属性值)
console.log('str被改变,new:' + newVal + ',old:' + oldVal)
// 要获取的值
this.reverseStr = newVal.split('').reverse().join('')
}
}
})
4.3 计算属性和watch的区别:
computed中data:需要一个监听的值 str
watch中data:需要监听的值和获取的值 str reverseStr
- 计算属性是依赖的值改变会重新执行函数,计算属性是取返回值作为最新结果,所以里面不能异步的返回结果。不能写异步逻辑。
- 侦听属性是侦听的值改变会重新执行函数,将一个值重新赋值作为最新结果,所以赋值的时候可以进行一些异步操作。
watch
为对象形式,键是需要观察的表达式,值是对应的回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,可以看成是computed和methods的结合体
computed
属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当做属性来使用
4.4 案例:显示时间转换12-am-12 12-pm-24
改变12h,当am/pm => 24h跟着改变
改变am/pm,12h 和24h跟着改变
改变24h,12h和am/pm跟着改变
4.4.1 watch实现
<h2>watch</h2>
<div id="watch">
<label>12h</label><input type="number" min="0" max="12" v-model="time12">点<br>
<label>am/pm</label><input type="text" v-model="ap"><br>
<label>24h</label><input type="number" min="0" max="24" v-model="time24">点
</div>
new Vue({
el: '#watch',
data: {
time12: 1,
ap: 'pm',
time24: 13
},
watch: {
time12(newVal, oldVal) { // newVal新值 oldVal旧值
let num = parseInt(newVal)// 将值转化为数字类型,输入框输入的值是文本类型的
// 处理time12的值 必须在0-12之间 NaN == NaN false
if (num < 0 || num > 12 || num !== num) {
this.time12 = oldVal
}
// 0点问题 0点只有am存在
if (num == 0) {
this.ap = 'am'
}
//根据 am AM还是 pm 处理time24的值
if (/^am$/i.test(this.ap)) { // /正则表达式/ i不区分大小写 以^开始$结束
this.time24 = num
} else if (/^pm$/i.test(this.ap)) {
this.time24 = num + 12
}
},
ap(newVal, oldVal) {
if (/^am$/i.test(newVal) || /^pm$/i.test(newVal)) {
// 0点时不能设置pm
let num = parseInt(this.time12)
if (num == 0 && /^pm$/i.test(newVal)) {
this.ap = 'am'
} else {
this.ap = newVal
}
//根据 am AM还是 pm 处理time24的值
if (/^am$/i.test(this.ap)) {
this.time24 = num
}
if (/^pm$/i.test(this.ap)) {
this.time24 = num + 12
}
}
},
time24(newVal, oldVal) {
let num = parseInt(newVal)
if (num > 12) {
this.time12 = num - 12
this.ap = 'pm'
} else {
this.time12 = num
this.ap = 'am'
}
}
}
})
4.4.2 computed实现
<h2>computed</h2>
<div id="computed">
<label>12h</label><input type="number" min="0" max="12" v-model="time12">点<br>
<label>am/pm</label><input type="text" v-model="ap"><br>
<label>24h</label><input type="number" min="0" max="24" v-model="time24">点
new Vue({
el: '#computed',
data: {
time12: 1,
ap: 'pm'
},
computed: {
time24: {
get() {
if (/^am$/i.test(this.ap)) {
return this.time12
}
if (/^pm$/i.test(this.ap)) {
let num = parseInt(this.time12)
if (num == 0) {
this.ap = 'am'
} else {
num += 12
}
return num
}
},
set(value) {
value = parseInt(value)
if (value > 24 || value < 0) {
// 超出范围强制刷新
this.ap = /^pm$/i.test(this.ap) ? 'am' : 'pm'
} else {
if (value > 12) {
this.ap = 'pm'
this.time12 = value - 12
} else {
this.ap = 'am'
this.time12 = value
}
}
}
}
}
})
5.0 表单
model/'mɒdl/模型
5.1 v-model 双向绑定数据
v-model与表单进行配合使用,达到双向绑定让表单元素成为可控表单的命令,我们称v-model是一个语法糖
<input v-model="inputValue">{{inputValue}}
5.2 textarea 多行文本元素
多行文本元素textarea依然使用v-model进行双向绑定
<textarea v-model="textareaVal"></textarea>{{textareaVal}}
5.3 checkbox 复选框
-
复选框:通过v-model默认绑定是布尔值类型
单个复选框,绑定到布尔值:
<input type="checkbox" v-model="checkbox1">{{checkbox1}}
-
通过v-model进行复选,v-model绑定的属性是一个数组
多个复选框,绑定到同一个数组:
必须要有value属性值 value=""
爱好:
<input type="checkbox" value="anime" v-model="checkbox2">动漫
<input type="checkbox" value="code" v-model="checkbox2">代码
<input type="checkbox" value="music" v-model="checkbox2">音乐
{{checkbox2}}
<!--[ "anime", "code", "music" ]-->
5.4 单选框
必须要有value属性值 value=""
<input v-model="sex" type="radio" value="man">男
<input v-model="sex" type="radio" value="woman">女
{{sex}}<!--man / woman-->
5.5 选择框
disabled/dɪs’eɪbld/ 不能选中
<select v-model="select">
<option disabled value="">请选择你所在的城市</option><!--不能选中做提示用的-->
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="gz">广州</option>
<option value="sz">深圳</option>
</select>
{{select}} <!--北京/上海/广州/深圳-->
new Vue({
el: app,
data: {
inputValue: 'hello',
textareaVal: '多行文本',
checkbox1: true,
checkbox2: [],
sex: '',
select: ''
}
})
6.0 条件语句v-if
和 v-show
显示/隐藏元素
v-if和v-show的区别:
当v-show
值为false
对应元素display:none
被隐藏
当v-if
值为false
对应元素会被删除
如果 隐藏的元素需要频繁的出现在页面中时推荐使用 v-show
减少页面渲染降低cpu使用率
如果==元素只出现一次(或者次数较少)==请使用v-if
v-if
不存在组件复用所以涉及频繁组件之间的切换尽量不要使用v-if
true显示/false隐藏
<div v-show="show" style="width: 100px;height: 100px;background: red;">show</div> <!--为false display:none-->
<div v-if="show">123</div> <!--为false删除元素-->
v-if v-else-if v-else 条件判断语句
<input type="number" v-model="ifVal">{{ifVal}}
<div v-if="ifVal == 0" style="width: 100px;height: 100px;background: red;">ifVal == 0</div>
<div v-else-if="ifVal > 0" style="width: 100px;height: 100px;background: green;">ifVal > 0</div>
<div v-else style="width: 100px;height: 100px;background: blue;">else</div>
var vm = new Vue({
el: '#app',
data: {
show: true,
ifVal: 0
}
})
v-if与v-show的区别
相同点:v-if与v-show都可以动态控制dom元素显示隐藏
不同点:v-if显示隐藏是将dom元素整个添加或删除,而v-show隐藏则是为该元素添加css–display:none,dom元素还在。
vue中v-if和v-for优先级
v-for和v-if不应该一起使用,必要情况下应该替换成computed属性。原因:v-for比v-if优先,如果每一次都需要遍历整个数组,将会影响速度,尤其是当之需要渲染很小一部分的时候。
错误写法
<li
v-for="user in users"
v-if="user.isActive"
:key="user.id"
>
{{ user.name }}
</li>
如上情况,即使100个user中之需要使用一个数据,也会循环整个数组。
正确写法
computed: {
activeUsers: function () {
return this.users.filter(function (user) {
return user.isActive
})
}
}
<ul>
<li
v-for="user in activeUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
https://www.cnblogs.com/gitByLegend/p/10837777.html
永远不要把 v-if
和 v-for
同时用在同一个元素上。
<ul>
<li
v-for="user in users"
v-if="shouldShowUsers"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
更新为:
<ul v-if="shouldShowUsers">
<li
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</li>
</ul>
组件复用
webpack 以react为例,展示组件复用
import React from 'react'
import ReactDOM from 'react-dom'
function render() {
ReactDOM.render(
(<div>
当前时间为{new Date().toLocaleTimeString()}
</div>),
document.querySelector('#app')
)
}
render()
setInterval(render, 1000)