Vue 初识
官方地址
安装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,不要在用户提交的内容上。
Vue父子组件的传值
父向子传值
-
props只接收
props: ["cyb"]
限制类型
props: { cyb: String }
限制类型,限制必要性,限制默认值d
props: {
cyb: {
type: String,
required: true,
default:'你好',
},
},
-
注意
- props的数据时单向的,只能从父组件传到子组件
- props的数据不可更改,如果要更改需备份到data中做操作
子向父传值
- 自定义事件alex(@绑定)
// 父组件 <cyb-home @myParam="alex" />
// 子组件
dianji_cyb() {
this.$emit("myParam", this.name);
},
自定义事件的解绑
this.$off()
1

浙公网安备 33010602011771号