vue入门笔记
什么是vue
Vue是一个渐进式的框架
渐进式意味着你可以将Vue作为你应用的一部分嵌套其中
Vue的核心库以及其生态系统
Core + Vue-router + Vuex
Vue特点和Web开发常见高级功能
解耦视图和数据
可复用的组件
前端路由技术
状态管理
虚拟DOM
开始学习
推荐使用软件 hbuider
方式一. 直接CDN引入
可以选择引入开发环境版本 / 生产环境版本
// 开发环境版本, 包含了帮助的命令行警告
<srcipt src='https://cdn.jsdeliver.net/npm/vue/dist/vue.js'></script>
// 生产环境版本, 优化了尺寸和速度
<srcipt src='https://cdn.jsdeliver.net/npm/vue'></script>
方式二. 下载和引入
// 开发环境
https://vuejs.org/js/vue.js
// 生产环境
https://vuejs.org/js/vue.min.js
第一个vue项目
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>element-starter</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<h1>hello</h1>
<div id="app">{{ message }}</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</html>
小白基本
el
全称:element(元素)
作用:控制区域 的元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 被Vue控制的区域,我们称之为模板 -->
<div id="app"></div>
<!--vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
const vm = new Vue({
el: '#app' // 控制id为app的元素
})
</script>
</body>
</html>
$mount
作用和el一致,都是配置控制的元素,使用哪个都可以,二选一
我感觉不怎么使用
const vm = new Vue({})
vm.$mount('#app');
data
类型:对象
作用:存放要用到的数据,数据为响应式的
const vm = new Vue({
el: '#app',
data: {
'vue': 'hello vue'
}
})
插值表达式
<!-- 被Vue控制的区域,我们称之为模板 -->
<div id="app">
<p>{{vue}}</p>
</div>
<!--vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
const vm = new Vue({
el: '#app', // 控制id为app的元素
data: {
'vue': 'hello vue'
}
})
</script>
记住:插值表达式中,可以写:data、js数据、表达式,其他的想都不要想。
注意,只要插值表达式中使用了数据,必须在data中声明过,否则会报错
vue相关指令
v-pre
<!-- 不会被编译 -->
<span v-pre>{{ msg }}</span>
v-clock
这个指令保持在元素上直到关联实例结束编译
可以解决闪烁的问题
和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕
v-once
只渲染元素一次。随后的重新渲染,元素及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能
v-text
更新元素的 textContent
v-text 优先级高于 {{ }}
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>
v-html
更新元素的innerHTML
注意:内容按普通 HTML 插入,不会作为 Vue 模板进行编译
在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。
条件渲染(语法)
v-if, v-else
用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
因为 v-if 是一个指令,所以必须将它添加到一个元素上,但是如果想切换多个元素呢?此时可以把一个 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 元素
<template v-if=true>
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
<h1 v-if="type=true">Yes</h1>
<h1 v-else>No</h1>
<h1>hello</h1>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
/*Model:数据*/
data:{
type: true
}
});
</script>
</body>
</html>
if-else-if
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
<h1 v-if="type==='A'">A</h1>
<h1 v-else-if="type==='B'">B</h1>
<h1 v-else-if="type==='D'">D</h1>
<h1 v-else>C</h1>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
/*Model:数据*/
data:{
type: '6666'
}
});
</script>
</body>
</html>
v-show
<h1 v-show=true>Hello!</h1>
根据表达式之真假值,切换元素的 display CSS 属性。
v-if VS v-show
v-if 是惰性的,如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染条件块。v-show则不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
v-if 有更高的切换开销,v-show 有更高的初始渲染开销,如果需要非常频繁地切换,则使用 v-show 较好,如果在运行时条件很少改变,则使用 v-if 较好
v-show不支持元素
v-show不支持v-else/v-else-if
建议 v-if
v-bind
动态地绑定一个或多个特性
:后的为传递的参数
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--view层,模板-->
<div id="app">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
/*Model:数据*/
data:{
message: '页面加载于 ' + new Date().toLocaleString()
}
});
</script>
</body>
</html>
v-model
双向绑定
v-on
v-on是用来绑定事件监听器,用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
v-on:keyup.enter=“enterFn”
监控键 enter 触发 enterFn 方法
v-on监听事件
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button v-on:click="sayHi">点我</button>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
message:'Hello World'
},
methods:{
sayHi:function(event){
//'this'在方法里面指向当前Vue实例
alert(this.message);
}
}
});
</script>
</body>
</html>
v-for
表单双绑
1.单行文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
输入的文本:<input type="text" v-model="message" value="hello">{{message}}
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
message:""
}
});
</script>
</body>
</html>
2.多行文本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello</h1>
<div id="app">
多行文本:<textarea v-model="hello"></textarea> 多行文本是:{{hello}}
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
hello:""
}
});
</script>
</body>
</html>
3.单复选框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
单复选框:
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{checked}}</label>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
checked:false
}
});
</script>
</body>
</html>
4.多复选框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
多复选框:
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Join</label>
<input type="checkbox" id="join" value="Join" v-model="checkedNames">
<label for="join">Jack</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<span>选中的值:{{checkedNames}}</span>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
checkedNames:[]
}
});
</script>
</body>
</html>
5.单选按钮
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
单选框按钮
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<span>选中的值:{{picked}}</span>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
picked:'Two'
}
});
</script>
</body>
</html>
6.下拉框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- 性别:
<input type="radio" name="sex" value="男" v-model="pan">男
<input type="radio" name="sex" value="女" v-model="pan">女
<p>选中了:{{pan}}</p>-->
下拉框:
<select v-model="pan">
<option value="" disabled>---请选择---</option>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
</select>
<span>value:{{pan}}</span>
</div>
<!--1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
pan:"A"
}
});
</script>
</body>
</html>
组件
组件是可复用的Vue实例, 说白了就是一组可以重复使用的模板, 跟JSTL的自定义标签、Thymeleal的th:fragment等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织:
代码复用
1.第一个组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<pan></pan>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
//先注册组件
Vue.component("pan",{
template:'<li>Hello</li>'
});
//再实例化Vue
var vm = new Vue({
el:"#app",
});
</script>
</body>
</html>
注意
Vue.component():注册组件
pan:自定义组件的名字
template:组件的模板
2.使用props属性传递参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--组件:传递给组件中的值:props-->
<pan v-for="item in items" v-bind:panh="item"></pan>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
//定义组件
Vue.component("pan",{
props:['panh'],
template:'<li>{{panh}}</li>'
});
var vm = new Vue({
el:"#app",
data:{
items:["java","Linux","前端"]
}
});
</script>
</body>
</html>
3.子父组件传值
1.父给子传值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- vue实例的挂载点 vue实例只会处理挂载点里面的内容 -->
<div id="app">
<input type="text" v-model="inputValue">
<button @click="handleSubmit">提交</button>
<ul>
<!-- <li v-for="(item, index) in list" :key="index">{{item}}</li> -->
<!-- 使用组件 -->
<todo-item v-for="(item, index) in list"
:key="index"
:content="item" //将item值传给子组件的content属性
:index="index" //将index值传给子组件的index属性
@delete="handleDelete" //接收子组件发射的delete事件
>
</todo-item>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script>
//注册组件(全局组件),可以直接在任何模板中使用,不需要再vue实例中注册
// Vue.component('todo-item',{
// template:'<li>item</li>'
// })
//定义局部组件
var TodoItem = {
props: ['content','index'],//定义了从外部接收的变量
template: '<li @click="handleClick">{{content}}</li>',
methods: {
handleClick:function(){
//实现子组件删除,一定要在父组件中数据删除掉
//发布订阅模式
//通知父组件将我的数据删除掉
/*
delete:自定义事件
this.index:是delete的参数
*/
this.$emit('delete',this.index);
//说明,当前这个组件向外emit(触发)了一个delete事件,这个事件里面携带了index的值
}
},
}
var app = new Vue({
el: '#app',//vue实例接管id为app的dom,vue实例与DOM节点绑定
//template: ' <p>{{ message }}</p>',//将会放在挂载点之中
components: {
'todo-item': TodoItem,//将局部组件注册到本实例中
},
data: { //数据
inputValue: '',
list: [],
},
methods: {
handleSubmit: function () {
this.list.push(this.inputValue);
this.inputValue = '';
},
handleDelete:function(index){
this.list.splice(index,1);
}
},
})
</script>
</body>
</html>