最近跟着vue相关视频学了些vue的基础知识,做此总结,以防遗忘。
1、引入vue.js:
2、创建Vue对象:
el : 指定根element(选择器,指定用vue来管理页面中的哪个标签区域)
data : 初始化数据
这是html代码:
<div id="app">
<p>{
{message}}p>
div>
这是js代码:
<script type="text/javascript">
//创建vue实例
const vm = new Vue({
//配置对象
// 配置选项
el:'#app',//element:选择器 指定用vue来管理页面中的哪个标签区域
data:{
//数据(model)
message:'Hello Vue'
}
})
</script>
MVVM指的是
model:模型,数据对象(data)
view:视图,模板页面
viewModel:视图模型(Vue的实例vm)
<div id="app">
<input type="text" v-model="username" />
<p>Hello {
{username}}p>
div>
const vm = new Vue({
el:'#app',
data:{
username:'Tom'
}
})
<div id="app">
<p>{
{msg}}p>
<p>{
{msg.toUpperCase()}}p>
div>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
msg:"I Will Back!",
}
})
</script>
{ {}}:即textContent,将元素当成纯文本输出。
v-text:即textContent,将元素当成纯文本输出。
v-html:即innerHTML,将元素当成HTML标签解析后输出。
<div id="app">
<p>{
{msg}}p>
<p v-text="msg">p>
<p v-html="msg">p>
div>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
msg:"I Will Back!"
}
})
</script>
<div id="app">
<img v-bind:src="imgUrl" />
<img :src="imgUrl" />
div>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
imgUrl:'https://cn.vuejs.org/images/logo.png'
}
})
</script>
<div id="app">
<button v-on:click="test">test1button>
<button @click="test2('aaa')">test2button>
div>
<script type="text/javascript">
new Vue({
el:"#app",
methods:{
test(){
alert('哈哈!');
},
test2(content){
alert(content);
}
}
})
</script>
<div id="demo">
姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
姓名1(单向): <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
div>
<script type="text/javascript">
const vm = new Vue({
el:"#demo",
data:{
firstName:"A",
lastName:"B"
},
computed:{
//什么时候执行:初始化显示/相关的data属性数据发生改变
fullName1(){
//计算属性中的一个方法,方法的返回值作为属性值
return this.firstName+' '+this.lastName
}
}
})
</script>
watch 和 $watch 都能实现监视。
如果想要实现上述 计算属性实例的效果,需要写两个 监视。如下实例:用了一个 watch ,一个 $watch。
<div id="demo">
姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
姓名2(单向): <input type="text" placeholder="Full Name2" v-model="fullName2"><br>
div>
<script type="text/javascript">
const vm = new Vue({
el:"#demo",
data:{
firstName:"A",
lastName:"B",
fullName2: 'A B'
},
watch:{
//配置监视
firstName:function(value){
//firstName发生了变化
console.log(this)//就是vm对象
this.fullName2 = value+' '+this.lastName
}
}
})
vm.$watch('lastName',function(value){
//更新fullName2
this.fullName2 = this.firstName+' '+value
})
</script>
计算属性高级:
通过getter/setter实现对属性数据的显示和监视。
计算属性存在缓存, 多次读取只执行一次getter计算。
<div id="demo">
姓: <input type="text" placeholder="First Name" v-model="firstName"><br>
名: <input type="text" placeholder="Last Name" v-model="lastName"><br>
姓名3(双向): <input type="text" placeholder="Full Name3" v-model="fullName3"><br>
div>
<script type="text/javascript">
const vm = new Vue({
el:"#demo",
data:{
firstName:"A",
lastName:"B"
},
computed:{
fullName3:{
//回调函数 计算并返回当前属性的值
//当获取当前属性值时自动调用, 将返回值(根据相关的其它属性数据)作为属性值
get(){
return this.firstName+' '+this.lastName
},
// 当属性值发生了改变时自动调用, 监视当前属性值变化, 同步更新相关的其它属性值
set(value){
const names = value.split(' ')
this.firstName = names[0]
this.lastName = names[1]
}
}
}
})
</script>
三种情况:
xxx是字符串
xxx是对象
xxx是数组
<div id="demo">
<h2>class绑定: :class='xxx'h2>
<p class="classC" :class="a">xxx是字符串p>
<p :class="{classA:isA,classB:isB}">xxx是对象p>
<p :class="['classA','classC']">xxx是数组p>
<button @click="update">更新button>
div>
.classA {
color: red;
}
.classB {
background: blue;
}
.classC {
font-size: 20px;
}
<script type="text/javascript">
new Vue({
el:'#demo',
data:{
a:'classA',
isA:true,
isB:false,
},
methods:{
update(){
this.a='classB',
this.isA=false,
this.isB=true
}
}
})
</script>
<div id="demo">
<p :style="{
color: activeColor, fontSize: fontSize + 'px' }">style绑定p>
<button @click="update">更新button>
div>
<script type="text/javascript">
new Vue({
el:'#demo',
data:{
activeColor:'red',
fontSize:20
},
methods:{
update(){
this.activeColor='green',
this.fontSize=30
}
}
})
</script>
1. 条件渲染指令
v-if:能确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。但如果在初始渲染时条件为假,则什么也不做,直到条件第一次变为真时,才会开始渲染。
v-else
v-show:不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
2. 比较v-if与v-show
如果需要频繁切换, v-show 较好
如果在运行时条件很少改变,则使用 v-if 较好。
<div id="demo">
<p v-if="ok">成功了p>
<p v-else>失败了p>
<p v-show="ok">表白成功p>
<p v-show="!ok">表白失败p>
<button @click="ok=!ok">切换button>
div>
<script type="text/javascript">
new Vue({
el:'#demo',
data:{
ok:true
}
})
</script>
vue重写了数组中的一系列改变数组内部数据的方法(先调用原生,再更新页面)————>数组内部改变,页面自动变化
<div id="demo">
<h2>v-for 遍历数组</h2>
<ul>
<li v-for="(p,index) in persons" :key="index">
{
{
index}}--{
{
p.name}}--{
{
p.age}}
---<button @click="deleteP(index)">删除</button>
---<button @click="updateP(index, {name:'Cat', age: 16})">更新</button>
</li>
</ul>
<h2>v-for 遍历对象</h2>
<ul>
<li v-for="(value,key) in persons[1]" :key="key">
{
{
value}}---{
{
key}}
</li>
</ul>
</div>
<script type="text/javascript">
//vue本身只是监视了persons的改变,没有监视数组内部数据的改变
//vue重写了数组中的一系列改变数组内部数据的方法(先调用原生,再更新页面)————>数组内部改变,页面自动变化
new Vue({
el:'#demo',
data:{
persons:[
{
name:'Tom',age:18},
{
name:'Jack',age:16},
{
name:'Bob',age:19},
{
name:'Rose',age:17}
]
},
methods:{
deleteP(index){
this.persons.splice(index, 1)
// 调用了不是原生数组的splice(), 而是一个变异(重写)方法
// 1. 调用原生的数组的对应方法
// 2. 更新界面
},
updateP (index, newP) {
console.log('updateP', index, newP)
this.persons.splice(index, 1, newP)
},
addP (newP) {
this.persons.push(newP)
}
}
})
</script>
看下面的示例,搜索是通过computed属性计算出新的数组,该数组通过filter对persons数组进行过滤得到。
排序是通过点击不同的按钮传递不同的orderType值进行判断,使用sort方法。
<div id="demo">
<input type="text" v-model="searchName">
<ul>
<li v-for="(p, index) in filterPersons" :key="index">
{
{index}}--{
{p.name}}--{
{p.age}}
li>
ul>
<div>
<button @click="setOrderType(1)">年龄升序button>
<button @click="setOrderType(2)">年龄降序button>
<button @click="setOrderType(0)">原本顺序button>
div>
div>
<script type="text/javascript">
const vm = new Vue({
el: '#demo',
data: {
searchName: '',
orderType: 0, // 0代表原本顺序, 1代表升序, 2代表降序
persons: [
{
name: 'Tom', age:18},
{
name: 'Jack', age:17},
{
name: 'Bob', age:19},
{
name: 'Mary', age:16}
]
},
computed: {
filterPersons () {
// 取出相关数据
const {
searchName, persons, orderType} = this;
//最终需要显示的数组
let fPersons;
// 对persons进行过滤
fPersons = persons.filter(p => p.name.indexOf(searchName)!== -1)
// 排序
if(orderType !== 0) {
fPersons.sort(function (p1, p2) {
if(orderType===2) {
// 降序
return p2.age-p1.age
} else {
// 升序
return p1.age-p2.age
}
})
}
return fPersons
}
},
methods: {
setOrderType (orderType) {
this.orderType = orderType
}
}
})
</script>
(1)v-on:xxx=“fun”
(2)@xxx=“fun”
(3)@xxx=“fun(参数)”
默认事件形参: event
隐含属性对象: $event
<div id="example">
<button @click="test1">test1button>
<button @click="test2('atguigu')">test2button>
<button @click="test3">test3button>
<button @click="test4('abcd', $event)">test4button>
div>
<script type="text/javascript">
new Vue({
el:'#example',
data:{
},
methods:{
test1 () {
alert('点击了')
},
test2 (msg) {
alert(msg)
},
test3(event) {
alert(event.target.innerHTML)
},
test4 (msg, event) {
alert(msg+'---'+event.target.textContent)
}
}
})
</script>
.prevent : 阻止事件的默认行为 event.preventDefault()
.stop : 停止事件冒泡 event.stopPropagation()
<div id="example">
<div style="width: 200px;height: 200px;background: red" @click="test5">
<div style="width: 100px;height: 100px;background: blue" @click.stop="test6">div>
div>
<a href="http://www.baidu.com" @click.prevent="test7">百度一下a>
div>
<script type="text/javascript">
new Vue({
el:'#example',
data:{
},
methods:{
test5 () {
alert('out')
},
test6 () {
alert('inner')
},
test7(){
alert('点击了');
}
}
})
</script>
可以自己试试,可以发现,事件的默认行为和冒泡行为全部被阻止了。
.keycode : 操作的是某个keycode值的健
.enter : 操作的是enter键,enter键的keycode值为13,以下以enter为示例。
<div id="example">
<input type="text" @keyup.13="test8">
<input type="text" @keyup.enter="test8">
div>
<script type="text/javascript">
new Vue({
el:'#example',
data:{
},
methods:{
test8(event){
alert(event.target.value+" "+event.keyCode)
}
}
})
</script>
使用v-model(双向数据绑定)自动收集数据
text/textarea
checkbox
radio
select
<div id="demo">
<form action="/xxx" @submit.prevent="handleSubmit">
<span>用户名: span>
<input type="text" v-model="username"><br>
<span>密码: span>
<input type="password" v-model="pwd"><br>
<span>性别: span>
<input type="radio" id="female" value="女" v-model="sex">
<label for="female">女label>
<input type="radio" id="male" value="男" v-model="sex">
<label for="male">男label>
<br>
<span>爱好: span>
<input type="checkbox" id="basket" value="basket" v-model="likes">
<label for="basket">篮球label>
<input type="checkbox" id="foot" value="foot" v-model="likes">
<label for="foot">足球label>
<input type="checkbox" id="pingpang" value="pingpang" v-model="likes">
<label for="pingpang">乒乓label>
<br>
<span>城市: span>
<select v-model="cityId">
<option value="">未选择option>
<option :value="city.id" v-for="(city, index) in allCitys" :key="city.id">{
{city.name}}option>
select>
<br>
<span>介绍: span>
<textarea rows="10" v-model="info">textarea><br><br>
<input type="submit" value="注册">
form>
div>
<script type="text/javascript">
new Vue({
el:'#demo',
data: {
username: '',
pwd: '',
sex: '男',
likes: ['foot'],
allCitys: [{
id: 1, name: 'BJ'}, {
id: 2, name: 'SS'}, {
id: 3, name: 'SZ'}],
cityId: '2',
info: ''
},
methods: {
handleSubmit () {
console.log(this.username, this.pwd, this.sex, this.likes, this.cityId, this.info)
alert('提交注册的ajax请求')
}
}
})
</script>
1. vue对象的生命周期
1). 初始化显示
* beforeCreate()
* created()
* beforeMount()
* mounted()
2). 更新状态
* beforeUpdate()
* updated()
3). 销毁vue实例: vm.$destory()
* beforeDestory()
* destoryed()
2. 常用的生命周期方法
created()/mounted(): 发送ajax请求, 启动定时器等异步任务
beforeDestory(): 做收尾工作, 如: 清除定时器
<div id="test">
<button @click="destroyVue">destory vuebutton>
<p v-if="isShow">尚硅谷IT教育p>
div>
<script type="text/javascript">
new Vue({
el: '#test',
data: {
isShow: true
},
beforeCreate() {
console.log('beforeCreate()')
},
created() {
console.log('created()')
},
beforeMount() {
console.log('beforeMount()')
},
mounted() {
// 初始化显示后立即调用
console.log('mounted()')
this.intervalId = setInterval(() => {
console.log('-----')
this.isShow = !this.isShow
}, 1000)
},
beforeUpdate() {
console.log('beforeUpdate()')
},
updated() {
console.log('updated()')
},
beforeDestroy() {
console.log('beforeDestroy()')
// 执行收尾的工作
clearInterval(this.intervalId)
},
destroyed() {
console.log('destroyed()')
},
methods: {
destroyVue() {
this.$destroy()
}
}
})
</script>
1. vue动画的理解
操作css的trasition或animation
vue会给目标元素添加/移除特定的class
2. 基本过渡动画的编码
1). 在目标元素外包裹
2). 定义class样式
1>. 指定过渡样式: transition
2>. 指定隐藏时的样式: opacity/其它
3. 过渡的类名
xxx-enter-active: 指定显示的transition
xxx-leave-active: 指定隐藏的transition
xxx-enter
<div id="demo">
<button @click="show = !show">Togglebutton>
<transition name="xxx">
<p v-show="show">hellop>
transition>
div>
/*指定过渡样式*/
.xxx-enter-active, .xxx-leave-active {
transition: opacity 1s
}
/*指定隐藏时的样式*/
.xxx-enter, .xxx-leave-to {
opacity: 0;
}
<script type="text/javascript">
new Vue({
el: '#demo',
data: {
show: true
}
})
</script>
<div id="demo2">
<button @click="show = !show">Toggle2button>
<transition name="move">
<p v-show="show">hellop>
transition>
div>
.move-enter-active {
transition: all 1s
}
.move-leave-active {
transition: all 3s
}
.move-enter, .move-leave-to {
opacity: 0;
transform: translateX(20px)
}
<script type="text/javascript">
new Vue({
el: '#demo2',
data: {
show: true
}
})
</script>
<div id="example-2">
<button @click="show = !show">Toggle showbutton>
<br>
<transition name="bounce">
<p v-if="show" style="display: inline-block">Loremp>
transition>
div>
在这里插入代码片
`.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
```javascript
1. 理解过滤器
功能: 对要显示的数据进行特定格式化后再显示
注意: 并没有改变原本的数据, 而是产生新的对应的数据
2. 编码
1). 定义过滤器
Vue.filter(filterName, function(value[,arg1,arg2,…]){
// 进行一定的数据处理
return newValue
})
2). 使用过滤器
{ {myData | filterName}}
{ {myData | filterName(arg)}}
<div id="test">
<h2>显示格式化的日期时间h2>
<p>{
{time}}p>
<p>最完整的: {
{time | dateString}}p>
<p>年月日: {
{time | dateString('YYYY-MM-DD')}}p>
<p>时分秒: {
{time | dateString('HH:mm:ss')}}p>
div>
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.22.1/moment.js"></script>
<script type="text/javascript">
// 定义过滤器
Vue.filter('dateString', function (value, format='YYYY-MM-DD HH:mm:ss') {
return moment(value).format(format);
})
new Vue({
el: '#test',
data: {
time: new Date()
},
mounted () {
setInterval(() => {
this.time = new Date()
}, 1000)
}
})
</script>
v:text : 更新元素的 textContent
v-html : 更新元素的 innerHTML
v-if : 如果为true, 当前标签才会输出到页面
v-else: 如果为false, 当前标签才会输出到页面
v-show : 通过控制display样式来控制显示/隐藏
v-for : 遍历数组/对象
v-on : 绑定事件监听, 一般简写为@
v-bind : 强制绑定解析表达式, 可以省略v-bind
v-model : 双向数据绑定
ref : 为某个元素注册一个唯一标识, vue对象通过$refs属性访问这个元素对象
v-cloak : 使用它防止闪现表达式, 与css配合: [v-cloak] { display: none }
<div id="example">
<p ref="msg">abcdp>
<button @click="hint">提示button>
<p v-cloak>{
{content}}p>
div>
[v-cloak] {
display: none }
<script type="text/javascript">
new Vue({
el: '#example',
data: {
content: '百度一下'
},
methods: {
hint () {
alert(this.$refs.msg.innerHTML)
}
}
})
</script>
1. 注册全局指令
Vue.directive(‘my-directive’, function(el, binding){
el.innerHTML = binding.value.toupperCase()
})
2. 注册局部指令
directives : {
‘my-directive’ : {
bind (el, binding) {
el.innerHTML = binding.value.toupperCase()
}
}
}
3. 使用指令
v-my-directive='xxx’
<div id="test1">
<p v-upper-text="msg">p>
<p v-lower-text="msg">p>
div>
<div id="test2">
<p v-upper-text="msg">p>
<p v-lower-text="msg">p>
div>
<script type="text/javascript">
// 注册一个全局指令
// el: 指令所在的标签对象
// binding: 包含指令相关信息数据的对象
Vue.directive('upper-text', function (el, binding) {
console.log(el, binding)
el.textContent = binding.value.toUpperCase()
})
new Vue({
el: '#test1',
data: {
msg: "I Like You"
},
// 注册局部指令
directives: {
'lower-text'(el, binding) {
console.log(el, binding)
el.textContent = binding.value.toLowerCase()
}
}
})
new Vue({
el: '#test2',
data: {
msg: "I Like You Too"
}
})
</script>
(function (window) {
//这里写入你的代码
//向外暴露
window.MyPlugin = MyPlugin
})(window)
<script type="text/javascript" src="vue-myPlugin.js"></script>
Vue.use(MyPlugin)
Vue.xxx()