前言
- VUE是前端用的最多的框架;
- 这篇文章是本人大一上学习前端的笔记;
- 欢迎点赞 + 收藏 + 关注,本人将会持续更新。
文章目录
-
-
- [3、使用Vue CLI脚手架](#3、使用Vue CLI脚手架)
-
- 3.1、初始化脚手架
- 3.2、ref属性
- 3.3、props配置项
- 3.4、mixin混合插入
- 3.5、plugin插件
- 3.6、scoped样式
- 组件化编码流程
- 3.8、WebStorage
- 3.9、自定义事件
- 3.10、全局事件总线
- 3.11、消息的订阅与发布
- [3.12、nextTick](#3.12、nextTick)
- 3.14、过渡与动画
-
3、使用Vue CLI脚手架
3.1、初始化脚手架
看课件
3.1.1、分析脚手架结构
html
.文件目录
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ └── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
└── package-lock.json: 包版本控制文件
src/components/School.vue
:
html
<template>
<div id='Demo'>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
</template>
<script>
export default {
name:'School',
data() {
return {
name:'尚硅谷',
address:'北京'
}
},
methods: {
showName() {
alert(this.name)
}
},
}
</script>
<style>
#Demo{
background: orange;
}
</style>
src/components/Student.vue
:
html
<template>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:'JOJO',
age:20
}
},
}
</script>
src/App.vue
:
html
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {
name:'App',
components:{
School,
Student
}
}
</script>
src/main.js
:
html
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
el:'#app',
render: h => h(App),
})
public/index.html
:
html
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<!-- 针对IE浏览器的特殊配置,含义是让IE浏览器以最高渲染级别渲染页面 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 开启移动端的理想端口 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 配置页签图标 -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 配置网页标题 -->
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<!-- 容器 -->
<div id="app"></div>
</body>
</html>
3.1.2、render函数
htmlimport
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
el:'#app',
// 简写形式
render: h => h(App),
// 完整形式
// render(createElement){
// return createElement(App)
// }
})
3.1.2、修该默认配置
- 使用vue.config.js可以对脚手架进行个性化定制
js
module.exports = {
//关闭语法检测
lineOnSave: false
}
3.2、ref属性
html
<template>
<div>
<h1 ref="title">{{msg}}</h1>
<School ref="sch" />
<button @clivk="show" ref="btn">输出ref</button>
</div>
</template>
<script>
import School from '......'
export default {
name: 'App',
concompents: {
School
}
data() {
return {
msg: '欢迎学习Vue'
}
},
methods: {
show() {
console.log(this.$ref.title)
console.log(this.$ref.sch)
console.log(this.$ref.btn)
}
}
}
</script>
- 使用方法:
- 打标识:
<h1 ref="xxx"></h1>
或<School ref="xxx"></School>
- 使用:this.$refs.xxx
- 打标识:
3.3、props配置项
src/components/Student.vue
:(子)
html
<template>
<div>
<h1>{{msg}}</h1>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
</template>
<script>
export default {
name: 'Student',
data() {
return {
msg: "i come from GuangDong",
}
},
//简单接受声明:
//props:['name','age','sex']
//接受的同时对数据进行类型限制
props: {
name: String,
age: Number,
sex: String
}
//接收的同时对数据进行类型限制 + 指定默认值 + 限制必要值
props:{
name: {
tyep: String,
required: true,
},
age: {
tyep: String,
required: true,
},
sex: {
tyep: String,
required:true
}
}
}
</script>
src/App.vue
:(父)
html
<template>
<div>
<Student name='wy' sex='man' :age='18+1'></Student>
</div>
</template>
<script>
import Student from '......'
export default {
name: 'App',
compoents: {Student},
}
</script>
总结:
- 功能:让组件接收外部传过来的数据
- 接受数据:
- 第一种方式(只接受):props:['name']
- 第二种方式(限制数据类型): props:{name:String}
- 第三种方式(限制类型、限制必要性、指定默认值):
html
<script>
props: {
name: {
type: String, //类型
required: true, //必要性
default: 'JOJO' //默认值
}
}
</script>
**注意:**required不能和default一起混用
3.4、mixin混合插入
功能:把多个组件共用配置提取成一个混入对象
使用方式:
-
定义混入
jsconst minxi = { data(){......}, methods:{......} ...... }
-
使用混入
- 全局混入:Vue.minxi(xxx)
- 局部混入:mixins:['xxx'] (注意加了s)
src/mixin.js
:
js
export default mixin = {
methods: {
show() {
alert(this.name)
}
},
mounted() {
console.log("hello")
}
}
src/components/School.vue
html
<template>
<div>
<h2 @click="show">学校姓名:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
//引入混入**注意写法**
import {mixin} from '......'
export default {
name: 'School',
data() {
return() {
name: 'School',
adress: 'beijing'
}
},
mixin:[mixin]
}
</script>
src/components/Student.vue
html
<template>
<div>
<h2 @click=show>学校姓名:{{name}} </h2>
<h2>学生性别:{{sex}} </h2>
</div>
</template>
<script>
//引入mixin
import {mixin} from '......'
export default {
name: 'Student',
data() {
return {
name: 'wy',
sex: 'man'
}
},
mixins:[mixin]
}
</script>
src/App.vue
:
html
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
import Student from '......'
import School from '......'
export default {
name: 'App',
components: {
School,
Student
}
}
</script>
全局混入:
js
import Vue from 'vue'
import App from './App.vue'
import {mixin} from './mixin'
Vue.config.productionTip = false
Vue.mixin(mixin)
new Vue({
el:"#app",
render: h => h(App)
})
注意 注意 注意:组件和混入对象含有同名选项时,这些选项将以恰当的方式进行"合并",在发生冲突时以组件优先。
3.5、plugin插件
功能:插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制。用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用则传递的数据
使用插件:Vue.use(plugin)
定义插件:
js
plugin.install = function(Vue,options) {
//1.添加过滤器
Vue.filter(......)
//2.添加全局指令
Vue.directiove(......)
//3.配置全局混入
Vue.mixin(......)
//4.添加实例方法
Vue.prototype.$myMethod = function() {......}
Vue.prototype.$myProperty = xxx
}
src/plugin.js
:
js
export default {
install(Vue,x,y,z) {
console.log(x,y,z)
//全局过滤器
Vue.filter('mySlice',function(value){
return value.slice(0,4)
})
//定义混入
Vue.mixin({
data() {
return{
x: 100,
y: 200
}
},
//给vue原型上添加一个方法
Vue.protitype.hello = () => alert('hello')
})
}
}
src/main.js
:
js
import Vue from 'vue'
import App from './App.vue'
import plugin from './plugin'
Vue.config.productionTip = false
Vue.use(plugin,1,2,3)
new Vue({
el:"#app",
render: h => h(App)
})
src/components/School.vue
:
vue
<template>
<div>
<h2>学校姓名:{{name | mySlice}}</h2>
<h2>学校地址:{{adress}}</h2>
</div>
</template>
<script>
export default {
name: 'School',
data() {
return {
name: '尚硅谷',
adress: 'beijing'
}
}
}
</script>
src/components/Student.vue
:
vue
<template>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click="text">测试</button>
</div>
</template>
<script>
export default {
name: 'Student',
data() {
return {
name: 'wqy',
sex: 'man'
}
},
methods: {
text() {
this.hello();
}
}
}
</script>
3.6、scoped样式
作用:让样式在局部生效,防止冲突
写法:
组件化编码流程
- 拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突
- 实现动态组件:考虑好数据的存放位置(一些组件放到他们自身,一些组件放到他们父元素)
- 实现交互:从绑定事件开始
注意:使用v-model时要切记:v-model绑定的值是props传过来的值,因为props是不可以修改的
3.8、WebStorage
相关知识点:
xxxStorage.setItem('key', 'value')
:该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值xxxStorage.getItem('key')
:该方法接受一个键名作为参数,返回键名对应的值xxxStorage.removeItem('key')
:该方法接受一个键名作为参数,并把该键名从存储中删除xxxStorage.clear()
:该方法会清空存储中的所有数据
注意:SessionStorage存储的内容会随着浏览器窗口关闭而消失
html
<body>
<h2>localStorage</h2>
<button onclick="saveDate()">保存数据</button> <br>
<button onclick="readDate">读取数据</button> <br>
<button onclick="deleteDate">删次数据</button> <br>
<button onclick="deleteAllDate">清空数据</button> <br>
</body>
<script>
let person = {name:"wqy",age:20}
function saveDate() {
localStorage.setItem('msg','localStorage')
localStorage.setItem('person',JSON.stringify(person))
}
function readDate(){
console.log(localStorage.getItem('msg'))
const person = localStorage.getItem('person')
console.log(JSON.parse(person))
}
function deleteDate(){
localStorage.removeItem('msg')
localStorage.removeItem('person')
}
function deleteAllDate(){
localStorage.clear()
}
</script>
3.9、自定义事件
总结:
-
一种组件通信的方式,适用于:==子组件 > 父组件
-
使用场景:A是父组件,B是子组件,那么就要在A中给B绑定自定义事件(事件的回调在A中)
-
绑定自定义事件:
第一种方式,在父组件中:<Demo @atguigu="test"/> 或
第二种方式:
html<Demo ref="demo"/> ... mounted(){ this.$refs.demo.$on('atguigu',data) }
- 触发自定义事件:
this.$emit('atguigu',数据)
- 解绑自定义事件:
this.$off('atguigu')
- 通过
this.$refs.xxx.$on('atguigu',回调)
绑定自定义事件时
3.9.1、绑定
src/App.vue
:
vue
<template>
<div class="app">
<-->通过父组件给子组件绑定一个自定义事件实现子给父传递数据 </-->
<Student @wqy="getStudentName" />
</div>
</template>
<script>
import Student from '......'
export default {
name: 'App',
compoemnts: {Student},
methods: {
getSchoolName(name){
console.log("已收到学校的名称:"+name)
},
},
mounted() {
this.$refs.student.$on('wqy',this.getStudent)
}
}
</script>
src/components/Student.vue
:
vue
<tempalte>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click="sendStudentName">传送学生姓名</button>
</div>
</tempalte>
<script>
export default {
name: 'student',
data() {
return {
name: 'wqy',
sex: 'man'
}
},
methods: {
sendStudentName() {
this.$emit('wqy',this.name)
}
}
}
</script>
3.10、全局事件总线
- 所有的组件对象都必须能看见他
- 这个对象必须能够使用
$on
、$emit
和$off
方法去绑定、触发和解绑事件
src/main.js
:
javascript
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#root',
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线
}
})
src/App.vue
:
vue
<template>
<div>
<School/>
<Student />
</div>
</template>
<script>
import Student from './components/Student'
import School from './components/School'
export default {
name:'App',
components:{School,Student}
}
</script>
src/components/School.vue
:
vue
<template>
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default {
name: 'School',
data() {
retrun {
name: 'cy',
address: 'hy'
}
},
methods: {
demo(data) {
console.log('School组件,收到了数据',data)
}
},
mounted() {
this.$bus.$on('demo',this.demo)
},
bedoreDestroy() {
this.$bus.$off('demo')
}
}
</script>
src/components/Student.vue
:
vue
<template>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click='sendStudentName'>把学生名给School组件</button>
</div>
</template>
<script>
export default {
data() {
return {
name: 'wy',
sex:'man'
}
},
methods: {
sendStudentName() {
this.$bus.$emit('demo',this.name)
}
}
}
</script>
总结:
全局事件总线:
- 一种组件的通信方式,适用于任意组件通信
安装全局事件总线:
vue
new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this
}
})
- 使用事件总线:
- 接受数据:A组件接收数据,则在A组件中给$bus绑定自定义事件,
vue
export default {
methods(){
demo(data){...}
}
...
mounted() {
this.$bus.$on('xxx',this.demo)
}
}
- 接受数据:this. b u s . bus. bus.emit('xxx',data)
- 最好在
beforeDestroy
钩子中,用$off
去解绑当前组件所用到的事件
3.11、消息的订阅与发布
功能:消息订阅与发布是一种组件间通信方式,适用于任意组件间的通信
使用步骤:
-
安装pubsub:npm i pubsub-js
-
引入:import pubsub from 'pubsub-js'
-
接受数据:A组件想要接受数据,则在A组件中订阅消息,订阅的回调留在A组件自身
jsexport default { methods() { deom(daat) {......} }, ...... mounted() { this.pid = pubsub.subscribe('xxx',this.demo) } }
-
提供数据:pubsub.publish('xxx',data)
-
最好在
beforeDestroy
钩子中,使用pubsub.unsubscribe(pid)
取消订阅
src/components/School.vue
:
vue
<template>
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
import pubsub from 'pubsun-js'
export default {
name:'School',
data() {
return {
name: 'cy',
address: 'hy'
}
},
methods: {
demo(msgName,data) {
console.log('我是School组件,收到数据',this.demo)
}
},
mounted() {
this.pubId = pubsub.subscribe('demo',this.demo) //订阅消息
},
beforeDestroy() {
pubsub.unsubscribr(this.demo) //取消订阅
}
}
</script>
src/components/Student.vue
:
vue
<tempalte>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click="sendStudentNmae">把学生给School组件</button>
</div>
</tempalte>
<script>
import pubsub from 'pubsub-js'
export default {
name: 'Student',
data() {
return {
}
},
methods: {
sendStundenName() {
pubsub.publish('demo',this.name) //发布消息
}
}
}
</script>
3.12、$nextTick
$nextTick(回调函数)
可以将回调延迟到下次 DOM 更新循环之后执行
语法:this.$nextTick(回调函数)
作用:在下一次DOM更新结束后执行其指定的回调
3.14、过渡与动画
-
作用:在插入、更新或移除DOM元素,在合适的时候给元素添加样式类名
-
写法:
-
准备好样式:
- 元素进入的样式:
v-enter
:进入的起点v-enter-active:进入过程中
v-leave-to
:进入的终点
- 元素离开的样式:
v-leave
:离开的起点v-leave-active:离开过程中
v-leave-to
:离开的终点
- 元素进入的样式:
-
使用包裹要过度的元素,并配置name属性
html<transition name="hello"> <h1 v-show="isShow">你好!</h1> </transition>
-
备注: 若有多个元素需要过度,则需要使用:,且每个元素都要指定key值
-
``src/components/MyTransitionGroup.vue`:
vue
<template>
<div>
<button @click="isShow = !isShow">显示/隐藏 </button>
<transition name="joio">
<h1 v-show="isShow" key="1">hello </h1>
<h1 v-show="!isShow" key="2">pig!</h1>
</transition>
</div>
</template>
<script>
export default {
name: 'MyTitle',
data() {
return {
isShow = true
}
}
}
</script>
<style>
h1 {
background-color: orange;
}
.join-enter,.joio-leave-to {
transform: translate(-100%)
}
.join-enter-to,.joid-leave {
tansform: translate(0);
}
.joio-enter-active,.joio-leave-active{
transition: 0.52s linear
}
</style>