官方地址
安装Vue库
地址:https://v2.cn.vuejs.org/v2/guide/installation.html
安装浏览器调试工具
另外一种方式
安装Vue-devtools
-
克隆gitee项目 https://gitee.com/wen_zhao/devtools
git clone https://gitee.com/wen_zhao/devtools.git
- 切换到add-remote-devtools分支
git checkout -b add-remote-devtools origin/add-remote-devtools
- 安装依赖
cnpm i
- 打包
npm run build
- 在谷歌浏览器添加扩展程序
用vue写第一个Hello world
- 引入Vue.js
<script src="../vue.js/vue.js"></script>
- 准备好一个装载数据的容器
<div id="app">{{message}}</div>
- 创建Vue实例
<script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 message: 'Hello world!' } }); </script>
注意
- 一个vue实例只能接管一个容器
- 插值语法:{{}} 可以读取到在data的所有属性
- data中数据发生变化,那么在容器用到的数据会自动更新
模板语法
插值语法
-
特点:用在标签体内容
-
写法
{{xxx}} // xxx是js表达式,可以拿到data里所有的属性
指令语法
-
特点:用在标签的解析(标签属性,标签体内容,绑定事件等)
-
举例(vue的指令语法形式写法:v-xxx)
// 解析标签属性:v-bind v-bind:href='url' :href='url' // 简写模式
示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js/vue.js"></script> </head> <body> <div id="app"> {{name}} <a :href="url">博客园地址-1</a> <a v-bind:href="url">博客园地址-2</a> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: 'Hello world!', url: 'https://www.cnblogs.com/chenyanbin/' } }); </script> </body> </html>
双向数据绑定
单项数据绑定
-
特点:只能从data流向页面
-
实现
// 通过v-bind实现单项数据绑定 <input type="text" :value="name" />
双向数据绑定
-
特点:不仅可以从data流向页面,也能从页面表单元素(输入元素)流向data
-
实现
// 通过v-model实现双项数据绑定 <input type="text" v-model:value="name" /> <input type="text" v-model="name" /> // 简写
示例
<div id="app"> <h3> 单项数据绑定<input type="text" :value="name" /> <br/> 双项数据绑定<input type="text" v-model:value='name' /> </h3> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: 'Hello world!' } }); </script>
Vue核心知识点
常用事件处理修饰符
- 事件绑定指令:v-on
<button v-on:click="showMessge">点击</button> // 简写 <button @click="showMessge">点击</button>
- 事件传参
<button @click="showMessge('hello')">点击</button> methods: { showMessge(text) { console.log(text); }, },
注意
- methods中配置的函数不要使用箭头函数
- event.target.innerText能拿到标签的值,但是调用不加()或者加($event)
常用事件修饰符
- 阻止默认事件
// js中的阻止默认事件 e.preventDefault() // vue @click.prevent="showMessge"
- 阻止事件冒泡
// js中的阻止事件冒泡 e.stopPropagation() // vue @click.stop="showMessge" // 阻止冒泡、默认事件连用 @click.stop.prevent="showMessge"
- 只触发一次事件
@click.once="showMessge"
键盘事件
@keyup.enter="showMessge"
示例
<div id="app"> <h3 v-on:click="cyb">点击</h3> <h3 @click="cyb">点击</h3> <h3 @click="show('hello world')">有参数点击</h3> <h3 @click="cyb2">点我试试</h3> <h3 @click="cyb2($event)">点我试试1111</h3> <a href="https://www.cnblogs.com/chenyanbin/" @click="cyb3">博客地址</a> <a href="https://www.cnblogs.com/chenyanbin/" @click.prevent="cyb4">博客地址</a> <div @click="cyb5"> <div @click="cyb5"> 冒泡事件 </div> </div> <h3 @click.once="cyb">一次事件</h3> <div> 键盘事件:<input type="text" @keyup.enter='cyb6' /> </div> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: 'Hello world!' }, methods: { cyb() { //无参方法 alert("111111111"); }, show(text) { //有参方法 alert(text); }, cyb2(event) { //获取标签内的值 alert(event.target.innerText) }, cyb3(e) { e.preventDefault(); alert('333') }, cyb4(e) { alert('444') }, cyb5() { alert('555') }, cyb6() { alert('666') } } }); </script>
Vue中的计算属性
计算属性
-
定义
通过已有的属性计算而来
-
写法
-
读取/更改
-
fullName: { get() { return this.firstName + '-' + this.lastName; }, set(value) { this.firstName = value.split('-')[0]; this.lastName = value.split('-')[1]; }, },
读取简写
computed: { fullName() { return this.firstName + '-' + this.lastName; }, } // 注意:只有当只读时可以简写,有修改需求时不能使用简写
通过methods实现
methods: { fullName() { return this.firstName + '-' + this.lastName; }, }
示例
<div id="app"> 姓:<input type="text" v-model="firstName"> 名: <input type="text" v-model="lastName" /> 全名: <input type="text" v-model='fullName()' /> 全名2: <input type="text" v-model="fullName2"> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 firstName: '', lastName: '' }, methods: { fullName() { return this.firstName + "-" + this.lastName; } }, computed: { fullName2: { get() { return this.firstName + "-" + this.lastName; }, set(value) { this.firstName = value.split('-')[0]; this.lastName = value.split('-')[1]; } } } }); </script>
计算属性优点
- 有缓存的机制,可以复用
- 效率高,调试方便
Vue中的监视属性
监视属性
watch: { isSunny: { immediate:true, // 开启初始化调用 deep:true, // 开启深度监视 handler() { this.plan = this.isSunny ? '打蓝球' : '敲代码'; }, }, }
-
被监视的属性发生改变时,调用回调函数,执行相关操作
-
配置
immediate:true
实现初始化调用 -
监视的属性须存在才能进行监视
深度监视
- Vue自身可以监测到多层数据的改变,但是在watch中不可以(只能监测简单的数据类型)
- 在watch中配置
deep:true
可以监测多维数据,根据具体数据结构决定是否采用深度监视
示例
<div id="app"> 今天的计划:{{plan}} <br> <button @click="change">切换天气</button> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 plan: '打篮球', isSunny: true }, methods: { change() { this.isSunny = !this.isSunny; } }, watch: { //监视属性 isSunny: { //监视属性的值 immediate: true, // 开启初始化调用监听 deep: true, //开启深度监听 handler() { this.plan = this.isSunny ? '打篮球' : '撸代码'; } } } }); </script>
Vue中class样式的绑定
字符串写法
-
使用场景
- 样式的类型不确定
-
写法
<div :class="cyb_bg">陈彦斌</div>
-
手动触发样式改变
-
注意
字符串使用的是vue实例data中的已有属性
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js/vue.js"></script> <style> .bg_1 { background-color: red; } .bg_2 { background-color: blue; } </style> </head> <body> <div id="app"> <div :class="bg_red" @click="change"> {{name}} </div> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: '陈彦斌', bg_red: 'bg_1' }, methods: { change() { this.bg_red = 'bg_2'; } } }); </script> </body>
对象写法
-
使用场景
- 样式个数、类名确定,通过Boolean动态展示与否
<style> .bg_1 { background-color: red; } .bg_2 { background-color: blue; } .fs { font-size: 50px; } </style> <div id="app"> <div :class="{bg_2:true,fs:true}">{{name}}</div> </div>
-
对象写在内联样式
<div :class="{bg_red:bg_red,border:border}">陈彦斌</div>
- 对象写在data中
<div :class="list">陈彦斌</div> data: { list: { bg_red: 'bg_red', border: 'border', }, }
数组写法
-
使用场景
- 需要绑定的样式个数不确定,类名也不确定
-
内联写法
<div :class="[cyb_border,cyb_bg]">陈彦斌</div>
- 数组里加三元表达式
<div :class="[isActive?cyb_border:'',cyb_bg]">陈彦斌</div>
- 写在data中
<div :class="list">陈彦斌</div> data:{ list:['border', 'bg_red'] }
示例
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../vue.js/vue.js"></script> <style> .bg_1 { background-color: red; } .bg_2 { background-color: blue; } .fs { font-size: 50px; } .fc { color: green; } </style> </head> <body> <div id="app"> <!-- 字符串的写法 --> <div :class="bg_red" @click="change"> {{name}} </div> <!-- 对象的写法 --> <div :class="{bg_2:true,fs:true}">{{name}}</div> <!-- 数组的写法 --> <div :class="list">{{name}}</div> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: '陈彦斌', bg_red: 'bg_1', list: [ 'bg_1', 'fs', 'fc' ] }, methods: { change() { this.bg_red = 'bg_2'; } } }); </script> </body>
Vue中style样式动态绑定
- 样式中2个单词中间不能出现“-”,第二个单词需要转大写
- style样式中,需要key-value形式,value需要加单引号
<div id="app"> <div :style="{backgroundColor:red,color:blue}">{{name}}</div> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: '陈彦斌', red: 'red', blue: 'blue' } }); </script>
Vue中的条件渲染
v-if
- 写法
<p v-if="dice===1">周一</p> <p v-else-if="dice===2">周二</p> <p v-else-if="dice===3">周三</p> <p v-else>未知</p>
特点
-
语法和原生js的
if...else if...else
一样 -
不展示时直接移除DOM元素,适合切换频率低的场景
-
v-if
、v-else-if
、v-else
要连用
v-show
- 写法
<p v-show="dice===1">周一</p> <p v-show="dice===2">周二</p> <p v-show="dice===3">周三</p> <p v-show="dice===4">周四</p>
特点
-
不展示时使用样式隐藏,适合切换频率高的场景
v-if
vs v-show
- 一般来说,
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。 - 如果需要非常频繁地切换,则使用
v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。
示例
<div id="app"> <p v-if="dice===1">周一</p> <p v-else-if="dice===2">周二</p> <p v-else-if="dice===3">周三</p> <p v-else>未知</p> <button @click="thorFun">投骰子</button> <br> <p v-show="dice===1">周一</p> <p v-show="dice===2">周二</p> <p v-show="dice===3">周三</p> <p v-show="dice===4">周四</p> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 dice: '' }, methods: { thorFun() { this.dice = Math.floor(Math.random() * 4); console.log(this.dice); } } }); </script>
Vue中的列表渲染
v-for
-
定义
- 用
v-for
指令基于一个数组来渲染一个列表。v-for
指令需要使用item in items
形式的特殊语法,其中items
是源数据数组,而item
则是被迭代的数组元素的别名
- 用
-
遍历数组
-
写法
-
<li v-for="(item,index) in list">{{item.name}}-{{index}}</li> new Vue({ el: '#app', data: { list: [{ name: '张三' }, { name: '李四' }, { name: '王五' }], }, });
- 第二个参数
<li v-for="(item,index) in list">{{item.name}}-{{index}}</li>
- 也可以用
of
替代in
<li v-for="(item,index) of list">{{item.name}}-{{index}}</li>
遍历对象
-
写法
<li v-for="value in obj">{{value}}</li> new Vue({ el: '#app', data: { obj: { name: '张三', age: '18', sex: '男' }, }, });
- 第二个参数(键名)
<li v-for="(name,value) in obj">{{name}}:{{value}}</li>
- 第三个参数(索引)
<li v-for="(name,value,index) in obj">{{index}}:{{name}}:{{value}}</li>
示例
<div id="app"> <div v-for="item in name">{{item}}</div> <br> <div v-for="(item,index) in list">{{item.week}}-{{index}}</div> <br> <div v-for="(v,k) in obj">{{k}}-{{v}}</div> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 name: '陈彦斌', list: [{ week: '周一' }, { week: '周二' }, { week: '周三' }, { week: '周四' }, { week: '周五' }, { week: '周六' }, { week: '周日' }], obj: { name: 'Alex', age: '18', sex: '男' } } }); </script>
Vue中列表过滤
列表过滤
- 做一个商品关键字搜索展示列表
<div id="app"> <input type="text" v-model='inputValue' /> <ul> <li v-for="obj in newList">{{obj.name}}-{{obj.price}}</li> </ul> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 list: [{ name: '牛仔裤', price: '88元' }, { name: '运动裤', price: '67元' }, { name: '羽绒服', price: '128元' }, { name: '运动服', price: '99元' }], newList: [], inputValue: [] }, watch: { //监听器 inputValue: { immediate: true, handler(val) { this.newList = this.list.filter((i) => { return i.name.indexOf(val) !== -1; }) } } } }); </script>
Vue中列表排序
列表排序
-
对商品列表进行排序
<div id="app"> <input type="text" v-model='inputValue' /> <button @click="keyword=1">降序</button> <button @click="keyword=2">升序</button> <button @click="keyword=0">原顺序</button> <ul> <li v-for="obj in newList">{{obj.name}}-{{obj.price}}元</li> </ul> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 list: [{ name: '牛仔裤', price: '88' }, { name: '运动裤', price: '67' }, { name: '羽绒服', price: '128' }, { name: '运动服', price: '99' }], inputValue: [], keyword: 0 }, computed: { newList() { const arr = this.list.filter((i) => { return i.name.indexOf(this.inputValue) !== -1; }) if (this.keyword) { arr.sort((a1, a2) => { return this.keyword === 2 ? a1.price - a2.price : a2.price - a1.price; }) } return arr; } } }); </script>
表单数据的绑定
<div id="app"> <form @submit.prevent="submit"> 账号:<input type="text" v-model="userInfo.username"><br /> 账号:<input type="password" v-model="userInfo.password"><br /> 手机号:<input type="number" v-model.number="userInfo.phone"><br /> 性别:男<input type="radio" name="sex" value="male" v-model='userInfo.sex' /> 女<input type="radio" name="sex" value="femal" v-model='userInfo.sex' /><br /> 方向:前端<input type="checkbox" value="front" v-model='userInfo.direction' /> 后端<input type="checkbox" value="back" v-model='userInfo.direction' />测试<input type="checkbox" value="test" v-model='userInfo.direction'><br /> 地区:<select v-model="userInfo.city"> <option value="">请选择地区</option> <option value="bj">北京</option> <option value="sh">上海</option> <option value="gz">广州</option> <option value="sz">深圳</option> </select><br/> 备注:<textarea v-model="userInfo.remarks"></textarea><br> <input type="checkbox" v-model="userInfo.agree">请阅读并接受<a href="http://baidu.com">《用户协议》</a> <br><br> <button>提交</button> </form> </div> <script> new Vue({ el: '#app', //用于指定当前Vue实例为那个容器使用,值为css选择器字符串 data: { //用于存储数据,数据供el指定的容器使用 userInfo: { username: '', password: '', phone: '', sex: '', direction: [], city: '', remarks: '', agree:'' } }, methods: { submit(){ console.log(this.userInfo) } } }); </script>
Vue指令v-text/v-html
v-text
-
写法
<p v-text="name"></p> new Vue({ el: '#app', data: { name: '陈彦斌', }, });
特点
- 在所在节点渲染文本内容
- 会替换节点中所在的内容
v-html
-
写法
<p v-html="str"></p> new Vue({ el: '#app', data: { str: '<h1>陈彦斌</h1>', }, });
-
特点
- 在所在节点渲染html结构的内容
- 替换节点所在的所有内容
-
注意
- 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击(注入恶意指令代码到网页)
- 只在可信内容上使用
v-html
,不要在用户提交的内容上。