Vue2

作者: 追风还是少年 | 来源:发表于2023-11-07 23:19 被阅读0次

let、var、const

(1) var
在 ES6 出现之前,var 声明占主导地位。但是,使用 var 声明的变量存在一些问题。

  • var 声明的作用域是全局的或函数/局部的
    当 var 变量在函数外部声明时,作用域是全局的。这意味着在函数体外用 var 声明的任何变量都可以在整个窗口中使用。
    var 在函数中声明时,它的作用域是在函数体内。这意味着它只能在该函数中被访问。
  • var 变量可以重新声明和更新
    这意味着我们可以在相同的作用域内执行此操作,并且不会出错。
var greeter = "hey hi";
var greeter = "say Hello instead";
var greeter = "hey hi";
greeter = "say Hello instead";
  • var 的提升
console.log (greeter);
var greeter = "say hello"

解释为

var greeter;
console.log(greeter); // greeter is undefined
greeter = "say hello"
  • val的问题
var greeter = "hey hi";
var times = 4;

if (times > 3) {
    var greeter = "say Hello instead"; 
}

console.log(greeter) // "say Hello instead"

(2) let

  • let 是块作用域
   let greeting = "say Hi";
   let times = 4;

   if (times > 3) {
        let hello = "say Hello instead";
        console.log(hello);// "say Hello instead"
    }
   console.log(hello) // hello is not defined
  • let 可以更新但不能重新声明
let greeting = "say Hi";
greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared

但是,如果同一个变量定义在不同的作用域,就不会报错

let greeting = "say Hi";
if (true) {
    let greeting = "say Hello instead";
    console.log(greeting); // "say Hello instead"
}
console.log(greeting); // "say Hi"

就像 var 一样,let 声明被提升到顶部。与初始化为 undefined 的 var 不同,let 关键字未初始化。所以如果你在声明之前尝试使用 let 变量,你会得到一个 Reference Error。

(3) const
与 let 声明一样,const 声明只能在它们声明的块内访问。
每个 const 声明都必须在声明时进行初始化。
const 不能更新或重新声明。

const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable. 
const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared
const greeting = {
        message: "say Hi",
        times: 4
    }
greeting = {
    words: "Hello",
    number: "five"
} // error:  Assignment to constant variable.

greeting.message = "say Hello instead"; //这样是允许的

=== 与 =

  • ===
    严格相等(三个等号)
    比较两个操作数时,如果类型不同,就一定不相等
    (1)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等
    (2)如果两个值都是true,或是false,那么相等
    (3)如果两个值都引用同一个对象或是函数,那么相等,否则不相等
    (4)如果两个值都是null,或是undefined,那么相等
  • ==
    宽松相等(两个等号)
    比较两个操作数时
    如果两个类型不同,双等号(==)将执行类型转换,有可能会返回相等
    (1)如果一个是null,一个是undefined,那么相等
    (2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较

Vue Chrome浏览器调试插件Devtools

// 开发环境,包含完整的警告和调试模式
<script type="text/javascript" src="./js/vue.js"></script>
// 生成环境
<script type="text/javascript" src="./js/vue.min.js"></script>

容器与vue绑定

<input id = "root" v-bind:value="name"></input>
<input id = "root2" v-model:value="age"></input>
<script>
vm = new Vue({
  el: '#root2',
  data: {
    name: '简书',
    age: 18
  }
})

vm2 = new Vue({
  el: '#root2',
  data: {
    name: '简书',
    age: 18
  }
})
<script>

//容器与vue是一 一绑定,即多个vue对象不能绑定同一个容器
//(1) root输入框容器与vue单向绑定,即vue的data数据更新会同步更新到容器,而容器的输入值修改不会同步更新到vue的data数据
//(2) root2输入框容器与vue双向绑定,即vue的data数据更新会同步更新到容器,容器的输入值修改也会同步更新到vue的data数据

<div id = 'root'>{{name}}<div>
var data =  {
    name: '简书',
    age: 18,
  }
vm = new Vue({
  data: data,
  method: {
    showinfo: funtion(){
      console.log(this) //this为 vue对象
    },
    //showinfo(){ //简写方式
    //}
    //showinfo: ()=>{ //箭头函数
    // console.log(this) //this不为vue对象,为windows
    //}
  },
  created: function () {
     // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
 }
})
// 实例化vue对象时没有绑定容器,而是实例化之后进行绑定
vm.$mount('#root')
vm._data === data
vm.name == data.name

插值法与指令语法

  • 插值法
    {{name}},用于html标签体,即<div>{{name}}</div>
  • 指令语法
    v-bind 指令,用于标签属性,v-bind:可以简写为:, 如 v-bind:value,可以简写为:value
    v-model 指令,用于表单类型元素,如 v-model:value,可以简写为v-model
    v-if 指令, <p v-if='seen'>现在你看到我了</p>,当seen=true时,才展示
    v-else-if指令、v-else
    v-for 指令, <li v-for='book in books'>{{book}}</li>
    v-on 指令,可以简写为@,如 v-on:click,可以简写为@click
    v-show指令,控制是否显示,映射样式的display 如:style='display:none'
    v-text指令,<div v-text='name'>这里输入内容失效</div>与<div>{{name}}</div>等价,如果name='<h1>test</h1>' v-text不解析html标签,内容原样显示

v-html指令,作用v-text差不多,与v-text区别,v-html指令会解析内容里面的标签

<template v-if><h1>aa</h1></h2>bb</h2></template> 模版与v-if配合

vm = new Vue({
  el: '#root',
  data: {
    name: '简书',
    age: 18,
    seen: true
    books: ['book1','book2']
  }
})

修饰符:

// .prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault(),即只执行事件处理函数,不提交到服务器端
<form v-on:submit.prevent="onSubmit">...</form>

绑定class样式

:class属性值由vue解析出来的样式会与class属性定义的样式合并

<div id = 'root'>
  <div class = 'basic' :class='style' @click='changStyle'>test</div>
 //<div class = 'basic' :class="['normal','happy']" >test2</div>
 <div class = 'basic' :class='arr' @click='changStyle2'>test2</div>
<div class = 'basic' :class='classObj' >test3</div>
<div class = 'basic' :style='styleObj' >test4</div>
<div>
<script>
vm = new Vue({
  el: '#root',
  data: {
    name: '简书',
    age: 18,
    style: 'normal',
    arr: ['style1','style2'],
    classObj: {
      'normal': true,
      'happy': false
    },
    styleObj:{
      fontSize: '40px'
    }
  },
  methods:{
    changStyle(){
      this.style = 'happy'
    },
    changStyle2(){
      this.arr.shift()
    }
  }
})
</script>

computed计算属性

计算属性会缓存,get函数什么时候调用?1、初次读取计算属性时,2、当依赖的属性发生变化时候,get函数会重新调用
计算属性使用{{fullName}}

computed:{
  fullName: {
    get(){
    }
    set(){
    }
  }
}

当计算属性只有get函数时,简写为下面形式:
computed:{
  fullName(){
  }
}

style scope

组件的style加 scope防止组件定义的class样式与其它组件的class名称相同导致冲突

<style scope>
</style>

app组件的style一般不会定义为scope,这里定义的class样式为所有组件共享的样式

语言默认为css,如果要使用less,需要配置lang='less',使用前需要npm -i less-loader@7(不加版本,默认是最新的,最新的less是需要配合webpack的5版本)

<style lang='less'>
</style>

:key 唯一标识(虚拟DOM,Vue使用,在真实DOM中不存在)

自定义指令

<div id= root>
    <h2>{{name}}</h2>
    <h2>当前n的值<span v-text="n"></span></h2>
    <h2>放到十倍后的值<span v-big="n"></span></h2>
</div>
<script>
vm = new Vue({
  el: '#root',
  data: {
    name: '简书',
    age: 18,
    n: 1
    },
   directives:{
      // big函数何时会被调用 1、指令与元素成功绑定时 2、指令所在模版被重新解析(有变量变化就会引起模版解析)
      big(element, binding){
        element.innerText = binding.value*10
      },
      fbind: {
       // 指令与元素成功绑定
        bind(element, binding){
          element.innerText = binding.value
        },
        // 指令所在元素被插入页面
        inserted(element, binding){
          element.foucus()
        },
        // 指令所在模版被重新解析
        updated(element, binding){
          element.innerText = binding.value
        }
      }
   }
})
</script>

表单

// 修饰符阻止默认行为,不提交调整了
<form @submit.prevent='showInfo'>
<input type='text' v-model.trim='username'/>
<input type='password' v-model='password'/>
// number修饰符
<input type='number' v-model.number='age'/>

<input type='radio' name='sex' v-model='sex' value='male'/>
<input type='radio' name='sex' v-model='sex' value='female'/>

// 如果没有配置value属性,收集的是checked属性
<input type='checkbox' v-model='hobby' value='study'/>
<input type='checkbox'  v-model='hobby' value='game'/>

<select v-model='city'>
  <option value=''>请选择</option>
  <option value='beijing'>北京</option>
  <option value='shanghai'>上海</option>
</select>
//延迟收集,失去焦点收集
<input type='text' v-model.lazy='other'/>
</form>
<script>
const vm = new Vue({
  el: '#root',
  data: {
    username: '',
    password: '',
    sex: 'male',
    hobby: [] //类型必须为数组,如果定义为'',会影响数据收集,收集的为true或false
    city: 'beijing',
    other: ''
  },
  methods:{
    showinfo(){
      alert('ok')
    }
  }
})
</script>

组件

实现应用中局部功能的代码和资源的集合
非单文件组件:一个文件包含多个组件
单文件组件:一个文件只包含一个组件(vue文件)

1、创建组件 2、注册组件

<div id= 'root'>
// 使用组件
<school></school>
<hr>
<student></student>
</div>
<script>
const school = Vue.extend({
  // 组件不能写el,因为组件可以公用
  // el: '#root',
  template: '<div><h1>{{schoolName}}</h1><h1>{{address}}</h1></div>'
  // data只能用这种写法
  data(){
    return {
      schoolName: 'a',
      address: 'xxx'
    }
  }
})

const student= Vue.extend({
  //开发者工具呈现名字
  name: 'school',
  // 组件不能写el,因为组件可以公用
  // el: '#root',
  template: '<div><h1>{{studentName}}</h1><h1>{{age}}</h1></div>'
  // data只能用这种写法
  data(){
    return {
      studentName: 'b',
      age: 18
    }
  }
})

const vm= new Vue({
   el: '#root',
  // 局部注册
   components:{
     school: school,
     student: student
   }
})

//全局注册
Vue.component('hello',hello)
</script>

VueComponent构造函数
### 数据代理
```javascript
var data = { name: '简书' }
// var data = { name: '简书' , age: 20} 直接在这里定义的sex属性默认是可以修改的
const vm = new Vue({
  el: '#root',
  data: data
})

Object.defineProperty(data, 'age',{
  configurable: true,  // 属性是否可删除,默认为false
  writable: true, //属性值是否可以修改,默认为false
  enumerable: true, //属性key是否可枚举,默认false,类似for key in data console.log(key) 、Object.keys()不会输出sex属性
  value: 18,
  get: funtion(){ // getter
    return vm.age
  },
  set: funtion(val){ //setter
    vm.age= val
  }
})

MVVM

image.png

M 代表Model,即模型,plain javascript objects
V 代表View, 即模版视图,DOM
VM代表 View Model,Vue

Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。
ViewModel把Model和View关联起来。ViewModel负责通过Data bindings把Model的数据同步到View显示出来,还负责通过DOM Listeners(监听view的修改)把View的修改同步回Model

安装vue-cli

//全局安装
npm install -g @vue/cli
npm config set registry https://registry.npm.taobao.org

vue create my-project

// 运行
npm run serve

babel,es6转es5

export

ctrl + s,更新代码

vue核心 + 模版

esm:es module
common.js

render

new Vue({
router,
render: h => h(App),
}).$mount('#app')

vue ref

给html元素或子组件注册引用信息

<template>
  <h1 v-text='msg' ref='title'></h1>
</template>

<script>
this.$refs.title
</script>

### props

<School name='张三' sex='男' age='18>


student= {
  //开发者工具呈现名字
  name: 'school',
  //props: ['name','sex','age'] //简单接收
  /*
  props:{
    name: String,
    sex: String,
    age: Number
  },
*/
 props{
    name{
      type: String,
      required: true
    },
    sex{
      type: String,
      required: true
    },
    age{
      type: Number,
      required: true,
      default: 19
    },
  }
}

mixin 混入

多个组件共用配置提取为一个混入对象,使用混入
mixin.js

export const henru1 = {
  data:{},
  methods:{},
  mounted(){
  }
}

全局混合:在app组件 import 混入 Vue.mixin(henru1) Vue.mixin(henru2)
局部混入: 在vc的mixins:[henru1,henru2]

插件plugin

export default{
  install(Vue,options){
    Vue.filter(..)
    Vue.directive(..)
    Vue.mixin(..)
    Vue.prototype.$myMethod = function(){...}
    Vue.prototype.$myProperty = xxx
  }
}
// 传入多个参数
Vue.use(plugins,1,2)

插槽 slot

默认插槽

<category>
  <image src=''></image>
</category>

category组件:
<template>
  <h1>测试</h1>
  <slot>默认</slot>
</template>

具名插槽:

<category><image slot="center" src=''></image><a slot="footer"/></category>
或
<category>
  <template slot="center">//或<template v-slot:center> 只有template元素才能用这种写法
    <image src=''></image>
  </template>

  <a href='' slot="footer"/>
</category>

category组件:
<template>
<h1>测试</h1>
<slot name="center">默认</slot>
<slot name="footer">默认</slot>
</template>

作用域插槽:

数据在组件,需要把数据传给使用插槽的地方
<category>
<template scope = '{games}'> //或者使用slot-scope 必须使用template包裹,{games}是结构赋值,如果<template scope = 'xx'>,那使用games就必须通过xx.games
</template >
</category>

category组件:
<template>
<slot :games="games" msg="hello">默认</slot> //可以传多个数据给组件的使用者
</template>

$emit

组件自定义事件

使用组件地方
<Student v-on:test="getName" ref="student"/>

new Vue(){
  methods:{
    getName(){
    }
    mounted(){
      this.$refs.student.$on('test',this.getName);
    }
  }
}

Student组件定义:
<h1>student组件</h1>
<button @click="sendName"></button>
export default {
  methods:{
    sendName(){
      this.$emit('test','xx');
    }
  }
}

也可以通过refs实现 this.off('test'); //解绑事件 this.$off(['test'])

...param,接收多个参数

sync修饰符

在父组件上告诉子组件传递过去的msg跟父组件上的n保持同步,相当于允许它修改
<child :msg.sync='n'></child> //msg属性

<button @click="$emit('update:msg',msg-1)">子组件点击{{msg}}</button>

vuex

多组件数据共享:全局事件总线实现

vm store配置项

action:{}、mutation: {}、state: {}

route

export default new VueRouter({
  router:[
    {
      path: '/about',
      component: about
    },
    {
      path: '/home',
      component: home
    }
  ]
})

<route-link to='/about' active-class='active'>

<route-view></route-view>

路由守卫

{
path: '/home',
component: Home,
meta: {title:'', isAuth:true}
}

  • 全局路由守卫(针对所有路由)
    // 初始化的时候调用、每次路由被切换之前被调用
    // to代表要切换到哪个路由,from代表从哪个路由来
    router.beforeEach(to,from,next){
    //next()
    })
    // 初始化的时候调用、每次路由被切换之后被调用
    router.afterEach(to,from){
    }

  • 独享路由守卫(只有一个)
    {
    path: '/home',
    component: Home,
    // 进入之前
    beforeEnter: (to, from, next) =>{
    }
    }

  • 组件内路由守卫
    export default {
    name: 'Student',
    data(){
    return {}
    },
    // 通过路由规则,进入该组件时被调用
    beforeRouteEnter(to, from, next){
    },
    // 通过路由规则,离开该组件时被调用
    beforeRouteLeave(to, from, next){
    }
    }

路由的两个生命周期钩子

//组件激活
activated(){
}
//组件失活
deactivated(){
}

数据劫持

ES6与ES5

<script type='module'/>

export:
(1)分别暴露
export function(){}
(2)统一暴露
export {}
(3)默认暴露
export default

import:
通用导入
import * as m1 from ''; ////分别暴露、统一暴露、默认暴露

解构赋值形式
import {} from ''; //分别暴露和统一暴露
import {default as x} from ''; //默认暴露

简便形式:
import x from ''; //默认暴露

<script src='' type='module'/>

webpack

相关文章

网友评论

      本文标题:Vue2

      本文链接:https://www.haomeiwen.com/subject/knvfwdtx.html