mixin
混入是非常灵活的技术用来分发Vue 组件中的可复用功能。一个混入对象可以包含任意组件选 项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项.
var mixin = {
data:function(){
return {
info:"this is a mixin"
}
},
created(){console.log("this is mixin created");},
methods:{
foo(){
return "this is mixin foo";
}}
}
new Vue({
el:"#app",
mixins:[mixin],
data:{msg:"hello"},
created(){
console.log("this is vue created");
},
methods:{
foo(){
return "this is vue foo";
}
}
})
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。mixin常用于插件开 发,例如vue-router,vuex就是用到了mixin
合并的原则:
- 数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先
- 同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用
- 值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲 突时,取组件对象的键值对
mixin混入的方式
- 全局混入
Vue.mixin({ created: function () {} })
- 局部混入
let mixin = {
data:{
}
}
mixins: [mixin]
基于以上对mixin的知识点,有了以下实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>mixin混入</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
{{msg}}
</div>
<script>
//混入(对象)
let mixin = {
//数据
data() {
return {
//数据冲突时,以组件的数据优先
mixinMsg: 'mixin数据',
obj: {
name: 'zhangsan'
}
}
},
//生命周期
created() {
console.log("混入的created")
},
//方法
methods: {
//当组件中没有的时候将会合并到组件中methods中的键值对
mixinSendMsg() {
console.log("mixin的mixinSendMsg方法")
},
//当组件中的methods也具有相同的方法时,以组件的为主
test() {
console.log("mixin的test方法")
}
}
//原型方法
};
//Vue.mixin(mixin) 表示全局混入
let vm = new Vue({
el: "#app",
// 局部混入
mixins: [mixin],
data: {
msg: "hello",
obj: {
age: 15
}
},
created() {
console.log("creat创建")
},
methods: {
test() {
console.log("组件的test方法")
}
}
})
</script>
</body>
</html>
directive
指令允许我们对普通 DOM 元素进行底层操作。可以全局注册也可以局部注册
- 全局注册
<input v-focus>
Vue.directive("focus",{
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素,el为DOM中的Element元素
el.focus()
}
})
- 局部注册
new vue({
.........
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
})
钩子函数
钩子函数可以在指令的生命周期内的关键时刻加入代码
bind(){}
只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
bind(el,binding,vnode,oldNode){}
inserted(){}
被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update(){}
所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。componentUpdated(){}
指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind(){}
只调用一次,指令与元素解绑时调用。
钩子函数的参数
el:
dom元素
binding:
对象,指令的详细参数
vnode:
Vue 编译生成的虚拟节点。
oldVnode:
上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
基于自定义指令的知识点,下面给出一个完整的实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
{{msg}}
</div>
<script>
let myModel = {
bink() { },
inserted() { },
//vnode更新
updata() { },
//组件更新调用
componentUpdated() {
},
//解绑的时候调用
unbink() {
}
};
//全局注册 v-mymodel
Vue.directive('mymodel', myModel)
new Vue({
el: "#app",
components: {},
//局部注册
directives: {
myModel
},
data: {
msg: "hello"
}
})
</script>
</body>
</html>
过滤器 filter
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind表达式过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示
过滤器的注册方式
- 全局注册
Vue.filter('fmtDate',
function(date){
return date?moment(date).format('YYYY-MM-DD HH:mm'):'';
});
{{ birthday | fmtDate }}
- 局部注册
filters: {
fmtDate: function(date){
return date?moment(date).format('YYYY-MM-DD HH:mm'):'';
} }
{{ birthday | fmtDate }}
基于上述关于过滤器的知识点,下面给出一个完整的实例,帮助理解:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
{{msg}}
<div v-for="item in arr" :key="item.time">
<span>{{item.name}}</span>
<span>{{item | parseTime}}</span>
</div>
</div>
<script>
//全局注册过滤器 {{arr|parseTime}}
// Vue.filter('parseTime', (date) => {
// //date
// return new Date(date).toLocaleString();
// })
new Vue({
el: "#app",
//
filters: {
// parseTime(date) {
// return new Date(date).toLocaleString();
// }
parseTime(date) {
console.log(date)
return date.name === "zhangsan" ? date.time : ''
}
},
data: {
msg: "hello",
arr: [
{
name: 'zhangsan',
time: 1600676621255
},
{
name: 'lisi',
time: 1600676621888
},
{
name: 'wangwu',
time: 1600676621555
}
],
}
})
</script>
</body>
</html>
渲染函数 render
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器
<anchored-heading :level="1">Hello world!</anchored-heading>
Vue.component('anchored-heading', {
props: { level: { type: Number, required: true } } })
render: function (createElement) {
return createElement(
// 该方法用于创建虚拟节点
vnode 'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)},
createElement
该函数用于创建虚拟节点即vnode.
createElement(nodeName,props,childVnode)
参数说明:
nodeName
: 标签名props
: 该元素的配置信息
‘class’、style、attrs、props、domProps、On、nativeOn
childVnode
: 子虚拟节点,一般为数组,表示其子元素有多个
jsx
如果你写了很多 render 函数,可能会觉得其语法相对比较繁琐,在 Vue 中使用 JSX 语法,它 可以让我们回到更接近于模板的语法上
new Vue({
el: '#demo',
render: function (h) {
return (
<div> <span>Hello</span> world! </div> )
}
})
注意点:jsx的测试需要放到脚手架中进行
插件
插件通常用来为 Vue 添加全局功能。Vue.js 的插件应该暴露一个 install 方法。这个方法的 第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
new Vue({
MyPlugin.install = function (Vue, options) { Vue.myGlobalMethod = function ()
{
// 逻辑...
} // 1. 添加全局方法或
property Vue.directive('my-directive', {}) // 2. 添加全局资源
Vue.mixin({ created: function () { // 逻辑...
} ... }) // 3. 注入组件选项
Vue.prototype.$myMethod = function (methodOptions) { // 逻辑...
} // 4. 添加实例方法
}
组件使用的时候,通过在new Vue之前调用Vue.use()方法
Vue.use(MyPlugin)