vue 介绍
- 渐进式javascript框架
渐进式:主张最少
模块:数据请求:axios UI:elementUI 路由:vue-router状态层:vuex。。
- 优点
模块化友好 易用 灵活 高效 SPA 用户体验好
SPA :sing page application 单页面应用
1个url ——>1个html文件,多个html文件 多页面的应用:优点:利于SEO优化,缺点:白屏,用户体验不好
1个url ——>1个html文件,多个html文件 单页面的应用:优点:用户体验好 缺点:首屏加载慢,不利于SEO的优化
VUE缺点:
- 兼容性不好,首屏加载慢。不利于SEO优化
4.核心
数据驱动 组件系统
js 绑定事件 样式操作 event阻止默认事件 阻止冒泡事件。。
jq 获取节点 取值 赋值 样式 绑定事件 event阻止默认事件 阻止冒泡事件 ajax..
vue 获取节点 赋值 取值 绑定事件 event 阻止默认事件 阻止冒泡事件 ajax 自己的内容。。
节点赋值
-
非表单元素:div span等.. js:innerHTML jq:html()
-
表单元素: input textarea select-option.. js:value jq:val()
-
媒体元素:img video。 js:src jq:img.attr(src,1.jpg)
1.安装
官网:Vue.js
兼容性:vue不支持ie8及以下的版本
安装:
1.cdn
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
2.npm
npm install vue
3.vue脚手架 vue-cli :工作中使用的方式 5天
使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 1.安装 npm i vue -->
<!-- 2.引入 -->
<script src="./node_modules/vue/dist/vue.js"></script>
</head>
<body>
<!-- 3.控制范围 -->
<div>
{{1+1}}
</div>
<script>
// 4.实例化vue对象
new Vue({
//element
el:"div"
})
</script>
</body>
</html>
el挂载点
- 不能挂载到body html ,要 挂载到正常的元素上
- 一个vue实列只能挂载到一个节点上,所以一般情况使用id选择器
- 如果有多个元素都满足el的选择,vue实列挂载到满足条件的第一个节点上
data:先声明 后使用
new Vue({
el:"#app",//挂载点
data:{ //属性-变量
x:10,
arr:[]
},
methods:{//方法-函数
fn:function(){},
changeArr:function(){}
}
})
数据绑定 指令
1.非表单元素:div span …
{{}} 模板语法 优点:简单 方便 缺点:不能解析标签,首屏会出现闪屏问题
v-html 优点:可以解析标签 缺点:不方便
v-text 优点:可以解决首闪屏问题 缺点:不方便,不能解析标签
2.表单元素:input textarea
v-model
|
3.属性绑定:媒体元素:img video
v-bind简写 :
<a v-bind:href="company.url" v-bind:title="company.name">
<img v-bind:src="company.logo" alt="">
</a>
<a :href="company.url" :title="company.name" :a="10">
<img :src="company.logo" alt="">
</a>
4.条件渲染
相同点:
v-if 和v-show 都是true显示,false 消失
不同点:
v-if false 不加载节点-惰性加载
V-show false 加了display:none;
使用:
频繁切换,建议使用v-show,不频繁切换,建议使用v-if.
v-else 必须和它一对的v-if挨着
<h3 v-if="comment.length==0">暂无数据</h3>
<h3 v-else>有数据</h3>
5.列表渲染
<div v-for="(item,index) in arr">
</div>
1.for key
vue 的for更新的时候采用的是“就地更新”的原则,如果更新的时候想要提高更新的性能,我们就需要给vue一个标识,作为对比条件,这个标识必须是唯一的。所以一般用id
<ul>
<li v-for="(a,b) in people" :key="a.id">
<h3>{{b}}姓名:{{a.name}}</h3>
<p>金额:
{{a.money}} <button v-on:click="add(b)">++</button> </p>
</li>
</ul>
2.样式
-
动态行间样式
|
-
动态的类名
1.:class=”变量”
|
2.:class=”[三元]”
|
3.:class=”{class1:true,class2:false,…}
|
4.表单
- 1 定义变量为一个json,key和后端要求的字段保持一致;
- 2 所有表单元素通过v-model绑定数据
- 3 单选框 准备value:
<div>性别:
<input type="radio" name="sex" value="0" v-model="user.sex"> 男
<input type="radio" name="sex" value="1" v-model="user.sex"> 女
</div>
4 下拉菜单 option-value
<div>
专业:
<select v-model="user.job">
<option value="web">web工程师</option>
<option value="php">php工程师</option>
<option value="java">java工程师</option>
</select>
</div>
<div>
社团:
<select multiple v-model="user.org">
<option :value="1">篮球</option>
<option :value="2">足球</option>
<option :value="3">排球</option>
</select>
</div>
5 多选框:对于多选框来说,如果初始值是数组,那么结果就是数组;如果初始值不是数组,那么结果就是boolean
<div>爱好:
<input type="checkbox" v-model="user.hobbies" value="sing">唱歌
<input type="checkbox" v-model="user.hobbies" value="dancing">跳舞
<input type="checkbox" v-model="user.hobbies" value="codding">写代码
</div>
<div>
<input type="checkbox" v-model="user.isAgree">我同意
</div>
6 表单修饰符
<!-- .lazy 失去光标才修改模型数据,优化 -->
<input type="text" v-model.lazy="name">
<!-- .number 将绑定的数据 的数据类型转换为number -->
<input type="text" v-model.number="age" v-on:blur="blur()">
<!-- .trim 去空格 -->
<input type="text" v-model.trim="name">
5.事件绑定
-
1.如何绑定事件?
-
2.传参
-
3.event
-
4.阻止默认事件 阻止事件传播
-
5.本框架自带哪些事件特征
-
.prevent 阻止默认事件
.stop 阻止事件传播
.self 触发的目标元素是自身,才执行
.left .right .up .down .enter .13
.capture 捕获
.native native 解决组件绑定不上事件
1.生命周期
beforeCreate 创建之前:什么都是undefined
created 创建完成:vue实列数据初始化完成,el还是undefined
//如果有挂载点:了//如果有挂载点:el $mount()
beforeMount 挂载之前 :找到了要挂载的节点,但是{{}}、指令等等还没有被解析
mounted 挂载完成 *****
页面初始化完成。开启计时器、轮播图、ajax、操作DOM 节点、给window | docuemnt添加事件、
beforeUpdate 页面更新之前:不是数据变化之前,而是数据已经变了,页面重新渲染之前
updated 页面更新完成
// vm.$dstrory()
beforeDestroy 销毁之前:善后工作 ***
清除计时器、轮播图、window|document置空
destroyed 销毁完成
2.watch
目的:监听属性的改变
new Vue({
watch:{
kw(newV,oldV){
//逻辑
},
//深度监听不建议使用,因为会造成页面卡顿,如果要使用的话,建议转换成简单类型使用
json:{
handler(){
//逻辑
},
deep:true
}
}
})
sonp
ajax 不能跨域 get post
jsonp 可以跨域get
使用jsonp条件:1.跨域 2.有一个参数需要是回调函数,大部分情况下叫cb | callback
1.创建一个script标签
var os=document.createElement("script")
2.给他src
os.src="url"
3.插入到页面
document.body.appendChild(os)
4.回调函数中处理数据
3.filter
目的:转换数据
使用:| 管道符
<div>
{{price | filterPrice}}
</div>
定义:推荐全局定义
//全局定义
Vue.filter("过滤器名称",(过滤对象)=>{
//逻辑
return "你要的结果"
})
//局部定义
new Vue({
filters:{
//全局定义
过滤器名称(过滤对象){
//逻辑
return "你要的结果"
}
}
})
4.computed计算属性
计算属性:经过计算得到的属性
new Vue({
computed:{//计算属性
a(){
return 10
},
ava(){
var sum=0
this.students.forEach(item=>{
sum+=item.score
})
return (sum/this.students.length).toFixed(2);
}
}
})
5.vue常见的bug有哪些?怎么解决?
1.{{}}闪屏问题。 v-text解决
2.组件绑定事件绑定不上。 .native解决
3.watch深度监听卡顿。 换成简单类型,浅监听。
1.计算属性补充
1.v-for和v-if同时作用在一个标签上的时候,不合法。需要所使用的的计算属性解决。
2.如果出现数组变了,页面不渲染问题,采用下面3种方式结解决:
//1.this.goods.splice('下标',1,'新值')
this.goods.splice(index,1,obj)
//2.vm.$set(数组,下标,新值)
this.$set(this.goods,inds,obj)
//3.vue.set(数组,下标,新值)
vue.set(this.goods,indes,obj)
3.如果是json发生了改变,页面不渲染
//vm.set(obj,key,value)
this.$set(this.json,'y',30)
vue.set(this.json,'y',40)
2.动画
使用场景:
v-if
v-show
动态组件
路由
状态:
进来之前 enter
进来过程 enter-active
进来完成 enter-to
离开之前 leave
离开过程 leave-active
离开完成 leave-to
animate.css
1.官网:Animate.css | A cross-browser library of CSS animations.
2.安装
|
3.使用:
<link rel="stylesheet" href="./node_modules/animate.css/animate.css">
<transition
enter-active-class="animate__animated animate__flipInX"
leave-active-class="animate__animated animate__rotateOutDownRight"
>
<div class="box" v-if="isshow"></div>
</transition>
建议:
只写进来|离开的动画,如果都写了,太花里胡哨。一般情况下写进来。
3.组件
定义:
可复用的vue实列
目的:
重复调用
注册:推荐局部
1.全局注册:
Vue.component('组件名',{
//配置项
})
2.局部注册:
new Vue({
components:{
组件名:{
//配置项
}
}
})
组件命名
//1.不要以现有的标签命名 eg:div span
//2.不能以现有的标签的大写命名 eg Input Div
//3.如果组件名称中间包含了大写字母,调用改成 —小写 烤串写法
//4.建议组件取名的时候中间包含一个大写字母,方便调用
template
1.一个vue实列只能挂载到一个节点上,所以template只能有一个元素
2.借助template 标签来实现template 配置顶
data
1.data是一个返回对象的函数
2.组件希望模板是一样的,但是数据是隔离的。如果直接使用json,json引用类型,
一个变全都变
3.一个vue实例只能使用自己的data、methods、watch、filters、mounted、computed,components ....
4.脚手架
//安装webpack
npm i webpack -g
//安装vue的脚手架
npm i vue-cli -g
//创建项目
vue init webpack 项目名称
//进入项目
cd 创建的项目
//启动项目
npm run dev //http://localhost:8080
项目目录
- 项目
-build webpack所有配置
-config 启动配置文件
-node_modules 依赖包
-dist 打包生成的文件夹
-static 静态资源:reset.css 图片 rem.js
.babelrc ES6-》ES5
-editorconfig 编辑器配置文件
.gitignore 上传到github不用上传的文件
.postcssrc.js 处理css
index.html 页面
package.json 记录项目命令和依赖包
README.md 项目说明
-src 你的代码
main.js 入口文件
App.vue 根组件
件进阶
1.组件通信
-
父传子
父传子:父组件将要传递的数据通过自定义属性传递给子组件,子组件通过props、接收
<!--父组件-->
<v-child :a="name"></v-child>
//子组件
export default {
props:["a"]
}
扩展:
1.在子组件js使用父组件传递过来的数据,用this.age
2.对于一个组件来说,模板中可以使用的变量只能是自己的props data computed,能直接修改的只有data和computed
3.父组件传递过来的数据,子组间不允许修改,按标准来做,应该使用子传父,实现子组件修改父组件的数据
4.如果子组件直接修改父组件传递过来的值子变 父不变 还报错
5.父变,子变;子变,父变.可以传递json数据解决。
props验证
export default{
props:{
//约束传递过来的数据类型
type:Number,
//必传
required:ture
},
arr:{
//默认值
default(){
return['7','8','9']
}
}
}
2.子传父
目的:
子组件要修改父组件的值
在父组件上绑定自定义事件,子组件通过$emit()触发自定义事件,携带的参数,在event上
<!--父组件-->
<v-child2 @changwang='change' @change='changename('$event')></v-child2>
子组件
//子组件
export default {
methods:{
changeWang(){
//通知父组件 修改他自己的name
this.$emit("changewang")
},
change(name){
//通知父组件,把父组件的name改成功 name
this.$emit("change",name)
}
}
}
3.非父子传值
1.单一事件管理
//1. main.js
Vue.prototype.Event=new Vue();
//2.想要接受数据的组件,绑定自定义事件
mounted(){
this.Event.$on("sendA",(e)=>{
console.log(e);
this.a=e;
})
},
//3.触发事件
this.Event.$emit("sendA","王昭君")
2.vuex状态层
3.本地存储 localstorage sessionStorage
2.is
1.is 解决标签固定搭配问题
<ul>
<li is="v-one"></li>
</ul>
2.动态组件
<button @click="com='v-one'">one</button>
<button @click="com='v-two'">two</button>
<!--2. 动态组件 -->
<div :is="com"></div>
3.动态组件使用动画
1.安装
|
2.main.js引入
//引入animate.css
import "animate.css"
3.transition 嵌套
<button @click="obj='v-ui'">ui</button>
<button @click="obj='v-java'">java</button>
<transition
enter-active-class="animate__animated animate__rotateInDownLeft"
>
<div :is="obj"></div>
</transition>
slot插槽
目的:组件嵌套内容,不希望内容消失
1.匿名插槽
<!-------组件--------->
<div class="right">
<!-- 匿名插槽 -->
<slot></slot>
<v-one>
<div>天道酬勤</div>
</v-one>
<v-one>
<div>人道酬善</div>
<div>商道酬信</div>
</v-one>
<v-one></v-one>
4.scoped
样式局部作用,都要局部作用
<style scoped>
h2 {
color: red;
}
</style>
5.jquery
1.安装
|
2引入 挂到vue的原型链上
//main.js
import $ from "jquery"
Vue.prototype.$=$
3.使用 :注意在mounted之后使用
mounted() {
this.$("button").eq(0).click(()=> {
this.$(".red").slideDown(400);
});
this.$("button").eq(1).click(() => {
this.$(".red").slideUp(400);
});
},
6.ref
是vue安全访问DOM和子组件的句柄!
<template>
<div class="box">
<h1 ref="h1">ref</h1>
<button @click="getWidth">点击获取下面元素的宽度</button>
<!-- ref 访问了DOM -->
<div class="red" ref="red"></div>
<button @click="change">哈哈哈</button>
<!-- ref 访问子组件 -->
<v-child ref="child"></v-child>
</div>
</template>
<script>
import vChild from "./child"
export default {
components:{
vChild
},
methods: {
getWidth() {
console.log(this.$refs.red.clientWidth);
var div=this.$refs.red
div.innerHTML="哈哈哈"
div.style.background="red"
},
change(){
console.log(this.$refs.child);
this.$refs.child.change()
}
},
};
</script>
使用情景:
1.媒体元素
2.DOM属性:offsetLeft clientWidth scrollTop 、children
3.父组件要调用子组件的数据和方法
注意:ref必须在mounted之后