vue2.0 小记

事件修饰符

.self 点击自己才会触发,包括冒泡情况也会跳过
.capture 冒泡顺序倒置

绑定类名

:class="[‘classname’,flag ? ‘classname’ : ‘’,{‘classname’ : flag}]"
{‘需要绑定的类名’:是否绑定} 该对象也可以在data中声明赋值

绑定样式

:style="{color:‘red’,‘font-size’:‘16px’}"
样式的名称带-,必须用’'括起来;多个对象绑定时:style="[obj1,obj2]"

v-on绑定事件

可以写() 也可以不加 v-on=“fn” @on=“fn()”
$event 作为参数的时候传递原生的事件对象

自定义指令

第一个参数:指令的名称 第二个参数:对象
指令名称不需要"v-";指令可以在不同的生命周期阶段执行
bind:指令被绑定到元素上的时候执行
inserted:绑定指令的元素被添加到父元素上的时候调用
Vue.directive(“color”,{
bind:function (el,obj){ //第二个参数是个对象,常用obj.value获取指令绑定的值
el.style.color = =‘red’
// el.focus(); 该事件在bind阶段中不生效,元素还未被渲染,应该在inserted生命周期中执行
}
})

红色

在bind的回调函数中调用第二个obj参数的value获得blue

局部指令

与methods同级
directives:{
“color”:{
bind:fucntion(el,obj){
el.style.color = obj.value;
}
}
}

计算属性

与methods同级
conputed:{
“key”:function(){
let value = ‘’;
return value;
}
}
计算属性不是函数所以调用的时候不要() 直接插值调用{{计算属性名称}}
计算属性会将返回的结果缓存起来,结果没有发生变化,就执行一次;数据常变用函数,变动少用计算属性性能高

全局过滤器

Vue.filter(‘过滤名称’,function(value){
//处理数据的函数
value = value.replace(/学院/g,“大学”)
return value;
});
使用:{{插值变量 | 过滤器名称}} 1.只能在插值语法和v-bind中使用 2.过滤器可以连续使用 {{插值变量 | 过滤器1 | 过滤器2}}

局部过滤器

只能在自定义过滤器的vue实例中使用
和methods同级
filters:{
‘过滤器名称’:function(value){
return value;
}
}

在使用过滤器的时候,可以在过滤器名称后面加上()给过滤器的函数传递参数
{{number | filt(2)}}
filters:{
‘过滤器名称’:function(被过滤的值,过滤器参数){
return value;
}
}

过渡动画

标签包围,通过css控制样式,过程中写transition:all 3s;
.v-enter 进入开始前 opacity:0;
.v-enter-active 移入开始后 transition: all 3s;
.v-enter-to 进入过程中 opacity:1;
.v-leave 离开 开始前 opacity:1;
.v-leave-active离开后 transition: all 3s;
.v-leave-to 离开 过程 opacity:0;
一个transition标签中只能放一个元素
appear刷新页面的时候执行动画
class对应的v-enter类名为 .one-enter
钩子函数:v-on:before-enter=“beforeEnter” enter after-enter before-leave
beforEnter(el){//el是当前元素} enter(el,done){//done 是否已经执行完毕,执行完毕后要调用 done(); 回调,否则afterEnter不会执行} afterEnter(el){}
通过js钩子函数实现动画,vue会查找类名;transition标签中可以通过v-bind:class=“false” 取消查找类名
如果通过js钩子函数来实现过渡动画,要在执行过程执行结束回调前执行el.offsetWidth 或 el.offsetHeight
一刷新就执行js动画,最好在过程中延迟后执行done()回调;

第三方js动画库过渡 example : Velocity

enter(el,done){
Velocity(el,{opacity:1,marginLeft:“500px”},3000)
el:元素 Object 动画的属性 Number 动画时长
}

第三方css动画库 example: animated

绑定自定义过渡类名(组件属性):enter-class(动画进入开始) enter-active-class(动画进入过程) enter-to-class(动画进入结束) leave-class leave-active-class leave-to-class
使用:

动画盒子

多个元素动画可用包裹,其使用和transition标签一致

for注意点

v-for在渲染元素的时候,会先查看缓存中有没有需要渲染的元素
如果缓存中没有要渲染的元素,就会创建一个新的放到缓存中,如果缓存中有要渲染的元素,就不会创建一个新的,而是直接复用原有的
在vue中,只要数据发生改变,就会重新渲染
不要用index当做key

自定义全局组件

1.创建组件构造器

模板只能有一个根元素
let Profile = Vue.extend({
template:<div>模板html内容</div>
})

2.注册已建好的组件

Vue.component(“abc”,[Profile])
第一个参数:注册组件的名称
第二个参数:构建好的组件构造器
使用:

全局组件简写

Vue.component(‘组件名称’,{这个对象就是组件构造器,不需要Vue.extend创建})
也可以将html模板写在
然后使用VUe.component(‘组件名称’,{template:"#模板id"})注册组件
在Vue中有template标签可以写html模板内容,带上id属性即可

局部组件

在当前vue实例中使用
使用与methods同级定义:
components:{
“组件名称”:{
template:"#模板id"
}
}
组件中data必须是个函数,与vue实例不太一样
data:function(){
return {
abc:“你好”
}
}

组件中的data如果不是通过函数返回,多个相同组件就会共用一份数据,导致数据混乱.
通过函数返回data的组件,每创建一个新的组件就会调用这个方法,将这个方法返回的数据和当前创建的组件绑定在一起,这样就避免了数据混乱

切换组件

与元素切换一样,v-if控制

动态组件:


与v-if的区别:v-if每次都会删掉组件再加载,而动态组件被包住后切换就不会销毁,从缓存中取.

给组件添加动画:单个组件添加到标签中即可;多个组件添加到中即可
组件切换时动画是同时进行,则可以切换动画模式: 1.in-out:新元素进行过渡完成后当前再进行过渡离开; 2.当前元素先进行过渡,完成后新元素过渡进入;
过渡模式使用:

父子组件

Vue.Component(“father”,{
template:"#father",
components:{
“son”:{
template:"#son"
}
}
})
父组件中调用了子组件,子组件在父组件中注册,只能在父组件调用;

子组件访问父组件数据要通过 v-bind:自定义接收名称=“传递数据” ; 子组件通过props:[“自定义接收名称”] 接收数据
子组件使用{{自定义接收名称}} ; 接收名称不能用驼峰命名,最好小写字母;若使用的时候要驼峰命名使用,接收名称需要在大写字母前面加- 并且大写改为小写; 如: 使用: props[“parentName”] 插值{{parentName}}

组件命名注意:注册的时候使用驼峰命名,使用的时候是不能使用驼峰命名的,大写字母前面要使用- ;
例如:Vue.component(“myFather”,{template:"#father"})使用
传递方法的时候也是不能使用驼峰命名的 <son @parent-say=“say”> 子组件中调用父组件方法:this.emit(“parent-say”) 用了横杠也不能使用驼峰命名调用,只能横杠调用

父组件传递子组件方法 v-on:自定义接收名称=“要传递的方法” ;或者 @自定义接收名称=“要传递的方法”
使用与传递属性不同,不需要在子组件props中接收;需要在子组件中自定义一个方法;使用this.$emit(“自定义接收名称”)

子组件传递给父组件传递参数:

在父组件中定义方法,传递给子组件;然后在子组件调用父组件方法,通过传递参数的方式设置父组件的数据
this.$emit(‘自定义方法名称’,参数1,参数2)

多级传递:需要一级一级往下传递
爷爷组件中调用爸爸组件 爸爸组件中pros[‘gfvalue’]接收;{{gfvalue}}使用;传递给儿子组件类似 再在儿子组件中pros[“fvalue”] 接收后{{fvalue}}使用
方法的传递也是一级一级传递 <father @gffun=“gfFun”> 爸爸组件中调用 自己在methods里面创建方法fFun(){this.emit(“gffun”)} ; 然后在爸爸组件中传递给儿子组件 <son @ffun=“fFun”> 儿子组件使用在methods中创建方法 sonFun(){this.emit(“ffun”)} 使用到爷爷组件中的方法

匿名插槽:

想在子组件的时候,给子组件动态添加内容就需要使用插槽
组件的模板中使用slot标签就是插槽,插槽其实就是一个坑,只要有了这个坑,就可以根据需要填坑
默认数据
插槽可以指定默认数据,如果没有填坑就显示这个默认数据,填了坑就使用填坑的数据

我是追加内容
div内容就填坑了
注意:插槽是可以指定名称的,默认情况没有指定名称,称为 匿名插槽
匿名插槽特点:有多少个匿名插槽,填充数据就会被拷贝多少份.推荐只使用一个匿名插槽

具名插槽:

想在组件中填充不同的内容就可以使用具名插槽
可以在定义插槽的时候给插槽添加一个name属性,通过这个name属性来指定插槽的名称;若没有通过slot属性告诉Vue,当前的内容是不知道要填充到哪个插槽中,则不会填充.

在组件的模板中使用
<template>
	<slot name="one">具名插槽1默认内容</slot>
	<slot name="two">默认内容2</slot>
</template>
在使用组件时
<son>
    <div slot="one">指定插槽内容1</div>
    <div slot="two">指定插槽内容2</div>
</son>

v-slot标签

v-slot指令只能使用在template标签上

<son>
    <template v-slot:one>
		<div>我是插槽one的内容1</div>
		<div>我是插槽one的内容2</div>
    </template>
    <template v-slot:two>
    	<div>我是插槽two的内容1</div>
    </template>
</son>

指定具名插槽的名称进行插槽填充

v-slot的简写形式 #one

<son>
	<template #one>
    	<div>插槽one的内容</div>
    </template>
</son>

VueX

虽然通过借助父组件能够实现兄弟组件之间的数据传递,但这种方式非常的复杂,;则可以使用VueX

使用

1.导入Vuex.js前先导入Vue.js
2.创建Vuex对象

  const store = new Vuex.Store({
    <!-- state相当于组件中的data,专门用于保存共享数据的 -->
    state:{
      msg:'共享数据'
    }
  })

3.使用:在祖先组件中和template同级添加key store:store, 必须通过this.$store.state.msg 调用
4.只要祖先组件中保存了Vuex对象,祖先组件和所有的后代都可以使用Vuex中保存的共享数据了

修改共享数据:this.$store.state.共享数据变量名称 = 值;
但是!VueX不推荐直接赋值修改,数据错误不好排查;使用mutations

const store = new Vuex.Store({
  state:{
    共享数据:"值"
  },

mutations:{ //用于保存修改共享数据的方法
mAdd(state){ //自动传递一个state参数,state中保存了共享数据
state.共享数据 = state.共享数据 + 1; //内部对共享数据进行操作
},
}
})
修改共享数据方法使用:this.$store.commit(“mAdd”) 进行调用

Vuex - getters属性

与computed计算属性类似,将返回结果缓存起来
const store = new Vuex.Store({
state:{
msg:“你好”,
},
mutations:{},
getters:{
format(state){
console.log(“返回值一样只执行一次”)
return state.msg + “东东”;
}
},
})
页面中使用: 先引入vuex store:store, {{this.$store.getters.format}}

Vue Router

和v-if 和 v-show一样用来切换组件显示的;Vue Router用哈希来切换(#/xxx)

比v-if和v-show强大的是还能在切换的时候传递参数

Vue Router使用

  1. 导入Vue Router(需先导入Vue)

  2. 定义切换的规则

    const one = { //组件1
    	template:'#one'
    };
    const two = { //组件2
    	template:'#two'
    };
    const routers=[
        //设置根目录访问时,默认重定向到/one 
        {path:'/',redirect:'/one'},
     	<!--数组中每个对象就是一个规则-->   
        {path:'/one',component:one},
        {path:'/two',component:two},
    ]
    
  3. 根据自定义的切换规则创建路由对象

    const router = new VueRouter({
        routes:touters
    })
    
  4. 将创建好的路由对象绑定到Vue的实例上

    let vue = new Vue({
    	el:"#app",
    	router:router,
    })
    
  5. 界面中的使用

<div id="app">
    <a href="#/one">切换到第一个页面</a>
    <a href="#/two">切换到第二个页面</a>
    <!--路由出口-->
    <!--将匹配到的组件渲染到这-->
    <router-view></router-view>
</div>

通过router-link设置hash标签

比a标签好:兼容性好,ie9降级使用hash模式还是html5的history模式和hash模式切换不需要做任何变动;

如果使用router-link设置url的hash值,不需要#,使用to属性来控制hash值

<div id="app">
    <router-link to="/one">切换到第一个界面</router-link>
    <router-link to="/two" tag="button">切换到第二个界面</router-link>
</div>

默认情况下Vue在渲染router-link的时候,是通过a标签来渲染的;

如果不想使用a标签来渲染,可以通过tag属性来告诉vue通过什么标签来渲染

.router-link-active{这个类名是重写当前激活的router-link的标签样式};

也可以通过linkActiveClass自定义激活时的class样式类名,会替换router-link-active类名

const router = new VueRouter({
    routes:routes,
    linkActiveClass:'custom-active'
})

Vue Router传递参数

1.通过url参数的方式传递
<router-link to="/one?name=ok&age=2"></router-link>

可在one的组件的生命周期方法中通过 this. r o u t e . q u e r y . n a m e 和 t h i s . route.query.name 和 this. route.query.namethis.route.query.age 获得参数值

2.通过指定路由规则的方式传参
//指定路由该位置的对应参数接收
const routes = [
    {path:'/one/:name/:age',component: one}
]
传递zhangsan到对应的name 22到对应的age参数
<route-link to="/one/zhangsan/22"></route-link>

嵌套路由

<template id="one">
	<div>
        <p>one组件</p>
        <router-link to="/one/onesub1">子组件1界面</router-link>
        <router-link to="/one/onesub2">子组件2界面</router-link>
        <!--匹配到的路由渲染到这里-->
        <router-view></router-view>
    </div>
</template>
<template id="onesub1">
	<div>子组件1界面</div>
</template>
<template id="onesub2">
	<div>子组件2界面</div>
</template>
1.定义组件
const onesub1 = {
    template:'#onesub1'
}
const onesub2 = {
    template:'#onesub2'
}
const one = {
    template:'#one',
    component:{
        onesub1:onesub1,
        onesub2:onesub2
    }
}
2.定义切换路由规则

如果是嵌套路由的子路由,不用再写一级路由的地址,也不用斜杠

const routes = [
    {
        path:'/one',
        component:one,
        children:[
            {
                //one下面嵌套的子路由
                path:'onesub1',
                component:onesub1
            },
            {
                paht:'onesub2',
                component:onesub2
            }
        ]
    },
    //以下方式不会进行嵌套,会直接覆盖页面
    //{path:'/one/onesub1',component:onesub1},
    //{path:'/one/onesub2',component:onesub2}
]

命名视图

和匿名插槽一样,如果指定了多个标签,多个标签内的内容是一样的.

const routes = [
    {
        path:'/',
        components:{
            key: value,
            name1:one,
            nam2,two
        }
    }
]

使用

<router-view name="name1" ></router-view>
<router-view name="name2" ></router-view>

这样就可以显示不同的组件

watch属性

watch属性属于vue实例对象

let vue = new Vue({
	el:'#app',
	data:{
		num1:0,
	},
	watch:{
		//要监听的属性名称
        num1:function(newValue,oldValue){
            console.log("属性变更值",newValue);
            console.log("属性变更前的值",oldValue);
        }
	}
})

使用:监听路由

vue.$route.path 当前路由地址

watch:{
	"$route.path":function(newval,oldval){
        console.log("切换路由后地址",newval)
        console.log("切换路由前地址",oldval)
    }
}

生命周期

创建阶段

beforeCreated:还未初始化data和methods方法

created:此时已初始化了data和methods,此时还没有编译模板

beforeMount:根据data中的数据生成HTML,但是还没有挂载到页面上

mounted:data中的数据已挂载到页面

运行阶段

beforeUpdate:

​ 该生命周期被调用时,表示Vue实例中保存的数据被修改了;

​ 只有保存的数据被修改了才会调用beforeUpdate,否则不会调用

​ 调用时数据已经更新了,页面还未渲染更新

updated:数据与页面都已更新后调用此生命周期函数

销毁阶段

Vue生命周期方法在组件中也可以使用,使用v-if切换组件可使组件销毁与创建

beforeDestroy: 当前组件即将销毁了;只要组件不被销毁,beforeDestroy就不会被处触发;此生命周期是最后能访问到data数据和方法的函数

destroyed:当前组件已经被销毁了,不要在此生命周期函数中操作数据与方法了.

Vue特殊特性

ref

想要拿到DOM元素,可以通过ref来获取;

Vue并不推荐使用原生操作DOM,如:

document.querySelector('p')

this.$refs 获取

<p ref='mypp'>p元素</p>
this.$refs.mypp; //获取mypp元素

Vue组件渲染方式

<div id="app">
    <!-- <one></one> 未使用render渲染,则在#app的控制区域中-->
</div>
<template id="one">
	<div>
        我是组件1
    </div>
</template>
<script>
    Vue.component("one",{
        template:"#one"
    });
	let vue = new Vue({
        el:'#app',
        render:function(createElement){
            let html = createElement("one"); //将组件名称传入,此时返回组件的元素就不在控制区域#app中
            return html;
        }
    })
</script>

Vue CLI

node环境中 安装

npm install -g @vue/cli

创建项目

vue create project-name

查看版本

vue --version

打包运行

根据package.json文件内 scripts 内的serve属性可知

npm run serve

进行启动运行

打包

npm run build

多一个dist的打包文件夹

文件结构

Vue-CLI2.x 版本是有build文件夹和config 文件夹;里面存储了webpack的相关配置

Vue-CLI3之后没有build和config文件夹

node_modules:存储了相关的依赖包

public:静态资源,不会经过webpack,要用绝对路径来引用它们,一般存永不变的静态资源或webpack不支持的第三方库

src:代码文件夹

​ assets:项目中自己的一些静态文件(图片/字体)

​ component:自定义组件(小组件)

​ views:自定义组件(页面级大组件)

​ router:存储VueRouter相关文件

​ store:存储Vuex相关文件

​ App.vue:根组件

​ main.js :入口

Vue-CLI中使用VueX 与vue-router

src - store目录中 index.js

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

main.js中

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

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

APP.vue

<template>
  <div id="app">
    {{ msg }}
    <button @click="getName">获取vueX的NAME</button>
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
    <!-- <One></One> -->
  </div>
</template>

<script>
// import One from './components/one.vue'
export default {
  name: "App",
  data: function () {
    return {
      msg: "你好",
    };
  },
  methods:{
    getName(){
      console.log(this.$store.state.NAME)
    }
  },
  components:{
    // One:One
  }
};
</script>

<style lang="scss">
</style>

配置Vue-CLI的webpack配置

Vue-CLI对webpack原有的属性进行了一层封装

如在vue.config.js中

const webpack = require('webpack')
module.exports={
  lintOnSave:false,//取消eslint校验
  outputDir:'bundle',// 修改打包输出目录
  configureWebpack:{
    // 原生的配webpack配置
    plugins:[
      new webpack.BannerPlugin({
        banner: 'Kid' //打包文件加印记
      })
    ]
  }
}

如果封装的webpack属性不能满足需求可以通过configureWebpack使用原生的webpack配置

elementUI

安装 npm方式

npm install element-ui -s

在main.js中 引入 并使用

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

即可在页面中使用饿了么UI组件库

<template>
  <div>
    <el-row>
      <el-button>默认按钮</el-button>
      <el-button type="primary">主要按钮</el-button>
      <el-button type="success">成功按钮</el-button>
      <el-button type="info">信息按钮</el-button>
      <el-button type="warning">警告按钮</el-button>
      <el-button type="danger">危险按钮</el-button>
    </el-row>
  </div>
</template>
elementUI 优化

按需导入,按需打包;首先,安装 babel-plugin-component:

npm install babel-plugin-component -D

修改babel.config.js

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

main.js中 按需使用

import { Button, Select } from 'element-ui';
Vue.use(Button);
Vue.use(Select);

mint UI (elementUI的移动端组件库)

npm安装

npm i mint-ui -s

main.js 完整引入

import MinUI from 'mint-ui'
import 'mint-ui/lib/style.css'

Vue.use(MintUI)

此组件库按需引入与elementui不相同

import {Button} from 'mint-ui'
import 'mint-ui/lib/style.css'

Vue.component(Button.name,Button);

Vue-Plugin

Vue.use使用插件;如果想通过此方向来注册组件,需先将组件封装成插件

如果将一个组件封装成一个插件,必须提供一个install方法;那么必须在install方法中注册当前组件

如:在src下的plugin文件夹下创建组件文件夹Loading,内有Loading.vue组件文件和index.js文件

index.js

import Vue from 'vue'
import Loading from './Loading'

export default{
    install:function(){
        Vue.component(Loading.name,Loading)
    }
}

在main.js

import Loading from './plugin/Loading/Loading'

Vue.use(Loading);

以上可以在页面中通过使用

我们可以不使用组件调用的方式使用:

src/plugin/loading/index.js

import vue from 'vue'
import Loading from './Loading'

export default{
    install:function(){
        //1.根据我们的组件生成一个构造函数
        let LoadingContructor = Vue.extend(Loading);
        //2.根据构造函数创建实例对象
        let LoadingInstance = new LoadingConstructor();
        //3.随便创建一个标签(元素)
        let oDiv = document.createElement('div');
        //4.将创建好的标签添加到界面上
        document.body.appendChild(oDIv)
        //5.将创建好的实例对象挂载到创建好的元素上
        LoadingInstance.$mount(oDiv)
        
        //添加全局方法
        Vue.showLoading = function(){
            LoadingInstance.isShow = true;
        }
        /*
        在页面中可以通过Vue.showLoading()调用
        */
        
        //添加实例方法
        Vue.prototype.$showLoading = function(){
            LoadingInstance.show = true;
        }
        /*
        在页面中可以通过this.$shhowLading() 使用
        */
    }
}

Vue.use有第二个参数:1:注册插件2:可选对象

Vue.use(Loading,{
	title:"加载中"
})

插件中的install函数可以接收两个参数

install(Vue,options){
    //options传入的对象
    LoadingInstance.title = options.title//就可以根据参数赋值到组件中
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值