Vue.js实战学习笔记(中)

时间:2021-01-20 01:28:18

1.递归组件
给组件设置name属性,组件就可以在它的模板内调用自己,但必须给一个条件来限制递归数量。
<div id="app">
<child-component :count="1"></child-component>
</div>
Vue.component('child-component',{
name:'child-component',
props:{
count:{
type:Number,
default:1
}
},
template:`<div class="child">
<child-component :count="count+1" v-if="count<3"></child-component>
</div>`
})
var app = new Vue({
el:"#app"
})

2.内联模板

在使用组件时,给组件标签使用inline-template特性,组件就会把它的内容当做模板,而不是把它的内容分发。
在父组件声明的数据和在子组件声明的数据都可以渲染上,作用域难理解,不能轻易使用。

3.动态组件
用元素<template>的is特性动态挂载不同的组件。
<div id="app">
<component :is="currentView"></component>
<button @click="handleChangeView('A')">切换到A</button>
<button @click="handleChangeView('B')">切换到B</button>
<button @click="handleChangeView('C')">切换到C</button>
</div>
var app = new Vue({
el:'#app',
components:{
comA:{
template:'<div>组件A</div>'
},
comB:{
template:'<div>组件B</div>'
},
comC:{
template:'<div>组件C</div>'
}
},
data:{
currentView:'comA'
},
methods:{
handleChangeView(component){
this.currentView = 'com'+component;
}
}
})

4.异步组件
vue.js允许将组件定义为一个工厂函数,动态解析组件。
vue.js只在组件需要渲染时触发工厂函数,并将结果缓存起来,用于再次渲染。
<div id="app">
<child-component></child-component>
</div>
Vue.component('child-component',function(resolve,reject){
window.setTimeout(function(){
resolve({
template:'<div>我是异步渲染的</div>' //工厂函数接收一个resolve回调
})
},2000);
});
var app = new Vue({
el:'#app'
})

5.$nextTick
Vue异步更新DOM;
用$nextTick能知道什么时候DOM更新完成
this.$nextTick(...)

6.X-Template
Vue提供了另一种定义模板的方式:
在<script>标签里使用text/x-template类型,并指定一个id,将id赋值给template
<script type="text/x-template" id="my-component">
<div>这是组件的内容</div>
</script>
在<script>标签内可以直接写HTML代码,不用考虑换行问题,但不建议使用。

7.手动挂载实例
Vue提供Vue.extend和$mount两个方法来手动挂载一个实例
Vue.extend是基础Vue构造器,创建一个“子类”,参数是一个包含组件选项的对象。
如果Vue实例在实例化时没有el选项,就处于“未挂载”状态,用$mount手动挂载一个未挂载的实例。
<div id="mount-div"></div>
var myComponent = Vue.extend({
template:'<div>Hello:{{name}}</div>',
data(){
return{
name:'lyf'
}
}
});
new myComponent().$mount('#mount-div');

8.watch监听
watch选项用来监听某个prop或data的改变,当它们发生变化,就会触发watch配置的函数

9.自定义指令
全局注册:
Vue.directive('focus',{
//指令选项
})
局部注册:
var app = new Vue({
el:'#app',
directives:{
focus:{
//指令选项
}
}
})
10.自定义指令的选项
自定义的选项是由几个钩子函数组成的,每个都是可选的
bind:只调用一次,指令第一次绑定到元素时调用,可以定义一个在绑定时执行一次的初始化动作。
inserted:被帮顶元素插入父节点时调用。
update:被帮顶元素所在的模板更新时调用,不论绑定值是否变化。
componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
unbind:只调用一次,指令与元素解绑时调用。

11.实时时间转换指令v-time

12.render函数
在Vue组件里可以这样写:
Vue.component('my-component',{
props:{},
render:function(createElement){
return createElement(
'h'+this.level,
[
createElement(
'a',
{
domprops:{
href:'#'+this.title
}
},
this.$slots.default
)
]
)
}
});
var app = new Vue({
el:'#pp'
})
render函数通过createElement参数来创建虚拟DOM

13.createElement用法
createElement构成了Vue虚拟DOM的模板,有三个参数:
第一个参数必选,可以是一个HTML标签、一个组件或函数;第二个参数可选,是数据对象,在template中使用;第三个参数可选,是子节点。
之前对于v-bind:class、v-bind:style、v-bind:click等都是放在组件的template选项的元素标签上,使用render函数后,可以这样写:
Vue.component('ele',{
render:function(createElement){
return createElement(
'div',
{
//动态绑定class,同:class
class:{
'show':this.show
},
//普通HTML特性
attrs:{
id:'element'
},
//给div绑定click事件
on:{
click:this.handleClick
},
},
'文本内容'
)
}
})

14.函数化组件
使用函数化组件时,render函数提供第二个参数context来提供临时上下文。组件需要的data、props等都是通过这个上下文来传递的,比如this.level会改写成context.props.level。

15.JSX
Vue.js提供babel-plugin-transform-vue-jsx来支持JSX语法。
new Vue({
el:'#app',
render(h){
return (
<Anchor level={1}>
<span>一级</span>标题
</Anchor>
)
}
})
这里使用了ES5语法缩写了函数,参数h不能省略。

16.export和import
用来导出和导入模块,一个模块就是一个js文件

17.webpack基础配置
首先在桌面新建一个目录demo,输入命令npm init,之后生成一个package.json文件;
之后本地局部安装webpack:
npm install webpack --save-dev
然后再在本地局部安装webpack-dev-server:
npm install webpack-dev-server --save-dev
操作之后,package.json文件里多了一项配置:
"devDependencies": {
"webpack": "^4.39.3",
"webpack-dev-server": "^3.8.0"
}

18.箭头函数
render:h=>h(App)
等同于render:function(h){ return h(Aapp) }
等同于render:h=>{ return h(App) }

19.前端路由和v-router
通过npm安装vue-router:
npm install --save vue-router
使用:
import VueRouter from 'vue-router';
Vue.use(VueRouter);

在ES6中使用let和const声明变量,作用域是块

20.跳转router-link
<router-link to="/about">跳转到about</router-link>
to是一个prop,指定需要跳转的路径
其他prop:
tag:可以指定渲染成什么标签 tag="li"
replace:使用replace不会留下history记录,所以导航后不能用后退键返回上一个页面
active-class:可以修改默认的名称

还有一种:this.$router.push()
JavaScript中的:window.location.href()

21.router.beforeEach
某些页面需要校验是否登录,登录了可以访问,否则跳转到登录页面,通过localstorage来简易判断是否登录
router.beforeEach((to,from,next)=>{
if(window.localStorage.getItem('token')){
next();
}else{
next('/login');
}
})

22.状态管理vuex
用npm安装vuex:
npm install --save vuex
使用:
import Vuex from 'vuex';
Vue.use(Vuex);
数据放在vuex的state里:
export default new Vuex.store({
state:{
count:0
}
})
然后在任何组件内可以用$store.state.count读取:
<div>{{ $store.state.count }}</div>
在业务中用到时一般会先在计算属性中读取到,然后再绑定到组件上进行渲染页面:
<div>{{count}}</div>
computed:{
count(){
return this.$store.state.count;
}
}
要想修改state中的数据,需要vuex的第二个选项mutations:
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state){
state.count ++
},
decrease(state){
state.count --
}
}
})
在组件内通过this.$store.commit方法来执行mutations
比如在index.vue页面有两个按钮用来加减,每个按钮有个方法,在每个方法里就可以执行mutations里的两个方法了:
handleIncrement(){
this.$store.commit('increment')
}
handleDecrease(){
this.$store.commit('decrease')
}
mutations还有第二个参数,第二个参数可以是固定值也可以是一个对象,也可以是当没有传入参数是固定值,传入参数就是该参数:
mutations:{
increment(state,n=1){
state.count += n;
}
}
mutations:{
increment(state,n){
n = n||1;
state.count += n;
}
}
mutations:{
increment(state,params){
state.count += params.count;
}
}

23.this.$nextTick( function () {} )
等页面dom全部加载完之后执行这个函数,Vue自带的函数。
this.$nextTick(function () {
_this.tableHeight = _this.$utils.tableHeight (_this.$refs.addbtn.offsetHeight,_this.$refs.card.offsetHeight,148)
})