vue 特点:
- 有自己的生态圈
- 运行快, 虚拟DOM
- 无刷新更新数据
基础 -指令
- v-html =》 将传入数据中的标签内容提出来显示
- v-text => 将传入数据中的标签和内容全部显示出来
<body>
<div id="app">
<p v-html="txt1"></p>
<p v-text="txt2"></p>
<div>
<script src="./vue.js" ></script>
<script>
let vm = new Vue({
el: '#app',
data: {
txt1: '<h1>v-html</h1>',
txt2: '<h1>v-text</h1>'
}
})
</script>
</body>
显示如下图:
- v-cloak => 必须配合display:none 才能解决{{}}的闪现问题
- 作用:
- 让具有v-cloak的标签都隐藏
- 等数据都加载成功之后在显示
- 作用:
<style>
[v-cloak]{
display: none;
}
</style>
<div id="app" v-cloak>{{}}</div>
- v-model =>动态绑定数据
<input type="text" v-model="txt" /> // txt 对应 实例data数据中的属性txt
- v-once =》默认数据只绑定一次
<p v-once>{{txt==='hello' ? 'hello world' : txt}}</p>
- v-if / v-else / v-show
- v-if / v-else 是对DOM元素的增加和删除,相当于appendChild 和removeChild
- 用处:如果只对DOM操作一次,建议使用v-if ,频繁操作的话不建议使用
- v-show 是对display的block 和 none
- 用处:频繁操作DOM的话建议使用
- v-if / v-else 是对DOM元素的增加和删除,相当于appendChild 和removeChild
<body>
<div id="app">
<p v-if="bok">{{txt}}</p>
<p v-show="bok">{{txt}}</p>
</div>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data:{
txt: 'Hello world !',
bok: true
}
})
</script>
</body>
显示结果如下图:
值为true的图
值为false的图
- v-for => 用来遍历对象和数组
<body>
<div id="app">
<ul>
<li v-for="(item,i) in datas">{{item}}</li>
</ul>
</div>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data:{
datas:[1,2,3,4,5,6]
}
})
</script>
</body>
结果如下图:
表达式 {{}}
- 获取动态数据
<p> {{txt}}</p>
- 设置默认值,此处设置默认值时无法改变的,可以在实例设置默认值
// 表达式设置默认值 {{txt = '设置默认值'}} // 实例设置默认值 data:{ txt : '默认值' }
- 直接进行运算 和 比较
<body> <div id="app"> // 判断 {{txt===true ? 'Hellow world' : txt}} // 运算 {{a+b}} </div> <script> let vm = new Vue({ el:'#app, data:{ txt: true, a: 1, b: 3 } }) </script> </body>
vue 体验
vue : json+HTML =》通过表达式“”{{}}“”填入动态数据
<body>
<div id="app">{{name}}</div> // {{name}} 接收动态数据,并显示在页面上
<script src="./vue.js"></script>
<script>
let vm = new Vue({ // 创建一个vue实例
el: "#app", // 实例可以控制的范围
data:{ // 数据都在data对象内
name: 'Hello world !' // 数据
}
})
</script>
</body>
双向数据绑定
vue 为MVVM的框架 :即为数据影响视图 ,视图影响数据,主要用在form元素中
<body>
<div id="app">
<input type="text" v-model="txt"> // v-model:动态绑定绑定数据
<p>{{txt}}</p>
</div>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data:{
txt: ''
}
})
</script>
</body>
事件
- 事件绑定的函数,放在methods中;
- 动态数据,放在data中
- v-on :事件类型 =》 v-on:click
- 简写为:@click
- 事件绑定中,带不带 括号"()" 的区别
- 带括号 :
- 可以传参
- 必须"手动"传入事件对象$event
- 带括号 :
<body>
<div id="app">
<ul>
<li v-for="(item,i) in datas" v-on:click="fn(i,$event)">
<h1>{{item.name}}</h1>
<p>{{item.age}}</p>
</li>
</ul>
</div>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data:{
datas: [
{name:'a',age:1},
{name:'b',age:2},
{name:'c',age:3},
]
},
methods:{
fn(i,e){
console.log(i,e);
}
}
})
</script>
</body>
修饰符 通过"."操作
- 鼠标事件@click
- 键盘事件 @keydown / @keyup
- @keydown.down
- @keydown.up
- @keydown.enter
- @keydown.键值
- @click.stop =》 阻止事件冒泡
- @click.prevent =》 阻止默认事件
- 串联使用 : @keydown.stop.prevent
动态绑定 用冒号" : " 来绑定
-
v-bind:src 简写为 :src
- 所有标签元素身上的属性,都能简写为 " : 属性" 来获取动态数据
-
动态的class样式
- 对象
<div :class="{样式名:计算出的Boolean值}"> </div>
- 数组
<div :class="[变量名1,变量名2]"></div> data:{ 变量1: '样式1', 变量2: '样式2' }
-
动态的style样式
- 行间样式
- 获取数据中样式
<body>
<div id="app">
// 动态行间样式
<p :style="{background: 'red',color:'white'}">aaaaaaa</p>
// 动态获取数据中样式
<p :style="[a,b]">bbbbbbb</p>
</div>
<script src="./vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
bok: true,
a:{
background: 'blue'
},
b:{
color: 'white'
}
}
})
</script>
</body>
demo 焦点切换
<body>
<div id="app">
<div class="container">
<ul class="list-group h4">
<li @click="fn(i)" v-for="(item,i) in datas" class="list-group-item" :class="{active:index===i}">
<p>姓名 : {{item.name}} ; 年龄 : {{item.age}}</p>
</li>
</ul>
</div>
</div>
<script src="./vue.js"></script>
<script>
let datas=[
{name: 'a',age: 1},
{name: 'b',age: 2},
{name: 'c',age: 3},
{name: 'd',age: 4},
]
let vm = new Vue({
el: '#app',
data: {
datas,
index: 0
},
methods: {
fn(i){
this.index = i;
}
}
});
</script>
</body>
计算属性:computed
- 计算属性将被混入到Vue实例中
- 所有的getter和setter的this上下文自动绑定为Vue实例
- 计算属性的结果会被缓存
- 注意:此处不能使用箭头函数来定义计算属性函数
demo1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="animate.css">
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<div class="container h3">
<input type="text" class="form-control" v-model="txt">
<ul class="list-group">
<transition-group enter-active-class="animated fadeInUp" leave-active-class="animated fadeOutDown">
<li key="i" v-for="(item,i) in datas" class="list-group-item">{{item}}</li>
</transition-group>
</ul>
</div>
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data:{
txt: '',
lists:['aaa','bbbb','ccccc']
},
computed:{
// 在计算属性中,直接以函数形式只有get功能
datas(){
let arr = [];
this.lists.forEach(item=>{
item.toString().includes(this.txt) && arr.push(item);
})
return arr;
}
}
})
</script>
</body>
</html>
计算属性中的datas方法以datas属性中get方法代替
// 更替后效果完全一样
datas:{
get(){
let arr = [];
this.lists.forEach(item=>{
item.toString().includes(this.txt) && arr.push(item);
})
return arr;
}
}
在datas对象中有get方法,自然就少不了set方法
- set : 顾名思义就是用来设置属性值的
datas:{
get(){
// 获取
},
set(val){
// 设置
}
}
- set 赋值
- 通过实例调用datas来赋值
set(val){
// val 自动接收值
console.log(val);
}
vm.datas = 'ccc';
自定义键盘事件的修饰符
全局设置Vue.config
- Vue.config 是一个对象,包含Vue的全局配置,可以在启动应用之前修改属性
- 可修改的属性
- slient
- optionMergeStrategies
- devtools
- errorHandler
- warnHandler
- ignoredElements
- keyCodes
- performance
- productionTip
- 可修改的属性
<body>
<div id="app" >
<input type="text" @keydown.p="fn" >
<script src="vue.js">
// 通过全局设置keyCodes,自定义键盘事件的修饰符
Vue.config.keyCodes.p = 80;
let vm = new Vue({
el: "#app",
methods:{
fn(){
alert(111);
}
}
})
</script>
</div>
</body>
组件
- 组件是一个对象
- 包含:
- 模板
- 模板是字符串
- 数据
- 方法 / 函数
- 生命周期钩子函数,等
- 模板
- 包含:
- 组件特性
- :is -> 判断
- slot -> 接收来自显示写入组件的内容
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app">
<!-- 父组件显示 -->
<parent></parent>
</div>
<!-- 父组件内容 -->
<template id="parent">
<div>
<h1>Hello,我是{{name}}</h1>
<!-- 子组件显示 -->
<children>Hi</children>
</div>
</template>
<!-- 子组件内容 -->
<template id="children">
<div>
<h1><slot></slot>,我是{{name}}</h1>
</div>
</template>
<script src="vue.js"></script>
<script>
// 子组件
let children={
template:"#children",
data(){
return{
name: "丹丹"
}
}
}
// 父组件
let parent = {
template: "#parent",
data(){
return{
name: "蛋蛋"
}
},
// 子组件注册
components:{children}
}
let vm = new Vue({
el: "#app",
// 父组件注册
components:{parent}
})
</script>
</body>
</html>
浏览器渲染:
组件数据通信
- 概括:
- 父给子传递数据通过属性传递,通过props接收
- 子给符传递数据通过$emit传递,通过函数接收
- 也就是事件订阅发布的思想
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子互相传递数据</title>
</head>
<body>
<div id="app">
<parent></parent>
</div>
<template id="p">
<div>
<h2>我是parent,{{age}}岁,我children{{cAge}}</h2>
<!--
:pr => children组件接收parent组件传递的数据
@send => parent组件接收children组件传递的数据
-->
<children :pr="age" @send="fn"></children>
</div>
</template>
<template id="c">
<div>
<!--
children组件通过@click 点击事件触发fn函数发送数据
-->
<h2 @click="fn">我是children,{{age}}岁,我的parent{{pr}}岁</h2>
</div>
</template>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
components:{
parent:{
template:'#p',
data(){
return {
age: 48,
cAge: 0
}
},
methods: {
// parent组件通过fn方法接收children发送的数据 , 也就是订阅
fn(val){
this.cAge = val;
}
},
components:{
children:{
template: '#c',
data(){
return {
age: 18
}
},
// children组件通过props对象接收parent组件发送的数据
props:{
pr:{
// 设置接收的数据类型
type: Number,
// 默认值
default: 0,
// 进行校验
vilidator:function(val){
return val > 28;
},
// 是否为必传,true为必传,不设置此属性或属性值为false为不必传
required: true
}
},
methods: {
// children组件通过$emit发送数据 , 也就是发布
fn(){
this.$emit('send',this.age);
}
}
}
}
}
}
})
</script>
</body>
</html>
点击children组件后的浏览器渲染结果
路由
- 注册路由组件
- 组件即对象
- 创建路由实例
- routes 为 数组 [ ]
- 在Vue实例vm中注册路由
- 在app中,添加导航和对应显示的模块
- 导航链接: <router-link to=""></router-link>
- 显示模块:<router-view></router-view>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue-router : demo1</title>
<style>
a{
text-decoration: none;
}
.router-link-exact-active.router-link-active{
background: red;
color: white;
}
.style{
padding: 10px;
background: lightblue;
}
</style>
</head>
<body>
<div id="app">
<!-- 4. 添加导航和队形显示的模块 -->
<router-link to="/home" class="style">首页</router-link>
<router-link to="/list" class="style">列表页</router-link>
<router-view></router-view>
</div>
<template id="home">
<div>
<h1>我是首页</h1>
<router-link to="/home/login" class="style">登录</router-link>
<router-link to="/home/regist" class="style">注册</router-link>
<router-view></router-view>
</div>
</template>
<template id="list">
<div>
<h1>我是列表页</h1>
<router-link to="/list/news/1" class="style">new1</router-link>
<router-link to="/list/news/2" class="style">new2</router-link>
<router-link to="/list/news/3" class="style">new3</router-link>
<router-view></router-view>
</div>
</template>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>
// 1. 注册路由组件,组件为对象
let Home = {
template: "#home"
};
let List = {
template: "#list"
};
let Login = {
template: `<h1>我是登录页面</h1>`
};
let Regist = {
template: `<h1>我是注册页面</h1>`
}
// routes为数组
let routes = [
{path: '/home',component: Home,children:[
{path: 'login',component: Login},
{path: 'regist',component: Regist}
]},
{path: '/list',component: List,children:[
{path: 'news/:id',component:{template:`<h1>这是文章{{$route.params.id}}</h1>`}}
]}
]
// 2.创建路由实例
let router = new VueRouter({
routes
})
// 3. 在vm中注册路由
let vm = new Vue({
router,
el: "#app"
})
</script>
</body>
</html>