vue笔记之vue核心

246 阅读13分钟

简介

  1. vue(读作 /vju:/,类似view)是一套用于构建用户界面的渐进式框架。
  2. vue不支持IE8及以下版本。
  3. 安装:
    1. 直接下载并用<script> 引入,vue 会被注册为一个全局变量。注意:在开发环镜下不要使用压缩版本,否则会失去所有常见错误相关的警告。
    2. npm 安装:在使用vue构建大型应用时推荐使用npm安装。安装方式:npm install vue --save
    3. 查看vue的版本控制台:vue -V;
  4. vue的优点:
    • 体积小
    • 更高的运行效率
    • 双向数据绑定,让开发者不用再担心操作dom对象,把更多的精力投入到业务逻辑上。
    • 生态丰富、学习成本低。
  5. MVVM:
    • model: 模型,数据对象(data)
    • view:视图,模板页面
    • viewModel:视图模型(vue的实例)

模板语法

模板的理解

  1. 动态的 html 页面
  2. 包含了一些 js 语法的代码
    • 双括号表达式
    • 指令(以 v-开头的自定义标签属性)

双括号表达式

  1. 语法:{{exp}}
  2. 功能:向页面输出数据
  3. 可以调用对象的方法

指令一:强制数据绑定

  1. 功能:指定变化的属性值
  2. 完整写法: v-bind:xxx= 'yyy' //yyy 会作为表达式解析执行。
  3. 简洁写法: :xxx= 'yyy'

指令二:绑定事件监听

  1. 功能:绑定事件名的回调函数
  2. 完整写法:
    • v-on:事件名= 'xxx'
    • v-on:事件名= 'xxx(参数)'
    • v-on:事件名.事件修饰符= 'xxx'
  3. 简洁写法:
    • @事件名= 'xxx'
    • @事件名= 'xxx(参数)'
    • @事件名.事件修饰符= 'xxx'

参考代码:

<div id="app">
    <h2>1. 双大括号表达式</h2>
    <p>{{msg}}</p>
    <p>{{msg.toUpperCase()}}</p>

    <h2>2. 指令一:强制数据绑定</h2>
    <p><a href="url">访问指定站点1</a></p> <!-- 不可用 -->
    <p><a v-bind:href="url">访问指定站点2</a></p>
    <p><a :href="url">访问指定站点3</a></p>

    <h2>指令二:绑定事件监听</h2>
    <button type="button" v-on:click="handleClick">点我1</button>
    <button type="button" @click="handleClick">点我2</button>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {
			msg: 'hello',
			url: 'http://www.baidu.com',
        },
		methods: {
			handleClick() {
				alert('hello word');
			},
        },
    });
</script>

声明式渲染

  1. Vue.js的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进DOM的系统。

插值表达式渲染

  1. 可以通过{{ Mustache }} 插值表达式快速的渲染出元素中的内容
  2. 参考下面的代码
    <div id="app">
        {{ message }}
    </div>
    
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript">
        const app = new Vue({
            el: '#app', // el: element 的简写。'#app' ,表示选中id为app 的元素。
            data: { // data: 存放变量和数据
                message: 'hello word',
            },
        });
    </script>
    
    

v-bind 绑定元素特性

  1. v-bind 特性被称为指令。指令带有前缀 v-, 以表示它们是Vue 提供的特殊属性。 在上面的列子中,该指令的意识是: "将这个元素节点的 title 特性和 Vue实例的 message 属性保存一致"
  2. 参考下面的代码:
    <div id="app">
    <p v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '页面加载于: ' + new Date().toLocaleString(),
        },
    });
    </script>
    

v-text 渲染页面

  1. v-text: 更新元素的 textContent 。如果要更新部分的 textContent ,需要使用 {{ Mustache }} 插值表达式。
  2. 参考下面的代码:
    <p v-text="msg"></p> 
    <!-- 和下面的一样 -->
    <p >{{ msg }}</p>
    
    

v-html 渲染页面

  1. v-html: 更新元素的 innerHTML注意:内容按普通 HTML插入,不会做为 Vue 模板进行编译。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来代替。
  2. 在动态网站上渲染HTML是非常危险的,因为容易导致 xss 攻击。只在可信内容上使用 v-html ,永不用在用户提交的内容上。
  3. 在单文件组件里, scoped 的样式不会用在 v-html 内部,因为那部分HTML没有被vue的模板编译器预处理。如果你希望针对 v-html 的内容设置带作用域的css,可以替换为 css Modules 或用一个额外的全局 <style> 元素手动设置类似 BEM 的作用域策略。
  4. 参考下面代码:
    <p v-html="html"></p>
    

计算属性和监视

计算属性

  1. computed 属性对象中定义计算属性的方法
  2. 在页面中使用 {{方法名}} 来显示计算的结果
  3. 计算属性的方法什么时候调用:
    • 初始化显示时
    • 当相关的data属性数据发生改变的时候。

监视属性

  1. 通过vm对象的 $watch() 或 watch 配置来监视指定的属性。如果指定deep:true 则会启用深度监视
  2. 当属性变化时,回调函数自动调用,在函数内部进行计算。
  3. 不应该使用箭头函数定义 watch 函数

计算属性高级

  1. 通过 getter/setter实现对属性数据的显示和监视
  2. 计算属性存在缓存,多次读取只执行一个getter计算。
  3. getter: 属性的get方法。是一个回调函数,当需要读取当前属性的值时执行。计算相关属性的数据,并返回对应的值
  4. setter: 属性的set(在这里是监视的意思)方法。是一个回调函数,监视当前属性值的变化,当当前属性的值发生变化时执行,更新相关的数据

参考代码

<div id="dome">
    <p>姓:<input type="text" v-model="firstName"></p>
    <p>名:<input type="text" v-model="lastName"></p>
    <p>姓名(单向1):<input type="text" v-model="fullName1"></p>
    <p>姓名(单向2):<input type="text" v-model="fullName2"></p>
    <p>姓名(双向3):<input type="text" v-model="fullName3"></p>

    <ul>
        <li>{{fullName1}}</li>
        <li>{{fullName1}}</li>
        <li>{{fullName1}}</li>
    </ul>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#dome',
		data: {
			firstName: 'A',
			lastName: 'B',
			fullName2: 'A B',
		},
		computed: {
			fullName1() {
				console.log('fullName1');
				return this.firstName + ' ' + this.lastName;
			},

			fullName3: {
				//回调函数,当需要读取当前属性的值时执行。计算相关属性的数据,并返回对应的值
				get() {
					return this.firstName + ' ' + this.lastName;
				},
				//回调函数,监视当前属性值的变化,当当前属性的值发生变化时执行,更新相关的数据
				set(value) {
					[this.firstName, this.lastName] = value.split(' ');
				}
            },
		},

		watch: {
			firstName(newVal, oldVal) {
				this.fullName2 = newVal + ' ' + this.lastName;
			},
		},
	});

	vm.$watch('lastName', (newVal, oldVal) => {
		console.log(this);
		this.fullName2 = this.firstName2 + ' ' + newVal;
	});

Class 与 Style 绑定

理解

  1. 在应用界面中,某个(些)元素的样式是变化的
  2. class/style绑定就是专门用来实现动态样式效果的技术。

class绑定

  1. 语法::class= 'xxx'
  2. 表达式可以是字符串:'classA'
  3. 表达式可以是对象: {classA:isA, classB:isB}
  4. 表达式是数组:[ 'classA', 'classB' ]

style 绑定

  1. 语法::style= "{color:activeColor,fontSize:fontSize+'px' }"
  2. 其中 activeColor/fontSize 是data中的属性

参考代码:

<style>
        .aClass {
            color: red;
        }

        .bClass {
            color: blue;
        }

        .size {
            font-size: 30px;
        }
</style>

<div id="app">
    <h2>class样式绑定</h2>
    <p class="size" :class="aClass">class="XXX"</p>
    <p :class="{aClass:isA,bClass:isB}">class="XXX"</p>
    <p :class="['aClass','size']">class="XXX"</p>

    <h2>style样式绑定</h2>
    <p :style="{color:activeColor,fontSize:fontSize+'px'}">style动态样式绑定</p>

    <button type="button" @click="updata">更新</button>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {
			aClass: 'aClass',
			isA: true,
			isB: false,
			activeColor: 'pink',
			fontSize:'30'
		},
		methods: {
			updata() {
				this.aClass = 'bClass';
				this.isA=false;
				this.isB = true;
			}
        },
    });
</script>

条件与循环

v-show

  1. v-show 根据表达式之真假,切换元素的 display css属性。当条件发生变化时该指令触发过渡效果。如果需要频繁切换 v-show 较好。
  2. 参考下面的代码:
    <div id="app">
        <p v-show="show">展示</p>
        <p v-show="hidden">隐藏</p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                show: true,
                hidden:false,
            },
        });
    </script>
    
    

v-if v-else-if v-else

1.v-if: 根据表达式的值的真假条件渲染元素。在切换时元素的数据绑定/组件被销毁并重建。如果元素是 <template> ,将提出它的内容作为条件块。 2. 当 v-ifv-for 一起使用时,v-for 的优先级比 v-if 更高。 3. v-else:为 v-if 或者 v-else-if 添加 "else 块"。前一兄弟元素必须要有 v-if 或者 v-else-if 4. v-else-if: 表示 v-if 的 "else if 块",可以链式调用。前一兄弟元素必须要有 v-ifv-else-if 5. 参考下面的代码: ```

a

b

c

d

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {},
	});
</script>

```

v-for

  1. v-for :基于源数据多次渲染元素或模板块。此指令之值,必须使用特定语法 alias in expression,为当前遍历的元素提供别名。另外也可以为数组索引指定别名(或者是用于对象的键)

  2. v-for 默认行为试着不改变整体,而是替换元素。

    • 为了给vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,需要为每项提供一个唯一的 key 属性。
    • 建议尽可能在使用 v-for 时提供 key 属性。除非遍历时输出的DOM内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
    • key 属性是vue识别节点的一个通用机制,key 并不仅仅只与 v-for 特别关联,它还具有其它用途。
  3. 使用 v-for 循环数组

    <div id="app">
        <p v-for="(item, index) in list">{{ index }}---{{ item }}</p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
    	const vm = new Vue({
    		el: '#app',
    		data: {
    			list: [1, 2, 3, 4, 5, 6],
    		},
    	});
    </script>
    
    
  4. 使用 v-for 循环对象

    <div id="app">
        <p v-for="(val, key) in info" >{{key}}---{{val}}</p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
    	const vm = new Vue({
    		el: '#app',
    		data: {
    			info: {id:1,name:'小明',age:18, sex: '男'},
            },
        });
    </script>
    
    
  5. 使用 v-for 循环包含数组的对象

    <div id="app">
        <p v-for="(val, key) in list" :key="val.id">
            编号:{{val.id}}    &nbsp;&nbsp;&nbsp;&nbsp;
            姓名:{{val.name}}  &nbsp;&nbsp;&nbsp;&nbsp;
            年龄:{{val.age}}   &nbsp;&nbsp;&nbsp;&nbsp;
            性别:{{val.sex}}   &nbsp;&nbsp;&nbsp;&nbsp;
        </p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
    	const vm = new Vue({
    		el: '#app',
    		data: {
    			list: [
    				{id:1,name:'小明',age:18, sex: '男'},
    				{id:2,name:'小红',age:12, sex: '女'},
    				{id:3,name:'小光',age:13, sex: '男'},
    				{id:4,name:'小花',age:15, sex: '女'},
    				{id:5,name:'小黄',age:11, sex: '男'},
                ],
            },
        });
    </script>
    
    

列表搜索、排序和过滤

  1. 参考代码
<style>
    [v-cloak] {
        display: none;
    }
</style>

<div id="app" v-cloak>
    <input type="text" v-model="searchName">
    <ul>
        <li v- v-for="(item,index) in filterPersons" :key="index">
            {{index}}--{{item.name}}--{{item.age}}
        </li>
    </ul>
    <button @click="orderPerson(1)">按年龄升序</button>
    <button @click="orderPerson(2)">按年龄降序</button>
    <button @click="orderPerson(0)">原本顺序</button>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {
			orderType: 0, // 0表示原有的顺序,1表示升序,2表示降序
			persons: [
				{name: 'jack', age: 18},
				{name: 'tom', age: 16},
				{name: 'toy', age: 19},
				{name: 'alis', age: 17},
			],
			searchName: '',
		},
		computed: {
			// 得到根据searchName过滤后的成员
			filterPersons() {
				console.log(this);
				const {orderType, persons, searchName} = this;

				// 根据searchName过滤数组persons
				const fpersons = persons.filter((v) => {
					return v.name.includes(searchName);
				});

				// 排序
				if (orderType !== 0) {
					fpersons.sort((p1, p2) => {
						if (orderType === 1) { // 1表示升序 要返回负数
							return p1.age - p2.age;
						} else { // 降序 要返回正数
							return p2.age - p1.age;
						}
					});
				}
				return fpersons;
			},
		},
		methods: {
			orderPerson(orderType) {
				this.orderType = orderType;
			}
        },
	});

事件处理

绑定监听:

  1. v-on:xxx= 'fun'
  2. @xxx= 'fun'
  3. @xxx= 'fun(参数)'
  4. 默认事件形参:event
  5. 隐含属性对象:$event

事件修饰符

  1. .prevent:阻止事件的冒泡行为 event.preventDefault()
  2. .stop: 停止事件冒泡 event.stopPropagation()
  3. .selt: 仅当点击绑定事件的对应元素,才触发事件。

按键修饰符

  1. .keycode:操作的是某个keycode值的键
  2. .keyName:操作的某个按键名的键(少部分)

参考代码:

<div id="example">
    <h2>1. 绑定监听</h2>
    <button type="button" @click="test1">test1</button>
    <button type="button" @click="test2('hello')">test2</button>
    <button type="button" @click="test3">test3</button>
    <button type="button" @click="test4(123,$event)">test4</button>

    <h2>2. 事件修饰符</h2>
    <div style="width: 200px;height: 200px;background-color:pink;" @click.self="test5">
        <div style="width: 100px;height: 100px;background-color:purple;" @click.stop="test6"></div>
        <a href="http://www.baidu.com" @click.prevent="test7">去百度</a>
    </div>

    <h2>3. 按键修饰符</h2>
    <input type="text" @keyup.13="test8">
    <input type="text" @keyup.enter="test8">
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#example',
		data: {
			test1() {
				alert('test1');
			},
			test2(msg) {
				alert(msg);
			},
			test3(event) {
				console.log(event);
				alert(event.target.innerHTML);
			},
			test4(msg,event) {
				alert(`${msg}----${event.target.innerText}`);
			},
			test5() {
				alert('test5');
			},
			test6() {
				alert('test6');
			},
			test7() {
				alert('test7');
			},
			test8(event) {
				alert(event.target.value);
			}
        },
    });
</script>

表单数据的自动收集

  1. 对于 input、select[option]和 textarea 表单元素使用 v-model 指令实现双向数据绑定

参考代码:

<div id="app">
    <form action="http://www" @submit.prevent="handleSubmit">
        <div>
            <label for="name">姓名:</label>
            <input type="text" id="name" v-model="formData.name">
        </div>
        <div>
            <label for="password">密码:</label>
            <input type="password" id="password" v-model="formData.password">
        </div>
        <fieldset class="radios">
            <legend>性别:</legend>
            <div>
                <input type="radio" id="male" value="男" v-model="formData.sex">
                <label for="male"></label>
            </div>
            <div>
                <input type="radio" id="female" value="女" v-model="formData.sex">
                <label for="female"></label>
            </div>
        </fieldset>

        <fieldset class="checkbox">
            <legend>爱好:</legend>
            <div>
                <input type="checkbox" id="basketball" value="basketball" v-model="formData.like">
                <label for="basketball">篮球</label>
            </div>
            <div>
                <input type="checkbox" id="football" value="football" v-model="formData.like">
                <label for="football">足球</label>
            </div>
            <div>
                <input type="checkbox" id="pingPong" value="pingPong" v-model="formData.like">
                <label for="pingPong">乒乓球</label>
            </div>
        </fieldset>

        <div>
            <label for="city">城市:</label>
            <select id="city" v-model="formData.cityId">
                <option>未选择</option>
                <option :value="item.id" v-for="(item,index) in allCity" :key="index">{{item.name}}</option>
            </select>
        </div>
        <div>
            <label for="introduce">介绍:</label>
            <textarea cols="30" rows="3" id="introduce" v-model="formData.introduce"></textarea>
        </div>
        <button type="submit">注册</button>
    </form>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {
			allCity: [
				{id:1, name: 'BJ'},
				{id:2, name: 'SH'},
				{id:3, name: 'GD'},
			],
			formData: {
				name: '',
                password:null,
				sex: '女',
				like: ['pingPong'],
				cityId: null,
				introduce:null,
            }

		},
		methods: {
			handleSubmit() {
				console.log(JSON.stringify(this.formData));
			}
		},
	});
</script>

生命周期

生命周期流程图

vue 生命周期流程图

vue 生命周期分析

  1. 初始化显示
    • beforeCreate()
    • created()
    • beforeMount()
    • mounted()
  2. 更新状态:this.xxx= value
    • beforeUpdate()
    • updated()
  3. 销毁 vue 实例:vm.$destroy()
    • beforeDestroy()
    • destroyed()

常用的生命周期方法

  1. mounted(): 发送 ajax 请求,启动定时器等异步任务
  2. beforeDestroy(): 做收尾工作,如:清除定时器。

参考代码

<div id="app" v-cloak>
    <button type="button" @click="detroyVM">destroy vm</button>
    <p v-show="isShow">{{msg}}</p>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {
			isShow: true,
			msg: '每隔一秒显示',

		},

		methods: {
			detroyVM() {
				vm.$destroy();
			}
		},

		//------- 生命周期函数 --------
		// 1. 初始化阶段
		beforeCreate() {
			console.log('beforeCreate');
		},
		created() {
			console.log('created');
		},
		beforeMount() {
			console.log('beforeMount');
		},
		mounted() {
			console.log('mounted');
			this.intervalID = setInterval(() => {
				console.log('--------');
				this.isShow = !this.isShow;
			}, 1000);
		},

		// 2. 更新阶段
		beforeUpdate() {
			console.log('beforeUpdate');
		},
		updated() {
			console.log('updated');
		},

		// 3. 死亡阶段
		beforeDestroy() {
			console.log('beforeDetroy');
			clearInterval(this.intervalID);
		},
		destroyed() {
			console.log('destroyed');
		}

	});
</script>

动画

vue 动画的理解

  1. 操作 csstransitionanimation
  2. vue 会给目标元素添加/移除特定的 class
  3. 过渡的相关类名
    • xxx-enter-active: 指定显示的 transition
    • xxx-leave-active:指定隐藏的 transition
    • xxx-enter/xxx-leave-to: 指定隐藏时的样式
  4. vue 动画流程图:
    vue 动画流程图

基本过渡动画的编码

  1. 在目标元素外包裹 <transition name= "xxx">
  2. 定义class样式
    • 指定过渡样式:transition
    • 指定隐藏时的样式:opacity/其它

参考代码

使用 transition

 <style>
    /*定义显示/隐藏进行中的样式*/
    .xxx-enter-active {
        transition: all 3s;
    }

    .xxx-leave-active {
        transition: all 1s;
    }

    /*指定不显示时大样式*/
    .xxx-enter,
    .xxx-leave-to {
        transform: translateX(30px);
        opacity: 0;
    }
</style>

<div id="app">
    <button @click="isShow=!isShow">toggle</button>
    <transition name="xxx">
        <p v-show="isShow">下一秒我又回来了</p>
    </transition>
</div>

<script src="js/vue.js"></script>
<script>
	const vm = new Vue({
		el: '#app',
		data: {
			isShow: true,
		},
	});
</script>

使用animation

<style>
    .xxx-enter-active {
        animation: bounce 1s;
    }
    .xxx-leave-active {
        animation: bounce 1s reverse;
    }
    @keyframes bounce {
        0% {
            transform: scale(0);
        }
        50% {
            transform: scale(1.5);
        }
        100% {
            transform: scale(1);
        }
    }
</style>

<div id="app2">
    <button @click="isShow=!isShow">toggle</button><br>
    <transition name="xxx">
        <p v-show="isShow" style="display: inline-block">下一秒我又回来了</p>
    </transition>
</div>
<script src="js/vue.js"></script>
<script>
	const vm2 = new Vue({
		el: '#app2',
		data: {
			isShow: true,
		},
	});
</script>

过滤器

理解过滤器

  1. 功能:对要显示的数据进行特定格式化后再显示。
  2. 注意:并没有改变原本的数据,而是产生新的对应的数据。定义全局过滤器要在创建 Vue 实例之前

定义和使用过滤器

  1. 定义过滤器
    Vue.filter(filterName,(value[,arg1,arg2,...)]) => {
        // 进行一定的数据处理
        return newValue;
    });
    
  2. 使用过滤器
<div>{{myData | filterName}}</div>
<div>{{myData | filterName(arg)}}</div>

参考代码

<div id="app" v-cloak>
    <p>完整版:{{date | dateFormat}}</p>
    <p>年月日:{{date | dateFormat('YYYY-MM-DD')}}</p>
    <p>时分秒:{{date | dateFormat('HH:mm:ss')}}</p>
</div>

<script src="js/vue.js"></script>
<script src="js/moment.min.js"></script>
<script>
	Vue.filter('dateFormat', (value, format = 'YYYY-MM-DD HH:mm:ss') => {
		return moment().format(format);
	});
	const vm = new Vue({
		el: '#app',
		data: {
			date: new Date(),
		},
	});
</script>

指令

内置指令

  1. v-text :更新元素的 textContent
  2. v-html :更新元素的 innerHTML
  3. v-if : 如果为true,当前标签才会输出到页面
  4. v-else-if :如果为true,当前标签才会输出到页面
  5. v-else :如果为false,当前标签才会输出到页面
  6. v-show :通过 display 样式来控制显示/隐藏
  7. v-bind :强制绑定解析表达式,可以简写为 :
  8. v-on :绑定事件监听,一般简写为 @
  9. v-for :遍历对象/数组
  10. v-model :双向数据绑定
  11. ref:指定唯一标识,vue对象通过 $refs属性访问这个元素对象
  12. v-cloak:防止闪现,与css配合:[v-cloak]{display:none;}
  13. v-slot:插槽指令

自定义指令

  1. 注册全局指令
    Vue.directive('upper-text', (el,binding) => {
    	el.innerText = binding.value.toUpperCase();
    });
    
  2. 注册局部指令
     // 自定义局部指令
    directives: {
        'lower-text'(el,binding) {
            el.innerText = binding.value.toLowerCase();
        },
    }
    

参考代码

  1. 内置指令

    <style>
        [v-cloak] {
            display: none;
        }
    </style>
    <div id="app" v-cloak>
        <button @click="eject">弹出</button>
        <p ref="news">{{msg}}</p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
        const vm = new Vue({
            el: '#app',
            data: {
                msg: 'hello word',
            },
            methods:{
                eject() {
                    // alert(Vue.$refs);
                    console.log(this.$refs.news.innerText);
                },
            },
        });
    </script>
    
  2. 自定义指令

    <div id="app">
        <p v-upper-text="msg"></p>
        <p v-lower-text="msg"></p>
    </div>
    <div id="app2">
        <p v-upper-text="msg"></p>
        <p v-lower-text="msg"></p>
    </div>
    
    <script src="js/vue.js"></script>
    <script>
        // 自定义全局指令
        // el:指令属性所在的标签对象
        // binding: 包含指令相关信息数据的对象。
        Vue.directive('upper-text', (el,binding) => {
            el.innerText = binding.value.toUpperCase();
        });
        const vm = new Vue({
            el: '#app',
            data: {
                msg: 'DOCTYPE html',
            },
    
            // 自定义局部指令
            directives: {
                'lower-text'(el,binding) {
                    el.innerText = binding.value.toLowerCase();
                },
            }
        });
    
        const vm2= new Vue({
            el: '#app2',
            data: {
                msg: 'DOCTYPE html',
            },
        });
    </script>
    

vue 插件

说明

  1. vue插件是一个包含 install 方法的对象
  2. 通过 install 方法给 Vue 或 Vue 实例添加方法,定义全局指令等

参考代码:

  1. 插件js
    //========== 自定义vue插件 ========
    (function () {
    const MyPlugin = {};
    MyPlugin.install = function (Vue, options) {
    	// 1. 添加全局方法或属性
    	Vue.myGlobalMethod = function () {
    		console.log('全局方法myGlobalMethod()');
    	};
    
    	// 2. 添加全局资源
    	Vue.directive('my-directive', (el, binding) => {
    		el.innerText = binding.value.toUpperCase();
    	});
    
    
    	// 3. 添加实例方法
    	Vue.prototype.$myMethod = function (methodOptions) {
    		console.log('实例方法$myMethod()');
    	};
    };
    
    // 向外暴露 MyPlugin
    window.MyPlugin = MyPlugin;
    })();
    
  2. 页面使用插件
    <div id="app">
        <!--    使用插件定义的指令-->
        <p v-my-directive="msg"></p>
    </div>
    
    <script src="js/vue.js"></script>
    <script src="js/vue-myPlugin.js"></script>
    <script>
    	// 使用插件 MyPlugin
    	Vue.use(MyPlugin); // 内部会执行 MyPlugin.install(Vue)
    	const vm = new Vue({
    		el: '#app',
    		data: {
    			msg: 'I love you',
    		},
    	});
    
    	// 调用插件全局方法
    	Vue.myGlobalMethod();
    
    	// 调用插件实例属性
    	vm.$myMethod();
    </script>