Vue
Vue,中国的 Web 前端框架!
Vue的两个特性
1、数据驱动视图
2、双向数据绑定
底层原理:MVVM(Module 数据源、View 视图、ViewModel 是 Vue 的实例)
指令
1、内容渲染
支持 JavaScript 表达式的运算
1 | {{ number + 1}} |
-
v-text 覆盖元素内部原有的内容
-
插值表达式
-
v-html 渲染包含 HTML 标签的字符串
1
2
3
4
5
6
7
8
9
10
11
12
13<div id="app">
<p>姓名:{{ tom }}</p>
<h2 v-html="message2"></h2>
</div>
<script>
const app = new Vue({
el: '#app',//控制的区域
data: {//所要渲染的数据
tom: "王狗",
message2: '<h2 style="color: red">hegou</h2>'
}
});
</script>
2、属性绑定
注意:插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中
-
v-bind
简写为冒号:
1
2
3
4
5
6
7
8
9
10
11<div id="app">
<input type="text" :placeholder="tips">
</div>
<script>
const app = new Vue({
el: '#app',
data: {
tips: "请输入"
}
});
</script>
3、事件绑定
-
v-on 简写为@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<div id="app">
<p>{{ count }}</p>
<button @click="add($event, 1)">+N</button><br
</div>
<script>
const app = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
add(e, n) {
this.count += n
if (this.count % 2 == 0) {
e.target.style.backgroundColor = 'red'
} else {
e.target.style.backgroundColor = null
}
}
},
});
</script> -
事件修饰符
1
2@click.prevent <!-- 阻止默认行为 -->
@click.stop <!-- 阻止事件冒泡 --> -
按键修饰符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<body>
<div id="app">
<input type="text" @keyup.esc="clear" @keyup.enter="submit">
</div>
<script>
const app = new Vue({
el: '#app',
methods: {
clear(e) {
e.target.value = ''
},
submit(e) {
console.log('触发enter提交事件')
}
},
});
</script>
</body>
4、双向绑定
-
v-model
使用在表单元素:
1、input
2、textarea
3、select
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<body>
<div id="app">
<p>用户名:{{ username }}</p>
<input type="text" v-model="username"><br>
<select v-model="city">
<option value="1">上海</option>
<option value="2">深圳</option>
<option value="3">广州</option>
</select>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
username: 'zou',
city: '3'
},
});
</script>
</body>专用修饰符:
.number 自动将用户的输入值转为数值类型
.trim 自动过滤用户输入的首尾空白字符
.lazy 在 “change” 时而非 “input” 时更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<body>
<div id="app">
<input type="text" v-model.number="n1"> +
<input type="text" v-model.number="n2"> =
<span>{{ n1 + n2 }}</span><br>
<input type="text" v-model.trim.lazy="username">
<button @click="showName">获取用户名</button>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
username: 'zou',
n1: 1,
n2: 2
},
methods: {
showName() {
console.log(`用户名是:"${this.username}"`)
}
},
});
</script>
</body>
5、条件渲染
-
v-if
原理:每次动态创建或移除元素
-
v-show
原理:动态为元素添加或移除 display:none 样式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<body>
<div id="app">
<p v-if="flag">被 v-if 控制的元素</p>
<p v-show="flag">被 v-show 控制的元素</p>
<p v-if="type === 'A'">优秀</p>
<p v-else-if="type === 'B'">良好</p>
<p v-else>一般</p>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
flag: true,
type: 'A'
},
});
</script>
</body>
6、列表渲染
-
v-for
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32<body>
<div id="app">
<table class="table table-bordered table-hover table-striped">
<thead>
<th>索引</th>
<th>id</th>
<th>姓名</th>
</thead>
<tbody>
<!-- 把数据项的 id 作为 key 的值,因为具有唯一性 -->
<tr v-for="(item, index) in list" :key="item.id">
<td>{{ index + 1 }}</td>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
list: [
{ id: 1, name: '王狗'},
{ id: 2, name: '小何'},
{ id: 3, name: 'laofu'}
]
},
});
</script>
</body>
案例
1 | <div id="app"> |
全局过滤器
1 | <div id="app"> |
侦听器
作用:监视数据的变化
1、方法格式
缺点:1)无法在刚进入页面时触发 2)若监听的是对象,对象中属性变化时无法触发
1 | username(newval, oldval) { |
2、对象格式
1 | info: { |
-
deep 的代替方案
1
2
3
4
5watch: {
'info.username'(newval, oldval) {
console.log(newval, oldval)
}
}
计算属性
1 | <div id="app"> |
axios
-
post
1
2
3
4
5
6
7
8
9axios({
method: 'post',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
id: 1
}
}).then(result => {
console.log(result)
}) -
get
1
2
3
4
5
6
7
8
9axios({
method: 'get',
url: 'http://www.liulongbin.top:3006/api/getbooks',
params: {
id: 1
},
}).then(result => {
console.log(result.data)
})
vue-cli
assets: 静态文件(css)
components: 可复用的组件
main.js: 项目的入口文件
App.vue: 项目的根组件
流程:
main.js 把 App.vue 渲染到 index.html 的指定区域中
vue 组件
template: 组件的模板结构
style: 组件的 JavaScript 行为
script: 组件的样式
注册私有组件:
(1) 在 script 中导入(import)
(2)在 export default 的 components 中注册标签
(3)在 template 中使用标签
注册全局组件:
(1)导入: import Right from './components/Right.vue'
(2)注册标签: Vue.component('Left', Left)
//第一个参数为注册的标签名
(3)在其它组件中使用标签
组件的 props(为了提高组件的复用性)
自定义属性
props 应该是只读的
样式冲突
1 | <style lang="less" scoped> |
-
使用第三方组件库,修改默认样式
-
父组件修改子组件的样式
1
2
3/deep/h3 {
color: red;
}
生命周期 & 数据共享
组件的生命周期
指一个组件从创建 --> 运行 --> 销毁
组件之间的数据共享
ref 引用
动态组件
component 是内置标签,是组件的占位符,动态切换组件的显示与隐藏
1 | <keep-alive> |
使用 keep-alive 标签让组件被缓存而不是销毁,keep-alive 内置 activated 和 deactivated
当组件第一次被创建,既会执行 created 也会执行 activated
当组件被激活,只会执行 activated
keep-alive 标签的 include属性:指定哪些组件被缓存;exclude属性:指定哪些组件不被缓存;不能同时使用。
==注意==
components 中的组件名作用是使用到页面结构中
而原组件中的 name 作用是结合 keep-live 指定哪个组件被缓存或不被缓存
插槽
每个 slot 插槽,都有 name 属性
template 只是一个虚拟标签,v-slot 必须用在 template 上
v-slot 指令简写为 #
把内容填充到指定名称的插槽中
1 | <Left> |
作用域插槽
1 | <Article> |
自定义指令
-
私有自定义指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<h1 v-color="color">App 根组件</h1>
<h1 v-color="'pink'">App 根组件</h1>
<button @click="color = 'green'">改变 color</button>
data() {
return {
color: "blue",
};
},
directives: {
color: {
//bind 函数只会在一开始触发一次
bind(el, binding) {
el.style.color = binding.value;
},
//updata 函数在数据更新时触发
update(el, binding) {
el.style.color = binding.value;
}
},
}, -
全局自定义指令
1
2
3
4
5
6
7
8Vue.directive('color', {
bind(el, binding) {
el.style.color = binding.value;
},
update(el, binding) {
el.style.color = binding.value;
}
})
路由
嵌套路由
1 | App.vue: |
动态路由
1 | App.vue |
导航
this.$route 是参数对象,用 this.$route.params 访问路径参数,用 this.$route.query 访问查询参数
this.$router 是导航对象
-
声明式导航
点击链接实现导航
-
编程式导航
调用 API 方法
① this.$router.push(‘’) 跳转到指定页面(产生历史记录)
② this.$router.replace(‘’) 跳转到指定页面(不产生历史记录)
③ this.$router.go(n) 前进或后退 n 步到历史页面
- this.$router.back() 后退一步
- this.$router.forward() 前进一步
导航守卫
控制路由的访问权限