vue基础知识

 

什么是vue?

单页面应用框架,数据驱动视图,数据实现双向绑定
 

vue的数据流是什么?

单向数据流
 

vue语法

    {{}}  小胡子语法(mustache语法):将vue实例上的数据绑定在dom上
作用:
             1.解析变量
            2.js运算
            3.使用js对象的方法
 

vue的指令有哪些?

    指令:带有v-开头的特殊属性,主要用来操作DOM
 
1 v-text:v-text = "值",值需要在数据中声明,作用类似于{{}}语法,给DOM元素添加一些字符
2 v-html:v-html = "值",值需要在数据中声明
 *  区别: v-text:可以解析文本  
v-html:可以解析html元素
 
3 v-show:v-show="表达式",根据表达式的真假值控制元素的显示与隐藏
                    v-show="false"时会给元素添加一个display:none的属性
 
 4 v-if:v-if="表达式",根据表达式的真假值控制元素是否存在
                   v-if="false"时,dom元素不存在
        重点:v-if与v-show的区别:
             v-show 控制元素的display样式
             v-if    控制DOM元素的删除与添加
             频繁切换使用v-show,使用v-if浪费性能
 
5 v-else: 不能单独使用,必须跟在v-if或者v-else-if后面
6 v-else-if:不可单独使用,必须放在v-if或者v-else-if后面
        js中的if(){}else if(){}else{}
 
7 v-for:遍历数组或者对象,
问题:v-for 中除了 in 还有那种写法?of
              遍历数组:v-for="(item,index) in arr"  前面是两个变量,分别是属性值,下标
              遍历对象:v-for="(value,key,index) in obj" 前面是三个变量,分别是属性值,属性名,下标
 
    
8 v-on:绑定事件
       语法:v-on:不带on的事件名称(click) = "函数名"
简写:@事件名称="函数名"
                函数名一定要在methods里面声明,methods是挂载方法的
 
              如果需要传参 v-on:不带on的事件名称(click) = 函数名(param1,param2.....),通过函数接收
 
9 v-model:v-model="自定义名"
只能给表单元素绑定指令,不能绑定普通元素,
表单元素会忽略value属性,把vue实例上的数据作为数据的初始来源
 
10.v-slot:插槽,配合 template 使用
 
11 v-bind:给元素或者组件动态绑定一个或多个属性
         语法:v-bind:属性名=值
         简写::属性名=值
         当前this:在实例中this指向当前vm实例,在组件中this指向当前组件
        
         v-bind:class
         1.绑定字符串:<div :class="isClass"></div>
         2.绑定对象:<div :class="{red: isRed}"></div>
            red为key,key是类名,isRed是布尔值,这个布尔值决定是否绑定key
         3.绑定数组:<div :class="[classA,classB]"></div>
             数组中的每一项都是类名,需要在data中初始化
         4.数组与对象的组合:<div :class="[classA,{classB:isB,classC:isC}]">
 
         v-bind:style:动态绑定样式
             :style="{width:sWidth+'px',height:sHeight+'px',background:sColor}"
 
         另一种方式,自定义:
         <div v-bind="{id:'aaa','other-attr':'otherProp'}">
 
v-bind:title 鼠标悬停几秒钟查看此处动态绑定的提示信息
 
 
 修饰符:写在事件名称后面  用.表示
                    事件修饰符:
                         @click.prevent: 阻止默认事件
                         @click.stop:取消冒泡
@click.once:只触发一次回调
@click.left :点击鼠标左键时触发
@click.right :点击鼠标右键时触发
@click.middle:点击鼠标中键时
 
键盘修饰符:
@keyup.13 == @keyup.enter
@keyup.esc
 
 

自定义指令

自定义指令定义方法:
全局定义:Vue.directive("名字",{关于对象的钩子和逻辑})
                钩子函数:
                    1.bind:在绑定元素初始渲染时执行
                    2.inserted:在DOM元素插入到页面时执行
                    3.update:在更新时候执行的函数
                钩子的参数:
                    1.el:绑定的DOM元素
                    2.binding
Vue.directive("color",{     inserted(el){     el.style.color = "red";     } }) 自定义指令使input自动聚焦 Vue.directive('focus',{     inserted(el){       el.focus() } })
 
局部定义:在配置对象中写directives{"名字":{关于对象的钩子和逻辑}}
var vm = new Vue({
     el:"#app",
     directives:{
'focus':{
inserted(el,binding){
// 从binding下面获取是否存在修饰符
var sColor = binding.modifiers.color
if(sColor){
var value = binding.value
console.log(value)
el.style.boxShadow = `1px 1px 1px 1px ${value}`
}
el.focus()
}
},
}
})

 

注意:名字定义时不加v-,在使用时加上v-
 

组件缓存

keep-alive 缓存组件运行状态
keep-alive没有任何属性,缓存组件所有包含的组件状态,
    include:用来匹配要缓存的组件,
    exclude:排除不要缓存的组件 
    max:指定缓存组件的个数
 

动态加载组件

使用内置组件component,用is属性动态加载组件
```html <template>   <component is="home" /> </template> ``` ```js   import home from"./home"   export default = {     components:{       home     }   } ```
 
 

vue的计算属性

computed,与el,data,methods同级
        属性名--函数名   
  属性值--函数的返回值
        依赖普通属性(data中的数据),计算属性也会被挂载到当前实例上,也可使用{{}}
        函数与计算属性的区别:
           用函数去实现每次得到返回结果都会执行函数,计算属性只会执行一次,然后把结果存在缓存中,以后使用会从缓存中直接获取,不再执行逻辑,提高性能
 

computed:计算属性 与 watch:监听 区别

- computed:计算属性有缓存,所以监听的数据发生改变时,会对比缓存值,若新值与旧值一致,则不会触发更新
- watch:监听无缓存,只要被监听的数据发生了变化就会被执行
- computed 监听一个数据还要返回一个数据,但是 watch 只是监听
 

监听属性

监听属性:watch  监听数据的变化
msg(newVal,oldVal){}
监听的数据写成函数,新值与旧值作为函数的参数
 
对象在每一个属性都有一个setter/getter
分别演化成:
setter:set(){}:set函数在属性值发生变化之后执行
         set(){
             return value
         }
 getter:get(){}:get函数在获取属性的时候执行

 

深度监听
vue在运行时,对于非基本数据类型只会监听引用,添加deep:true,会给每一层数据绑定一个监听器,如果有一个值变化都会做出响应
watch:{
     msg(newVal,oldVal){
        console.log("我是新值"+newVal)
        console.log("我是旧值"+oldVal)     },
     "obj.a.b":{
             // 处理函数handler(固定)
          handler:function(newVal,oldVal){
            console.log("我是新值"+newVal)
            console.log("我是旧值"+oldVal)
          },
         deep:true,//深度监听
  } }

 

vue 组件实例组成部分

name:组件名称
data:数据
components:局部注册组件
computed:计算属性
watch:监听
methods:方法的集合
filter:自定义过滤函数
directive:自定义指令
mixins:混入,我们将公共的一些实例上的配置做成一个单独的 mixins 文件,
引入进来后,和我们实例上的配置做一个合并,说白了就是给组件功能的扩展
生命周期
 

defineProperty

Object.defineProperty(obj,attr,desc):该方法接收三个参数
        参数:
            obj:要修改或定义属性的对象
            attr:要修改或者新增的属性名
            desc:描述符(对象){}
                (1)、属性描述符:
                        value:描述属性值
                        writable:描述属性是否可以被修改 
布尔值,若为true表示可修改,为false表示不可修改
                        enumerable:描述属性是否可以被枚举(for in 遍历)  
                            布尔值 true:可以被枚举   false:不可以被枚举
                        configurable:描述属性是否可以被删除
                            布尔值:true:可以被删除  false:不可以被删除
         (2)、存取器描述符 setter和getter
                     get(){
                         获取属性时执行
                     }
                     set(){
                         属性值发生变化时执行
                     }
注意:存储器描述符不能和value、writable同时使用
 

挂载元素的方法

    1.$el
    2.调用实例的方法:$mount("#app")
 

style的作用域

默认全局,在style上加scoped使css只在当前组件生效
 

递归组件

一个组件接受父组件传递过来的数据,进行自我调用,必须有结束条件和name属性
 

MVC与MVVM

MVC:单向
        M:Model 模型,     数据层
        V:View  用户界面   视图层
        C:controller  控制器  大量的逻辑都放在controller里面
 
MVVM:一种模式或思想,vue框架的思想符合mvvm模式,双向
        M:Model 模型,     数据层
        V:View  用户界面   视图层
        VM:实例化的vue对象  
        vm:处理数据,不关心处理数据的过程,只关心数据的变化
 

生命周期

生命周期钩子:vue实例从创建、运行到销毁,伴随着一些事件,这些事件叫生命周期钩子,也叫生命周期函数
 
8个周期:
beforeCreate:在实例创建之前运行,el还没有挂载到DOM,实例上的数据、方法还未初始化
    $el:实例上的属性,挂载元素
             $data:实例上的属性,数据属性
             $mount():实例上的方法,把实例挂载到DOM上 多
created:实例创建完成,数据和方法已经被初始化,vue实例还未挂载到DOM上($el未找到) 多
 
beforeMount:实例挂载到DOM之前执行的函数,此时的DOM是虚拟的还不能使用
mounted:实例挂载DOM完成,DOM已经渲染完成,可以对DOM进行操作
    做Ajax请求
 
beforeUpdate:数据更新前执行的函数
updated:数据更新完成执行的函数,更新数据时执行
 
beforeDestroy:实例销毁之前执行的钩子,清除定时器和轮询接口
destroyed:销毁成功以后执行的钩子
 
 

数据双向绑定(核心底层封装)

2.x原理:Object.defineProperty
3.x原理:es6的proxy封装
 
拦截对象的属性,使用Object.defineProperty把每个属性转成setter和getter的形式,当属性值变化时执行setter,通知vue把数据重新渲染到页面
  var obj = {
         str:"hello",
         num:11111,
         a:{
             b:45
         }
     }
     function render(){
         console.log("数据变化了,该重新渲染到页面了")
     }
     // 定义一个观察者
     function observer(obj){
         // 容错处理
         if(typeof obj !== 'object' || obj == null){
             return obj
         }
         // 遍历对象,把对象每个属性添加一个监听
         for(let attr in obj){
             // 把每个属性转成getter和setter
             // obj:监听对象  attr:监听属性  obj[attr]:监听的值
defineReactive(obj,attr,obj[attr])
} } observer(obj) function defineReactive(data,key,value){ Object.defineProperty(data,key,{ get(){ // 获取属性时执行 return value }, set(newVal,oldVal){ // 监听到属性值发生变化时执行 render() value = newVal } }) }

 

 

组件

一个组件模板只能有一个根元素
 钩子函数与template同级
 

1.什么是组件?

    页面中可以复用的局部功能界面
 

2.组件化开发的好处

            2.1.协同开发
            2.2.可以复用
            2.3.便于维护
 

3.组件的组成部分

    html结构 css样式 数据 逻辑
 

4.创建组件

     a.全局注册 
                Vue.component("组件名称",{关于组件的配置})
                组件名称命名:
                    1.pascal命名法:MyComponentName
                    2.烤串命名法:a-b-c 必须小写
Vue.component("my-component", {
    //定义组件模板-
    template: `
       <div>
          <h3>我是组件</h3>
          <button @click="show">组件按钮</button>
          <custome-component></custome-component>
     </div>
  `
 })

 

     b.局部注册,在components配置项里面写
               
 components:{
       "组件名称":{
           组件配置
        },
components:{}
                }
 components: {
'custome-component': {
template: `
<div>
<h3>我是局部注册的组件</h3>
<child-component></child-component>
</div>
`,
data() {
return {
msg: "我是局部注册数据"
}
},
components: {
"child-component": {
template:
`<div>孙子组件</div>`
}
}
} }

 

 
5.使用组件
     把组件名称当作一个自定义的元素放在想放的位置
 
6.关于组件中data的问题
    组件中的data必须是一个函数,不能写成{}的形式,
组件中的数据可以复用,都要返回自己独立的拷贝,当修改一个组件的数据,其他组件数据不会被修改,
 
7.组件的this指向当前组件,在组件上声明的方法和属性都挂载到当前组件上
 
内置组件
 
<template>
   <div>
     <h3>内置组件</h3>
<p>1.component</p>
<!-- component组件必须给一个:is属性。这个属性是用来加载组件的 -->
<!-- 动态加载组件 -->
<button @click="name='z'">显示组件1</button>
<button @click="name='x'">显示组件2</button>
<button @click="name='y'">显示组件3</button>
<p>2.keep-alive 缓存组件运行状态</p>
<!-- keep-alive没有任何属性,缓存组件所有包含的组件状态,
include:用来匹配要缓存的组件,
exclude:排除不要缓存的组件
max:指定缓存组件的个数
-->
<keep-alive exclude="z">
<component :is="name" />
</keep-alive>
</div>
</template>
<script>
import Com1 from '../components/neizhi/com1'
import Com2 from '../components/neizhi/com2'
import Com3 from '../components/neizhi/com3'
export default {
components: {
z: Com1,
x: Com2,
y: Com3
},
data() {
return {
name: 'z'
}
}
}
</script>

 

 

通信方法

1、父组件向子组件传递数据

    父组件使用v-bind动态绑定数据
        绑定语法:v-bind:自定义属性名 = value(要传递给子组件的数据)
    子组件接收:子组件通过props接收父组件传递过来的数据
        接收方式:
                1.props:['自定义属性名'] 该值是父组件传递过来的数据
                2.props:{
key(要接收的数据):{ type:String    定义接收的数据类型,type:[String,Number] 验证, 防止他人修改 default:value 定义默认值,如果父组件传值则使用父组件的值默认值不生效, 如果没传可自己设置默认值,如果默认值不是基本数据类型要写出函数返回的形式 default:function(){ return { msg:100 } } required:布尔值   true:必传,default失效  false:不必传 } }                 

2、子组件向父组件传递数据

     子组件使用$emit()向上广播事件
         $emit('自定义事件名'(必填),value(可选))
     父组件监听自定义事件,使用v-on:"自定义事件名"="函数名"
<div id="app">
 <parent-com :num = "num" @change-num='receive'></parent-com>
</div> var vm = new Vue({
el:"#app",
data:{
num:1
},
methods:{
receive(newNum){
this.num = newNum
}
},
components:{
'parent-com':{
template:
`<div>
<p>我是父级组件:{{num}}</p>
<button @click="change">修改父级数据</button>
</div>`,
// props:['num'],
props:{
num:{
type:Number,
default:2
}
},
methods:{
change(){
this.$emit('change-num',200)
}
}
}
}
})

 

 

3、$attrs 批量向下传递数据:

$attrs:是组件固有的,用来描述该组件身上的所有属性集合的对象
向下批量传递,使用v-bind="$attrs",在父级里给子级标签设置
 
$listeners 批量向下传递方法
$listeners 是组件上的方法,用来保存组件身上的方法
继续向下传递  v-on="$listeners"
 

4、Provide和Inject

对象类型
依赖注入,强制注入,可以扩展更深层的数据传递,在任何后代组件中都可以使用
优点:跨组件获取数据
使用provide或inject实例选项,provide:设置   inject:接收
provied:{属性名:属性值}
inject:['属性名']
注入过来的数据成为组件上的属性
 

5、ref的使用

ref:string类型,主要用来给元素或者子组件注册引用信息,引用信息会注册在父组件的$refs对象上
$refs:类型是Object对象,持有所有已经注册过ref的子组件
如果在普通DOM元素上使用,那么引用的注册信息指向DOM元素
如果在组件上使用,那么引用指向的是组件实例对象,那么可以获取到组件上的属性或方法
 

6、EventBus

原理:创建一个vue实例,调用实例上的方法
方法:
    发送:$emit("自定义事件名称",value)
    监听:$on("自定义事件名称",function(value){
                函数的参数是发送时候的值
          })
能实现各组件之间的通信(父子,兄弟,跨组件)
实现方法:在main.js中创建全新的vue实例
Vue.prototype.$bus=new Vue()
 

7、$parent  $children

$parent:  当前组件的直接父组件(无直接父组件则指向本身)
$children:当前组件的直接子组件,子组件会被当作数组展示,若无子组件就是空数组
在mounted中直接打印this.$parent
 

8、vuex

 
 
 

posted @ 2020-12-16 11:39  董珊珊  阅读(89)  评论(0)    收藏  举报