主要方向 Java后端,vue.js 仅为兴趣学习归纳,可能存在错误请谨慎参照。
文档缩略(作大纲用,不代替文档)
整体简化,不易理解的部分例出
模板语法(HTML中声明)
- {{ }} : 普通文本插值
- v-once : 只插值一次(非持续动态绑定数据对象和值)
- v-html : 输出为 HTML
- v-bind :
- 响应式更新 attribute
- :class
- 可以传递一个对象,动态切换 class
- 例 v-bind:class=”{active: isActive}” ,active 存在与否依赖于绑定的 isActive 的 truthiness
- 传入更多字段切换多个 class
- 例 v-bind:class=”{active: isActive, ‘text-danger’: hasError}”
- 不必内联定义
- 例 v-bind:class = “classObject”
- data : {classObject : {active: true ,’text-danger’: false}}
- 可以传入数组
- 例 v-bind:class=”[activeClass, errorClass]”
- 可以传递一个对象,动态切换 class
- :style 传递 style
- 例 v-bind:style=”{color: a, fontSize: b + ‘px’}”
- 例 v-bind:style=”styleObject”
- 例 v-bind:style=”[baseStyles, overridingStyles]” 应用多个样式
- :key 用于跟踪每个节点的身份,从而重用和重新排序元素(请使用基本类型)
- 例 v-for=”item in items” v-bind:key=”item.id”
- v-if : 根据参数值条件性渲染内容,搭配 v-else、v-else-if (紧跟在 v-if 后)
- 通过<template v-if=””></template>包裹可以用 v-if 渲染一整组
- v-show : 被渲染,仅切换
- v-on : 监听参数为事件
- 绑定事件后,会调用 methods 中定义的对应方法
- 例 <button v-on:click=”greet”>Greet</button>
- 内联处理器中的方法
- 例 <button v-on:click=”say(‘hi’)”>Say hi</button>
- 使用 $event 访问原始的 DOM 事件
- 例 <button v-on:click=”warn(‘Form cannot be submitted yet.’, $event)”>
- warn: function (message, event) {} (warn方法可以调用到 event)
- v-on 提供了事件修饰符,去解决上面需要自行传入 event 并操作的问题(请注意顺序)
- 例 <button v-on:click.prevent=”warn(‘Form cannot be submitted yet.’)”>
- 绑定事件后,会调用 methods 中定义的对应方法
- [] : 用方括号括起来的 JS 表达式作为参数(先从 JS 获得值,注意这里不需要双引号)
- key : 不复用元素(重新渲染)
- v-for :
- 使用数组渲染列表
- 例 <li v-for=”item in items” :key=”item.message”> {{ item.message }} </li>
- 对应 items: [ { message: ‘Foo’ }, { message: ‘Bar’ } ]
- 添加当前项的索引
- 例 <li v-for=”(item, index) in items”> {{ parentMessage }} – {{ index }} – {{ item.message }} </li>
- 遍历一个对象的 property
- 例 <ul id=”v-for-object” class=”demo”> <li v-for=”value in object”> {{ value }} </li> </ul>
- 例 <div v-for=”(value, name) in object”> {{ name }}: {{ value }} </div> (提供了键名,还可以添加索引)
- 通过计算属性,显示过滤或处理后版本,但不更变原始数据
- 例 <li v-for=”n in evenNumbers”>{{ n }}</li>
- 例 <ul v-for=”set in sets”> <li v-for=”n in even(set)”>{{ n }}</li> </ul>
- 接受一个整数
- 例 <span v-for=”n in 10″>{{ n }} </span>
- 搭配<template>实现一段内容的循环渲染
- 例 <template v-for=”item in items”><li>{{ item.msg }}</li></template>
- 搭配 v-if (不推荐在同一元素使用,for 优先级大于 if)
- 例 <li v-for=”todo in todos” v-if=”!todo.isComplete”> {{ todo }} (同一元素)
- 例 <ul v-if=”todos.length”> <li v-for=”todo in todos”> {{ todo }} (if 在外层)
- 使用数组渲染列表
- v-model :
- 例 <input v-model=”message” placeholder=”edit me”>
备注:Truthy 不是 true,Falsy 值包括:false、undefined、null、正负0、NaN、””,其余都是 truthy 。
vm 属性
- el : 绑定HTML对应作用范围
- data : 参数和值
- computed : 计算属性,处理复杂逻辑
- methods : 方法
- watch : 侦听器,适用于开销较大的异步
实践遭遇问题
组件复用
//组件复用时请使用:
data: function () {
return {
count: 0
}
}
//而不是:
data: {
count: 0
}
//因为函数的作用域,每个实例都会维护自己函数内的 count,而直接创建在 data 中的 count 会被共同持有。
- prop : 自定义 attribute 并可以接收赋值,赋值之后可以类似于 data 被调用。
- 父级组件可以通过 v-on 监听子组件实例的任意事件
- 例 <blog-post … v-on:enlarge-text=”postFontSize += 0.1″ >
- 子组件调用 $emit 方法并传入事件名对事件进行触发 <button v-on:click=”$emit(‘enlarge-text’)”>
- 可以通过 $event 提供值
- 例 <button v-on:click=”$emit(‘enlarge-text’, 0.1)”>
- 父级组件监听时通过 $envent 访问到值 <blog-post … v-on:enlarge-text=”postFontSize += $event” >
组件注册
// 全局注册
Vue.component('my-component-name', {
// ... 选项 ...
})
// 局部注册
var ComponentA = { /* ... */ }
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
}
})
局部注册的组件在其子组件中不可用
基础组件可以通过 require.context 实现自动化全局注册。
父子组件交互
背景:登录框的 v-show 绑定在父组件中,登录框的关闭按钮需要改变其父组件对应的值。
解决:.sync 绑定 prop
例:
<!-- 在 LoginBox 组件中先定义 boxVisible 与父组件中的 loginBoxVisible 相互绑定 -->
<template>
<LoginBox v-show=loginBoxVisible :boxVisible.sync="loginBoxVisible">
</template>
/**
* 然后就可以通过在子组件的 JavaScript 逻辑中调用 this.$emit('update:')
* 对父组件中的 loginBoxVisible 进行更新
*/
this.$emit('update:boxVisible', false);
组件替换
背景:登录完成后,注册相关按钮组件要整个被替换成登录后的按钮组件。
解决:<component :is=”loginTransGroup”>
/**
* 声明当前所使用的组件,然后将其向 html 中 :is= 绑定的变量赋值
*/
export default {
name: "main-nav",
components: {
BeforeLoginGroup,
UserBar
},
data() {
return {
loginTransGroup: BeforeLoginGroup
}
},
methods: {
loginIn() {
this.loginTransGroup = UserBar;
},
signOut() {
this.loginTransGroup = BeforeLoginGroup;
}
}
}
隔代组件交互
背景:在上个问题的基础上,对登录框父组件(用户按钮组)又进行了一次组件封装,因而要求在登录成功后在Grand组件中整个替换其父组件(未登录登录注册按钮组变成登录后的按钮组),就要求孙组件的值能够传达到Grand组件中。
解决:$attrs 与 $listeners ,这里只用到 $listeners
例:
<!-- Grand组件中定义了@loginIn 和 @signOut 两个方法 -->
<component :is="loginTransGroup" @loginIn="loginIn" @signOut="signOut"></component>
JavaScript:
methods: {
loginIn(userInfo) {
this.isLogin = true;
this.loginTransGroup = UserBar;
this.userId = userInfo.userId;
this.userNickname = userInfo.userNickname;
},
}
<!-- 父组件中,对子组件声明了 v-on="$listeners" -->
<LoginBox v-show=loginBoxVisible :boxVisible.sync="loginBoxVisible" v-on="$listeners"></LoginBox>
/**
* 在 LoginBox 组件中可以通过 $emit("loginIn") 进行调用,可以传参
*/
context.$emit("loginIn", userInfo);
这里要注意一点,login 按钮点击方法中使用 axios 进行异步交互,就不能直接调用 this.$emit() 了,因为在 axios 中上下文已经切换了,应该在点击方法中保存上下文对象,如 let context = this; 之后就可以在 axios 中调用 context.$emit() 。
axios 简单异步通信
demo 的后端接口使用 JSON rawType
axios.post("/user/login",{userAcct: this.user.acct,userPswd: this.user.pswd})
.then(function (response) {
if (response.data.success === true) {
let userInfo = response.data.data;
console.log(userInfo);
context.$message({
message: "欢迎回来," + userInfo.userNickname + "。",
type: "success"
});
context.$emit("loginIn", userInfo);
} else {
context.loginButtonLoading = false;
context.$message({
message: response.data.message,
type: "warning"
});
}
})
.catch(function (err) {
console.log(err);
})
},
