内置指令
v-text 1. 作用:向其所在的节点中渲染文本内容 2. 与插值语法的区别:v-text会替换节点中的内容,{{xx}}不会。
<body>
<div id="main">
<div>你好,{{name}}</div>
<!-- v-text会将标签体的内容覆盖 -->
<div v-text="name">你好,</div>
<div v-text="str"></div>
</div>
<script>
new Vue({
el: "#main",
data: {
name: '筱筱',
str:'<h3>潇潇</h3>'
}
})
</script>
</body>
v-html 1. 作用:内容按普通HTMl插入,不会作为Vue模板进行编译 2. 与插值语法的区别 1. v-html会替换掉节点中所有的内容,{{xx}}不会 2. v-html可以识别识别html结构 3. 严重注意:v-html有安全性问题!!! 1. 在网站上动态渲染任意HTML是非常危险,容易导致XSS攻击 2. 一定要在可信的内容上使用v-html,永远不要用在用户提交的内容上。
<body>
<div id="main">
<div>你好,{{name}}</div>
<div>{{str}}</div>
<div v-html="name"></div>
<div v-html="str"></div>
</div>
<script>
new Vue({ v-cloak
1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
2. 使用CSS配合v-cloak可以解决网速慢时页面展示{{xxx}}的问题
v-once
1. v-once所在节点在初次动态渲染后,就视为静态内容了
2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
el: "#main",
data: {
name: '筱筱',
str:'<h3>潇潇</h3>'
}
})
</script>
</body>
v-cloak 1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性 2. 使用CSS配合v-cloak可以解决网速慢时页面展示{{xxx}}的问题。
<head>
<meta charset="UTF-8">
<title>23-v-cloak</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="main">
<div v-cloak>{{name}}</div>
</div>
<script id="demo" src="../js/vue.js"></script>
<script>
setTimeout(function(){
new Vue({
el: "#main",
data: {
name: '筱筱',
}
})
},5000)
</script>
</body>
v-once 1. v-once所在节点在初次动态渲染后,就视为静态内容了 2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<body>
<div id="main">
<h2 v-once>初始化的 n 值是:{{n}}</h2>
<h2>当前的 n 值是:{{n}}</h2>
<button @click="n ++">点我 n + 1</button>
</div>
<script>
new Vue({
el: "#main",
data:{
n: 1
}
})
</script>
</body>
v-pre 1. 跳过其所在的节点的编译过程 2. 可利用它跳过:没有使用指令语法,没有使用插值语法的节点,会加快编译。
<body> <div id="main"> <h2 v-pre>Vue其实很简单{{n}}</h2> <h2>当前的 n 值是:{{n}}</h2> <button @click="n ++">点我 n + 1</button> </div> <script> new Vue({ el: "#main", data:{ n: 1 } }) </script> </body>
自定义指令 1. 定义语法 1. 局部指令: new Vue({ditectives:{指令名: 配置对象} }) 或 new Vue({directives(){指 令名: 回调函数} }) 2. 全局指令: Vue.directive(指令名, 配置对象) 或 Vue.directivce(指令名, 回调函数) 2. 配置对象中常用的3个回调函数 1. bind: 指令与元素成功绑定时调用 2. inserted: 指令所在元素被插入页面时掉用 3. update: 指令所在模板结构被重新解析时调用 3. 说明 1. 指令定义不加 v- ,但使用要加 v2. 指令名如果是多个单词,要使用 kebab-case 命名方式,不要用camelCase 命名。
<body>
<!--
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大十倍
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦
点
-->
<div id="main">
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>放大十倍后的n值是:<span v-big="n"></span></h2>
<button @click="n++">点我 n + 1</button>
<hr>
<input type="text" v-fbind:value="n" />
</div>
<script>
new Vue({
el: "#main",
data:{
n: 1
},
directives:{
// big什么时候会被调用
// 1、指令与元素成功绑定时
// 2、指令所在的模板被重新解析时
big(element, binding){
element.innerText = binding.value * 10
console.log(element, binding.value);
console.log(element instanceof HTMLElement);
},
fbind:{
//1、指令与元素成功绑定时
bind(element, binding){
element.value = binding.value
},
//2、指令所在元素被插入页面时
inserted(element, binding){
element.focus()
},
//3、指令所在的模板被重新解析时
update(element, binding){
element.value = binding.value
}
}
}
})
</script>
</body>
生命周期 1. 又名:生命周期回调函数,生命周期函数,生命周期钩子 2. 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数 3. 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写 4. 生命周期函数中的this指向的vm 或 组件实例对象。
<body>
<div id="main">
<h2 v-if="s">你好啊</h2>
<h2 :style="{opacity}">学习Vue</h2>
</div>
<script>
new Vue({
el: "#main",
data:{
s: false,
opacity: 1
},
methods: {
},
// Vue完成模板的解析并把初始的真实DOM元素放入页面后,(完成挂载)调用mounted
mounted() {
console.log("mounted");
setInterval(() => {
this.opacity -= 0.01;
if(this.opacity <= 0){
this.opacity = 1;
}
}, 16);
},
})
</script>
</body>
分析生命周期 1. 常用的生命周期钩子: 1. mounted:发送ajax请求,启动定时器,绑定自定义事件,订阅消息等[初始化操作] 2. beforeDestroy:清除定时器,解绑自定义事件,取消订阅消息等[收尾工作] 2. 关于销毁Vue实例 1. 销毁后借助Vue开发者工具看不到任何消息 2. 销毁后自定义事件会失效 3. 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了
<body>
<div id="main">
<!-- 4、开始解析模板模板 template -->
<h2>当前的n值是:{{n}}</h2>
<button @click="add">点我n+1</button>
<button @click="bye">点击销毁</button>
</div>
<script>
const vm = new Vue({
// 3、开始解析Vue模板,生成虚拟DOM - 页面还不能显示解析好的内容 - 方式1
el: "#main",
// 4、开始解析模板
// template: `<div><h2>当前的n值是:{{n}}</h2>
// <button @click="add">点我n+1</button></div>`,
data:{
n: 1
},
methods: {
add(){
console.log("add");
this.n++
},
bye(){
console.log("destroy");
this.$destroy();
}
},
watch:{
n(){
console.log("n变了");
}
},
// 1、初始化生命周期、事件、数据代理还未开始执行 - 此时还无法通过vm访问到data中
数据,methods中的方法
beforeCreate() {
console.log("beforeCreate");
// console.log(this);
// debugger
},
// 2、初始化数据检测,数据代理 - 可以通过vm访问
created() {
console.log("beforeCreate");
// debugger
},
// 5、页面挂载前执行 - 页面重现的是未经Vue编译的DOM解构
beforeMount() {
console.log("beforeMount");
// debugger
},
// 6、完成挂载 - 页面呈现的是经过Vue编译的DOM
mounted() {
console.log("mounted");
// debugger
},
// 以上是完成挂载操作
// 7、当数据改变时
beforeUpdate() { //此时数据是新的,但页面是旧的
console.log("beforeUpdate");
// console.log(this.n);
// debugger
},
updated() { //此时数据是新的,页面也是新的
console.log("updated");
// debugger
},
// 8、销毁 - 收尾操作,
beforeDestroy() {
console.log("beforeDestroy");
this.add();
this.n = 20;
// debugger
},
destroyed() {
console.log("destroyed");
// debugger
},
})
// 3、开始解析Vue模板 - 方式2
// vm.$mount("#main")
</script>
</body>
Vue组件化编程
什么是组件化 面对复杂问题的处理方式 任何一个人处理信息的逻辑能力都是有限的 所以当面对一个非常复杂的问题时,我们不太可能一次性搞定一大堆内容哦个 但是我们人有一种天生的能力,就是将问题进行拆解, 如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在一个整体当中,你会发现大 的问题也会迎刃而解 组件化也是类似的思想 如果我们将一个页面中所有的逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的 管理以及扩展 但如果将一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分的独立的功能,那么 之后整个页面的管理和维护就变得非常容易。
非单文件组件 Vue中使用组件的三大步骤 1. 定义组件(创建组件) 1. 如何定义一个组件 1. 使用 Vue.extend(options) 创建,其中options和new Vue(options)时传入的那个 options几乎一样,区别如下 1. el不要写,为什么?--最终所有的组件都要经过一个vm容器, 由vm中的el决定服 务哪个容器 2. data必须写成函数,为什么?--避免组件被复用时,数据存在引用关系 2. 注册组件 1. 局部注册:靠new Vue的时候传入components选项 2. 全局注册:靠Vue.component('组件名', 组件) 3. 使用组件(写组件标签) 1. 4. 几个注意点 1. 关于组件名 1. 一个单词组成 1. 第一种写法(首字母小写):school 2. 第二种写法(首字母大写):School 2. 多个单词组成 1. 第一种写法(kebab-case命名):my-school 2. 第二种写法(CamelCase命名):MySchool(需要脚手架支持) 3. 说明 1. 组件名尽可能回避HTML中已有的元素名称如:h2, H2 都不行 2. 可以使用name配置项指定组件在开发者工具中呈现的名字 2. 关于组件标签 1. 第一种写法:
<school></school>
2. 第二种写法:
<school/>
3. 说明:不需要脚手架时, 会导致后续组件不能渲染
<body>
<div id="main">
<!-- 3、编写组件标签 -->
<hello></hello>
<hr>
<school></school>
<hr>
<student></student>
</div>
<div id="main2">
<hello></hello>
</div>
<script>
// 1、创建school组件
const school = Vue.extend({
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
`,
//
data(){
return {
schoolName: "网盒教育",
address: "集美区",
}
}
})
// 1、创建student组件
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data() {
return {
studentName: "张三",
age: 20
}
},
})
// 1、创建hello组件
const hello = Vue.extend({
template:`
<div>
<h2>你好啊Tom</h2>
</div>
`,
})
// 2、注册组件(全局)
Vue.component('hello',hello);
new Vue({
el: "#main",
// data:{
// schoolName: "网盒教育",
// address: "集美区",
// studentName: "张三",
// age: 20
// }
// 2、注册组件(局部注册)
components:{
school,
student
}
})
new Vue({
el: "#main2",
})
</script>
</body>
父子组件