vue基础篇

总结内容基于2.x版本。

使用vue-cli生成命令 : vue create demo 

mvvm , m model 数据模型, v ,view视图, vm  vue 干了两件事 第一件 监听 dom , 第二件,把modal数据和view绑定起来 

 

1,  选项 / 生命周期钩子

常用 钩子
beforeCreate:()=>{
 console.log('beforeCrearte')
  },
  created:()=>{
    console.log('created')
  },
  beforeMount:()=>{
 console.log('beforeMount')
  },
  mounted:()=>{
 console.log('mounted')
  },
  beforeUpdate:()=>{
 console.log('beforeUpdate')
  },
  updated:()=>{
 console.log('updated')
  },
 beforeDestroy:()=>{ // 销毁前
 console.log('beforeDestroy')
  },
  destroyed:()=>{ // 销毁后
 console.log('destroyed')
  },
  errorCaptured:(err, vm, info)=>{ // 销毁后
 console.log(err, vm, info)
  },

2,指令

mustache(胡子)语法  {{}} 
可以配合过滤器使用 语法为 值 |  过滤方法   使用 filters 选项
   filters:{
 nameFix(name){
      return name+'*'
    }
  },

 {{item|nameFix}}

*************
v-once 

 
{{msg}}
// 只渲染一次
{{msg}}
// 正常渲染 ******************* v-bind 用来绑定属性 简写为 : 1, 使用bind绑定 class , vue内部会对 已经声明的class和绑定的class做合并, 第一种是 对象语法 大括号里的key的键值对 的值 布尔值是否是true 来决定key是否应用的,
demo
第二张是数组语法,数组内item必须是字符串或者 data内的变量,也可以配合method,或者computed 来使用 methods :
demo
computed:
demo
2, 使用bind绑定 style, - 和小驼峰都支持 ,也可以配合method,或者computed 来使用 第一张是对象语法 : 和react 一样 ,
demo
第二种是数组语法 : 数据里有几个现成的样式, 然后会把这个样式进行合并 data:()=>{return { style1:{fontSize:'50px'}, style2:{color:'lightblue'} }},
demo
********************* v-on 用来绑定事件 简写为 @ 传递参数 : 1,不传参数, 会有默认事件参数传递
changeValue(e){ console.log(e) }, 2. 传如参数,直接传
changeValue(e){ console.log(e) }, 3, 希望参数和事件同事传递, 事件 通过$event传递 ,注意 事件要放到最后,否则值就丢了
changeValue(value,e){ console.log(value,e) }, 事件修饰符 : 阻止该事件冒泡 @click.stop 阻止默认行为 提交之类 @:submit.prevent="onSubmit" 阻止冒泡和捕获 @click.stop.prevent 监听键盘点击 1, 键代码 2, 键 名 原生组件监听修饰符 ,监听vue组件事件 @click.native 一次修饰符 .once
******************** v-if v-else v-else-if 组件 生成 还是不生成; 在某些特出场景中,输入框切换后, 值没有换掉,这是由于diff算法导致的, 解决办法加key ,key很重要 性能消耗比较大 ******************** v-show 布尔值 display 组件隐藏还是显示 性能消耗比较小 ******************** v-for 循环数组 movies:['八神','火神','雷神'],
  • {{item}}
v-for 要加key 优化性能,key的取值 ,最好不要取index, 而是取唯一的值, 否则 在做插入数组的时候性能算法消耗很大 循环对象 fighter:{ name:'八神', age:'24', skill:'八稚女' }
  • {{value}}
******************** v-html v-text 两个都不用写文本, 直接绑定变量
html用来解析 html文本
text用来直接放文本 v-pre 原封不动的显示出来 不做任何解析 v-cloak 在加载成功以后再进行展示。避免那种 {{}} 直接出现 用在css里的

3, methods 和 computed 

method   是方法名字 动词  , 在vue代码内调用 需要 (), 渲染 会每次都调用

computed  计算属性 是名次, 在vue代码内调用不需要 (),渲染 只会调用一次  有缓存 

4, computed 的 setter和getter 

   computed:{
    classes:{
      get(){
        return this.styleName
      },
      set(style){
       this.styleName=style
      },
    }
  },


get 默认返回, 一般用的都是get ,不用set 


set方法调用 

methods:{
    changeValue(){
  this.classes='activeClass2'
    },

}

 

5, for of 和 reduce 

/*
* for of
*/

let arr = [1,2,3];

// 可以直接拿到 item 展示
for(let item of arr){
	console.log(item)
}


/*
* reduce 
*/

 let arr = [100,200,300];
      
      // 传入一个函数, 函数的第一个参数是上一次计算的值, 第二个是循环item, 
      let result = arr.reduce((preValue,item)=>{
        return preValue + item
      })

console.log(result)

6, 哪些操作能够满足vue的及时响应 ,哪些不能呢 ?

可以:

    一, 原生数组操作 都可以 

   二, 或者替换整个数组对象的地址

不可以:

   修改数组已有的下标的值不可以引起响应

 
  • {{item}}
movies:['八神','火神','雷神'], changeValue(){ this.movies[1] = 'k-dash' },

7, v-model和几个form控件的配合使用 

表单 v-model 
这个 就等于 v-on和 v-bind 一起用 

修饰符使用
.lazy  回车或者失去焦点时 才会发生改变 提高性能
.number 转为数字,配合input的type=number使用
.trim  去除首尾空格



*************************
select 

单选

 selectValue:'八神',


复选 

 
  
选中了: {{selectValues}}
movies:['八神','火神','雷神'], selectValues:['八神'], ************************* radio
选中了: {{selectValues}}
movies:['八神','火神','雷神'], selectValues:'八神', ************************** checkbox checkbox的v-model交互做了修改为一个数组了
选中了: {{selectValues}}
movies:['八神','火神','雷神'], selectValues:['八神'],

8, runtime-compiler 和 runtime-only 之间的区别 

需要使用template模版的时候使用runtime-compiler

只使用.vue文件的时候 使用runtime-only

9 ,全局组件和 局部组件 

// 全局注册 全局 的vue 上挂在了一个组件, 无论在什么全局的vue实例上直接使用
 const comp  =  Vue.extend({  // extend 创建一个vue组件 
   template:`
demo
`, data:{ a:222 } }) Vue.component('cpn',comp); // 语法糖 Vue.component('cpn',{ // extend 创建一个vue组件 template:`
demo
`, data:{ a:222 } }); // 局部注册components中注册 这种就只能在局部组件内使用了 , 一般用这个 const comp1 = Vue.extend({ template:`
demo
`, data:{ a:222 } }) const app1 = new Vue({ template:`
demo
`, data:{ a:222 }, components:[comp1] }) // 语法糖 const app1 = new Vue({ template:`
demo
`, data:{ a:222 }, components:{ comp1 : { template:`
demo
`, data:{ a:222 } } } })

10,template 模版分离写法 : 

1, script  脚本段



Vue.component('cpn',{
  template:'#cpn'
})


2, template标签 

Vue.component('cpn',{
  template:'#cpn'
})

11 ,父子组件传参数 :

 父传子 

1, 父传子 通过props传递(bind 绑定 :,低版本中驼峰需要转成 - 连接形式), 通过props 约束 

 props 约束  有三种
 1, 数组  props: ["hero","des"]
 这种情况下直接声明注册 
2, 对象约束具体属性 
  props: {
      hero:Array,
      des:String
  }
3, 具体属性给予默认值 和ts 很像 
 props: {
      des:{
        type:String,
        default:'aaa'
}
  }

父组件  

  data:()=>{
    return {
    hero:['11','22','333'],
    des:'demo'
}
  },

子组件 



 子传父

2, 子传父 通过$emit发射 父组件在子组件上绑定的事件 

父组件在子组件上 是@ 绑定事件不是bind:绑定属性 

父组件
  

methods:{
    childClick(e){
      console.log(e)
    }
    
  },

自组件 

 

 methods:{
      btnClick(e){
          this.$emit('cpmClick',e)
      }
  },

也可以顺便学习一下watch 函数
  watch:{
      nameDemo(newValue){
          this.nameDemo= newValue;
          this.$emit('cpmClick',newValue+'watchValue')
      }
  }

12, 父子访问组件方式 

父访问子
1, $children  不常用 是个数组 
2, $refs  reference 引用的隐私 -----   非常常用 




子访问父亲
1, $parent   不常用 





访问根节点
$root 不常用 


 

13, 插槽  slot 

插槽的作用就是把公共组件的公共部分又进行了抽象来使用 ,具体:

1, 简单使用  就是把标签内部的东西替换成 内容到预留位置 

父组件
 
     
我是插槽
子组件 默认值的位置 输入默认值 2, 具名插槽 使用具体名字 来表示替换的某个部分 ,注意 不要直接加slot属性到组件上 ,要包裹span 父组件 子组件 3, slot 作用域 父组件替换子组件的在标签,但是利用子组件的默认数据重新写了内容 步骤一 slot 绑定数据 :data='nameDemo' 步骤二 使用template slot-scope="slot" 绑定作用域 父组件 子组件

14, router的基本使用 

router/index.js 


import VueRouter from 'vue-router';
import Vue from 'vue'
// 懒加载  
//1, 会打出分包
//2. 以前的书写方式可能更为复杂
let home =()=>import ('../components/HelloWorld.vue');
let about =()=>import ('../components/About.vue');


// 1, 安装router 
Vue.use(VueRouter);

// 创建router
const routes= [
    {
        path:'',
        redirect:'/home'
    },
    {
        path:'/home',
        component: home
    },
    {
        path:'/about',
        component: about
    }
]

const router = new VueRouter({
    routes
});

// 导出 router
export default router

********************
// main.js 

import Vue from 'vue'
import App from './App.vue'
import router from './router/index'

Vue.config.productionTip = false

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


********************
// App.vue






15, router-link  router-view 




1, router-link 链接 

属性有这几种 
tag 默认渲染 a , 但是可以改成其他标签元素

replace   to的模式为pushstate,使用replace将改为replacestate,这样不会产生历史记录
 
activeClass 修改链接的选中默认样式 

 第一种方式 
 home 
    
第二张方式
 在router/index.js中 使用linkActiveClass 属性配置
const router = new VueRouter({
    routes,
    mode: 'history',
    linkActiveClass:'red'
});



2, router-view显示视图 子路由也用这种方式显示 在组件内使用 


3,方法跳转 
this.$router.push('/home');
this.$router.repalce('/home');

16, 切换 hash 和history

/router/index.js 内修改mode属性即可
const router = new VueRouter({
    routes,
    mode: 'history',
});

17,嵌套路由

// router/index.js 注意子路由不写/

  {
        path:'/about',
        component: about,
        children:[
            {
                path:'message',
                component: message
            },
            {
                path:'detail',
                component: detail  
            }
        ]
    }

// About.vue 
message detail

18, router 和route的区别

router

放了全局方法和对象,包括路由配置元信息

*********

route

当前命中的路由属性 

19,路由顶部传参 

// 动态路由


// 1, restful风格path传参数

const routes= [
    {
        path:'',
        redirect:'/home'
    },
    {
        path:'/home',
        component: home
    },
    {
        path:'/about/:names',
        component: about
    }
]


// 传递
 goAbout(){
      this.$router.push('/about/xiaoming');
    }

// 在about页面显示 /about/:names ,names 参数

 computed:{
        names(){
         return this.$route.params.names
        }
    }
// 2 ,query 传参

写法一:使用点点击方法
 goAbout(){
      this.$router.push(
        {
        path:'/about', 
        query: {
          names:'xiaoming',
          age:12
          }
      }
      );
    }

写法二: 使用bind属性 
 about

// 拿到传递的query 


 computed:{
        names(){
            console.log(this.$route)
         return this.$route.query.names
        }
    }

20,路由守卫

分为三种: before 函数里需要调用next方法, after 不需要
1,全局守卫

添加title

const routes= [
    {
        path:'',
        redirect:'/home'
    },
    {
        path:'/home',
        component: home,
        meta:{
            title:'首页'
        }
    },
    {
        path:'/about',
        component: about,
        meta:{
            title:'关于'
        },
        children:[
            { 
                path:'',
                redirect:'message'

            },
            {
                path:'message',
                component: message,
                meta:{
                    title:'信息'
                },
            },
            {
                path:'detail',
                component: detail,
                meta:{
                    title:'详情'
                },
            }
        ]
    }
]

router.beforeEach((to, from, next) => {
      // meta 元数据
    document.title = to.meta.title ? to.meta.title : to.matched[0].meta.title
     next()
  })


2,路由独享的守卫  写在route里

 {
        path:'/about',
        component: about,
        meta:{
            title:'关于'
        },
        beforeEnter: (to, from, next) => {
            document.title = to.meta.title ? to.meta.title : to.matched[0].meta.title
            next()
          },

}

3,组件内守卫  就像生命周期函数一样使用
 beforeRouteEnter (to, from, next) {
          console.log(this) // 访问不到 ,不能在这个地方才做this
            next(vm => {
                console.log(vm)
            // 通过 `vm` 访问组件实例
        })
  },
    beforeRouteUpdate (to, from, next) {
    // just use `this`
    this.name = to.params.name
    next()
    },
    beforeRouteLeave (to, from, next) {
    const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
    if (answer) {
        next()
    } else {
        next(false)
    }
    },

21,路由组件keep-alive,一般路由被卸载就会销毁 ,加上这个属性就不会被销毁 ,节省开销

 

exclude 这个属性是放开某个组件,逗号分割 不允许空格


             
        

22,vuex 

 1, 引入 创建实例

import Vuex from 'vuex'
import Vue from 'vue'

Vue.use(Vuex);

let store = new Vuex.Store({  // 注意Store 为大写
    state:{ // 全局根状态管理器
        count:1000
    },
    mutations:{  // 同步更新视图方法,可以直接更新但是为了工具插件能记录,所以要用mutations
        add(state,{payload}){
            //state.count++
            state.count+=payload;
        }
    },
    actions:{ // 异步发请求 仍需要mutations来提交

    },
    getters:{ // 类似computed

    },
    modules:{  // 更多模块的state 

    }
}) 

export default  store;

 2,引入 main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router/index'
import store from './store/global'

Vue.config.productionTip = false

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



3, state  // 全局根状态管理器
 在全局中使用 
{{$store.state.count}}
4, mutations 使用commit 提交 mutations:{ // 同步更新视图方法,可以直接更新但是为了工具插件能记录,所以要用mutations add(state,payload){ //state.count++ state.count+=payload; } }, methods:{ add(){ // 1,commit 方法来触发 方法名, // this.$store.commit('add') this.$store.commit('add',2) // 直接传入参数 // 2. commit 方法来类似react的diapatch触发对象写法 // this.$store.commit({ // type:'add', // payload:2 // }) } } 需要 mutations的方法名字和调用名字需要被抽离 export default { 'add':'add' } import mutationsType from './mutationsType' [mutationsType.add](state,payload){ //state.count++ state.count+=payload; } 5, actions fetchSth(){ this.$store.dispatch('fetchSth') } fetchSth(context){ // context 就是当前store 上下文环境 setTimeout(() => { // 通过commit提交让工具记录操作 context.commit(mutationsType.add,1); }, 1000); } // 通过promise 来传递 回调参数 fetchSth(context){ // context 就是当前store 上下文环境 setTimeout(() => { // 通过commit提交让工具记录操作 context.commit(mutationsType.add,1); }, 2000); return new Promise((resolve,reject)=>{ resolve('回调成功'); reject('') }) } this.$store.dispatch('fetchSth').then(res=>{ console.log(res) }) 6, getters
{{$store.getters.powerCount}}
getters:{ // 类似computed powerCount(state){ return state.count*500; } }, 入参数形式 getters:{ // 类似computed powerCount(state){ return (params)=>{ return state.count+params } } },
getters
{{$store.getters.powerCount(500)}}
7, modules 除了state 分 模块 的概念, 其他的都不区分模块的概念, 但是写的时候也写到一起 let moduleA = { state:{ age:1111111 } } modules:{ // 更多模块的state moduleA }
{{$store.state.moduleA.age}}
8,store的 代码抽离 首先 modules 要全部抽出来, 其次 state和其他的属性如果太大可以抽离出来

23, promise 

    1 ,promise的函数是为了解决和回调地狱的问题 

    2, promise 接收两个函数作为参数 resolve ,reject 

    3, 这几个方法也可以 拆成  promise.resolve(),promise.reject() , 还有一个 promise.all 接收多个请求,都成功.then会得到一个数组 放两个请求的结果 ,用来处理并发请求, 

    4,.then 对应.resolve  .catch  对应reject, 最后还有finally, 可以在。catch后继续.then 

    5,.then若需要继续.then下去回调 直接return res 就好 ;他是promise.resolve() 或者 new Promise(resolve)的简写

  

24,axios 

1, 基本使用

import axios from 'axios';

axios({
  url:'http://123.207.32.32:8000/home/multidata',
  method:'get'
}).then(res=>{
  console.log(res)
})

axios.get('http://123.207.32.32:8000/home/multidata').then(res=>{
  console.log(res)
})

axios({
  url:' http://123.207.32.32:8000/home/data',
  params:{
    type:'sell',
    page:1
  }
}).then(res=>{
  console.log(res)
})

2,  并发请求 
axios.all([
  axios({
  url:'http://123.207.32.32:8000/home/multidata',
  method:'get'
}),
axios({
  url:' http://123.207.32.32:8000/home/data',
  params:{
    type:'sell',
    page:1
  }
})]).then(res=>{
  console.log(res)
})

3, 全局配置

axios.defaults.baseURL = 'http://123.207.32.32:8000';
axios.defaults.timeout = 5000

axios({
  url:'/home/multidata',
  method:'get'
}).then(res=>{
  console.log(res)
})

4,实例封装

let request = axios.create({
  baseURL:'http://123.207.32.32:8000',
  timeout: 5000
})
request({
  url:'/home/multidata',
}).then(res=>{
  console.log(res)
})


5, 封装请求

let request = (config)=>{
   let instance = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout: 5000
   })
   // 自动返回一个promise
   return instance(config);
}
request({
  url:'/home/multidata',
}).then(res=>{
  console.log(res)
})



6, 拦截器

let request = (config)=>{
   let instance = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout: 5000
   })
   //!!!!! 拦截器需要返回对应的响应体 config
   // 配置发送成功和失败的拦截器 
   instance.interceptors.request.use(
     config=>{
       console.log('请求发送成功')
       return config
     },
     err=>{
      console.log('请求发送失败')
      return err
     }
     )
   // 配置响应成功和失败的拦截器
   instance.interceptors.response.use(
    config=>{
      console.log('响应返回成功')
      return config
    },
    err=>{
     console.log('请响应返回失败')
     return err
    }
    )
   // 自动返回一个promise
   return instance(config);
}


 

 

 

 

你可能感兴趣的:(vue,javascript)