删除Vue-cli预设
在用户根目录下(C:\Users\你的用户名)这个地址里有一个.vuerc 文件,修改或删除配置
组件
- Props(组件之间的数据传递)
- Prop 的大小写 (camelCase vs kebab-case)不敏感
- Prop 类型: String Number Boolean Array Object Date Function Symbol
- 传递静态或动态 Prop
- 单向数据流:只能父传子,不能子传父
- Prop 验证:
类型验证 空验证(是否允许为空) 默认值(缺省值)
注意:对象或数组默认值必须从一个工厂函数获取
- 自定义事件
子传父
.sync修饰符 - 插槽
- 插槽内容:tab切换
- 编译作用域:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。(动态数据写在哪里就在哪里声明)
- 后备内容(默认值,缺省值)
- 具名插槽
- 作用域插槽
- 解构插槽 Prop
- 具名插槽的缩写 v-slot: -> #
- 废弃了的语法(了解性知识)
- 动态组件 & 异步组件
- 动态组件:keep-alive
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。 - 异步组件:程序运行时不加载组件,什么时候组件被使用了,才会被加载
- 动态组件:keep-alive
- 处理边界情况
$root property $parent - Vue 实例
Vue是MVVM的模型,但是大家记住,他并不是完整的MVVM
M:Model
VM:ViewModel
V:View
MVC标准的设计模型,Angular
**实例生命周期钩子:生命周期函数会随着我们对程序理解越深,可参考价值越高 - 进入/离开 & 列表过渡
- 自定义指令
- 全局指令
- 局部指令
自定义指令存在三个钩子函数
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
- 渲染函数 & JSX
过滤器:商城平台,价格¥- 局部过滤器
- 全局过滤器
目录结构:
App.vue
<template>
<div id="app">
<!-- <MyComponent :title="num" :age="age" :banner="banner" demo="hello"></MyComponent> -->
<ul>
<li>hello</li>
<li>world</li>
</ul>
<hr>
<!-- <Parent /> -->
<hr>
<!-- <SlotParent /> -->
<hr>
<keep-alive include="Home">
<component v-bind:is="currentPage"></component>
</keep-alive>
<button @click="changeComponent">切换组件</button>
<hr>
<p>{{ $root.foo }}</p>
<p>{{ $root.getVue() }}</p>
<hr>
<!-- <ComponentInstance /> -->
<hr>
<!-- <AnimComponent /> -->
<hr>
<!-- <DirectiveComponent /> -->
<RenderComponent>
<h3>我是插槽</h3>
</RenderComponent>
<FilterComponent />
</div>
</template>
<script>
//引入各个组件
import MyComponent from "./components/MyComponent"
import Parent from "./components/group/Parent"
import SlotParent from "./components/slotComponents/SlotParent"
// import HomePage from "./components/pages/HomePage"
// 异步加载
const HomePage = () => import("./components/pages/HomePage");
import UserPage from "./components/pages/UserPage"
import ComponentInstance from "./components/ComponentInstance"
import AnimComponent from "./components/AnimComponent"
import DirectiveComponent from "./components/directiveComponent"
import RenderComponent from "./components/renderComponent"
import FilterComponent from "./components/fitlerComponent"
export default {
name: 'App',
data(){
return{
num:100,
age:"300",
banner:["导航","新闻"],
currentPage:UserPage,
flag:true
}
},
components: {
MyComponent,
Parent,
SlotParent,
HomePage,
UserPage,
ComponentInstance,
AnimComponent,
DirectiveComponent,
RenderComponent,
FilterComponent
},
methods:{
changeComponent(){
if(this.flag){
this.currentPage = HomePage
}else{
this.currentPage = UserPage
}
this.flag = !this.flag
}
}
}
</script>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
index.js
import Vue from "vue"
Vue.filter('rmb', (value) => {
// value就是{{}}或者v-bind绑定的值
if (value) {
return "¥" + value
}
})
focus.js文件
import Vue from "vue"
// 全局指令
Vue.directive("focus", {
inserted(el) {
el.focus(); // focus是js的获取input焦点的方法
}
})
Vue.directive('red',{
inserted(el){
el.style.color = '#ff0000'
}
})
AnimComponent.vue
<template>
<div>
<div>
<button @click="flag = !flag">切换</button>
<transition name="fade">
<p v-if="flag">HelloAnim</p>
</transition>
</div>
<div>
<button @click="flagAnim = !flagAnim">切换</button>
<transition
name="custom-classes-transition"
enter-active-class="animated rollIn"
leave-active-class="animated rollOut"
>
<p v-if="flagAnim">HelloAnim</p>
</transition>
</div>
</div>
</template>
<script>
export default {
name: "Anim",
data() {
return {
flag: true,
flagAnim: true
};
}
};
</script>
<style scoped>
.fade-enter,
.fade-leave-to {
opacity: 0;
font-size: 15px;
}
.fade-enter-to,
.fade-leave {
opacity: 1;
font-size: 30px;
}
.fade-enter-active,
.fade-leave-active {
transition: all 1s;
}
</style>
ComponentInstance.vue
<template>
<div>
<p>{{ msg }}</p>
<button @click="msg = '生命周期钩子函数重新渲染'">修改数据</button>
</div>
</template>
<script>
export default {
name: "Life",
data() {
return {
msg:"生命周期钩子函数"
};
},
beforeCreate() {
// 做初始化操作
console.log("组件创建之前:beforeCreate");
},
created() {
// 做初始化操作
console.log("组件创建之后:created");
},
beforeMount(){
// 判断组件渲染之前要做的额外事前
console.log("组件渲染之前:beforeMount");
},
mounted(){
// 网络请求
console.log("组件渲染之后:mounted");
},
beforeUpdate(){
console.log("数据更新之前:beforeUpdate");
},
updated(){
console.log("数据更新之后:updated");
},
beforeDestory(){
// 将组件中需要清除掉的在次函数中清除
// 定时器、持续事件、组件数据清空、清除未完成的网络请求
console.log("组件销毁之前:beforeDestory");
},
destoryed(){
console.log("组件销毁之后:destoryed");
}
};
</script>
directiveComponent.vue
<template>
<div>
自定义指令
<input v-focus type="text">
<p v-red>{{ msg }}</p>
<button @click=" msg = '嘿嘿嘿' ">修改</button>
</div>
</template>
<script>
export default {
name:"dir",
data(){
return{
msg:"哈哈哈哈"
}
},
// 局部指令,只能在当前组件中使用
directives:{
focus:{
inserted(el){
el.focus();
}
},
red:{
bind(el,binding,vnode,oldVnode){
console.log("初始化");
},
inserted(el,binding,vnode,oldVnode){
el.style.color = '#ff0000'
},
update(el,binding,vnode,oldVnode){
console.log("指令有更新的时候调用");
},
componentUpdated(el,binding,vnode,oldVnode){
console.log("指令有更新的时候调用!!");
},
unbind(el,binding,vnode,oldVnode){
console.log("解绑调用");
}
}
}
}
</script>
filterComponent.vue
<template>
<div>
filter过滤器:
<span>{{ money | rmb }}</span>
<p>{{ text | author | rmb}}</p>
</div>
</template>
<script>
export default {
data(){
return{
money:"101.00",
text:"喧闹任其喧闹,自由我自为知,我自风情万种,与世无争"
}
},
filters:{
author(value){
if(value){
return value +" ____ 陈果"
}
}
}
}
</script>
<style>
</style>
MyComponent.vue
<template>
<div>
MyComponent:{{ title }}:{{ age }}
<ul>
<li v-for="(item,index) in banner" :key="index">{{item }}</li>
</ul>
<p v-if="user">{{ user.username }}</p>
</div>
</template>
<script>
export default {
name:"MyComponent",
data(){
return{
}
},
// props:["title"]
props:{
title:{
type:Number
},
age:{
type:[Number,String],
default:1
},
banner:{
type:Array,
required:true
},
user:{
type:Object,
default:function(){
return{
username:"iwen"
}
}
}
}
}
</script>
<style lang="less" scoped>
li{
list-style: none;
}
</style>
renderComponent.vue
<script>
export default {
name:"RenderComponent",
data(){
return{
count:10,
username:''
}
},
methods:{
clicikHandle(){
this.count += 1
}
},
render(){
return(
<div>
Render函数:{ this.count }
<button onClick={ this.clicikHandle }>按钮</button>
<div>{ this.$slots.default }</div>
<input v-model={this.username} />
<p>{ this.username }</p>
</div>
)
}
}
</script>
作为引入的js
registerServiceWorker.js
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}
components/group/
Child.vue
<template>
<div>
Child
<input type="text" v-model="username" @keyup="changeHandle">
<p>{{ username }}</p>
<button @click="sendMsgHandle">发送数据</button>
<button @click="sendMsg2Handle">发送数据2</button>
</div>
</template>
<script>
export default {
name:"Child",
data(){
return{
msg:[1,2,3],
username:"",
msg2:"数据"
}
},
methods:{
sendMsgHandle(){
this.$emit('onEvent',this.msg)
},
changeHandle(){
this.$emit("myChange",this.username)
},
sendMsg2Handle(){
this.$emit("update:msg2Event",this.msg2)
}
}
}
</script>
components/group/
Parent.vue
<template>
<div>
Parent:{{ msg }}:{{ username }}:{{ msg2 }}
<!-- <Child @update:msg2Event="getMsg2Handle" @onEvent="getMsgHandle" @myChange="getChangeHandle"/> -->
<Child :msg2Event.sync="msg2" @onEvent="getMsgHandle" @myChange="getChangeHandle"/>
</div>
</template>
<script>
import Child from "./Child"
export default {
name:"Parent",
data(){
return{
msg:"",
username:"",
msg2:""
}
},
components:{
Child
},
methods:{
getMsgHandle(data){
this.msg = data
},
getChangeHandle(data){
this.username = data
},
getMsg2Handle(data){
console.log(data);
}
}
}
</script>
components/pages/
HomePage.vue
<template>
<div>
Home:{{ msg }}
<button @click="msg = '我是修改之后的数据'">修改数据</button>
</div>
</template>
<script>
export default {
name:"Home",
data(){
return{
msg:"我是修改之前的数据"
}
}
}
</script>
components/pages/
UserPage.vue
<template>
<div>
User:{{ msg }}
<button @click="msg = '哈哈哈哈'">修改数据</button>
</div>
</template>
<script>
export default {
name:"User",
data(){
return{
msg:"呵呵呵呵"
}
}
}
</script>
components/slotComponents/
SlotChild.vue
<template>
<div>
<slot :user="user"></slot>
<slot name="head" :msg="msg">我是默认值1</slot>
SlotChild
<slot name='foot'>我是默认值2</slot>
<p>{{ $parent.message }}</p>
</div>
</template>
<script>
export default {
name:"SlotChild",
data(){
return{
msg:"我是插槽数据",
user:{
name:"iwens"
}
}
}
}
</script>
components/slotComponents/
SlotParent.vue
<template>
<div>
SlotParent
<SlotChild>
<template v-slot:head="slotProps">
<h3>我是头部{{ demo }}:{{ slotProps.msg }}</h3>
</template>
<template #foot>
<h3>我是底部{{ demo }}</h3>
</template>
<template v-slot:default="{ user }">
<h3>哈哈哈:{{ user.name }}</h3>
</template>
<!-- <template slot="default" slot-scope="slotProps">
<h3>哈哈哈:{{ slotProps.user.name }}</h3>
</template> -->
</SlotChild>
</div>
</template>
<script>
import SlotChild from "./SlotChild";
export default {
name: "SlotParent",
data() {
return {
demo: "我是demo",
message:"我是SlotParent的数据!!"
};
},
components: {
SlotChild
}
};
</script>
运行效果图