当前位置: 首页 > news >正文

网站域名是啥免费的crm管理系统

网站域名是啥,免费的crm管理系统,山东网络推广网站,整站seo排名公司1.Vue基础原理#xff1a; #xff08;1#xff09;vue.js中有两个核心功能#xff1a;响应式数据绑定#xff0c;组件系统 #xff08;2#xff09;MVC,MVP,MVVM之间的区别和理解#xff1b; *****MVC#xff1a; 1) 视图(View):用户界面2) 控制器(Controller)#…1.Vue基础原理 1vue.js中有两个核心功能响应式数据绑定组件系统 2MVC,MVP,MVVM之间的区别和理解 *****MVC 1) 视图(View):用户界面2) 控制器(Controller)业务逻辑3) 模型(Model)数据保存 MVC各个部分之间的通信方式如下 1)视图传送指令到控制器2)控制器完成业务逻辑后要求模型改变状态3)模型将新的数据发送到视图用户得到反馈 以上的所有通信都是单向的接受用户指令的时候MVC有两种方式。一种是通过视图接受指令然后传递给控制器另一种是用户直接给控制器发送指令 实际使用中可能更加灵活下面是Backbone.js为例说明 1) 用户可以向视图View发送指令DOM事件再由View直接要求Model改变状态;2) 用户也可以向Controller发送指令(改变URL触发hashChange事件再由Controller发送给View3) Controller很薄只起到路由作用而View非常厚业务逻辑都放在View,所以Backbone索性取消了Controller只保留了Router(路由器) *****MVPMVP适用于 事件驱动的应用架构中如asp.net web formwindow forms应用 1)各部分之间的通信都是双向的2)视图(View)和模型(Model)不发生联系都是通过表现(Presenter)传递的3)View非常薄不部署任何业务逻辑称之为被动视图(Passive View)即没有任何主动性而Presenter非常厚所有逻辑都在这里 *****MVVM: MVVM模式将Presenter层替换为ViewModel其他与MVP基本一致示意图如下 1) 它和MVP的区别是采用双向绑定视图层(View)的变动自动反映在ViewModel反之亦然Angular和VueReact采用这种方式2) MVVM的提出源于WPF,主要用于分离应用界面层和业务逻辑层WPFSiverlight都基于数据驱动开发3) MVVM模式中一个ViewModel和一个View匹配完全和View绑定所有View中的修改变化都会更新到ViewModel中同时ViewModel的任何变化都会同步到View上显示之所以自动同步是ViewModel的属性都实现了observable这样的接口也就是说当使用属性的set方法会同时出发属性修改的事件使绑定的UI自动刷新 3数据双向绑定的流程 1) 建立虚拟DOM Tree通过document.createDocumentFragment()遍历指定根节点内部节点根据{{prop}},v-model等规则进行compile(主要负责给node节点赋值);2) 通过Object.defineProperty()进行数据变化拦截3) 截取到的数据变化通过发布者-订阅者模式触发Watcher从而改变虚拟DOM中的具体数据;订阅发布模式又称为观察者模式定义一种一对多的关系让多个观察者同时监听一个主题对象主题对象状态发生改变的时候通知所有的观察者。发布者发出通知 主题对象收到通知并推送给订阅者 订阅者执行相应的操作 4) 通过改变虚拟DOM元素值从而改变最后渲染dom树的值完成双向绑定 完成数据双向绑定的关键在于Object.defineProperty() Vue的数据驱动主要实现建立在是三个对象上 Dep( 主题对象 )WatcherCompiler Dep 主要负责依赖的收集Watcher 主要负责Dep和Compiler之间的联系Compiler 可以理解为virtual dom虚拟DOM  patch 也就是负责视图层的渲染 4简易双绑首先我们把注意力集中到这个属性上 Object.defineProperty Object.defineProperty()方法会直接在一个对象上定义一个新属性或者修改一个对象的现有属性并返回这个对象语法Object.defineProperty(obj,prop,descriptor)obj:要在其上定义属性的对象 prop:要定义或者修改的属性名字 descriptor:将定义或修改的属性描述符 举例如下 var obj {}; Object.defineProperty(obj,hello,{   //这里整个都是属性描述符get:function(){//我们在这里拦截到了数据console.log(get方法被调用);},set:function(newValue){//改变数据的值拦截下来额console.log(set方法被调用);} }); obj.hello//输出为“get方法被调用”输出了值。 obj.hello new Hello;//输出为set方法被调用修改了新值 通过以上方法可以看出 获取对象属性值触发get设置对象属性值触发set因此我们可以想象到数据模型对象的属性 设置和读取可以驱动view层的数据变化view的数据变化传递给数据模型对象在Set里面可以做很多事情。 在这基础上我们可以做到数据的双向绑定 let obj {};Object.defineProperty(obj, name, {set: function(newValue){console.log(触发setter);document.querySelector(.text-box).innerHTML newValue;document.querySelector(.inp-text).value newValue;},get: function(){console.log(触发getter);}});document.querySelector(.inp-text).addEventListener(keyup, function(e){obj.name e.target.value;}, false); html: input classinp-text typetext div classtext-box/div 以上只是 Vue的核心思想通过对象底层属性的set和get进行数据拦截vue的虚拟DOM又是怎么实现的呢且看以下分解 5虚拟DOM树 *****创建虚拟DOM的关键var frag   document.createDocumentFragment() DocumentFragment文档片段 可以看做是 节点容器 它可以包含多个子节点可以把它插入到DOM中只有它的子节点会插入目标节点所以可以把它看做是一组节点容器。使用DocumentFragment处理节点 速度和性能优于直接操作DOM 。Vue进行编译的时候就是将 挂载目标的所有子节点劫持到DocumentFragment 中进过处理后再将DocumentFragment 整体返回到挂载目标 *****view层的{{msg}}和 v-model的HTML如下 div idcontainer{{ msg }}input classinp-text typetext v-modelinpTextdiv classtext-boxp classshow-text{{ msg }}/p/div /div *****view层的{{msg}}和 v-model的编译规则如下 var container document.getElementById(container);//这里我们把vue实例中的data提取出来更加直观var data {msg: Hello world!,inpText: Input text};var fragment virtualDom(container, data);container.appendChild(fragment);//虚拟dom创建方法将目标盒子内所有子节点添加到其内部注意这里只有子节点function virtualDom(node, data){let frag document.createDocumentFragment();let child;// 遍历dom节点while(child node.firstChild){compile(child, data);frag.appendChild(child);}return frag;}//编译规则子节点通过compile进行编译a如果节点为元素其nodeType 1b:如果节点为文本其nodeType 3 function compile(node, data){let reg /\{\{(.*)\}\}/g;if(node.nodeType 1){ // 标签let attr node.attributes;for(let i 0, len attr.length; i len; i){// console.log(attr[i].nodeName, attr[i].nodeValue);if(attr[i].nodeName v-model){let name attr[i].nodeValue;node.value data[name];   //给node节点赋值data}}if(node.hasChildNodes()){node.childNodes.forEach((item) {compile(item, data); // 递归如果第二步子节点仍有子节点通过hasChildNodes()来确认如果有递归调用Compile方法});}}if(node.nodeType 3){ // 文本节点if(reg.test(node.nodeValue)){let name RegExp.$1;name name.trim();node.nodeValue data[name];}}} 6响应式原理 第一步核心思想Object.defineProperty(obj,key,{set,get})----定义访问器属性 function defineReact(obj, key, value){Object.defineProperty(obj, key, {set: function(newValue){console.log(触发setter);value newValue;console.log(value);},get: function(){console.log(触发getter);return value;}});} 第二步这里只是针对data数据的属性的响应式定义从数据出发去理解原理数据驱动但是如何去实现 vue实例vm绑定data每个属性通过以下方法 function observe(obj, vm){Object.keys(obj).forEach((key) {defineReact(vm, key, obj[key]);   //定义访问器属性})} 第三步vue的构造函数到这里就实现了Vue实例绑定data属性 function Vue(options){this.data options.data;let id options.el;observe(this.data, this); // 将每个data属相绑定到Vue的实例上this} 第四步如何去实现Vue实例化Vue var vm new Vue({el: container,data: {msg: Hello world!,inpText: Input text}});console.log(vm.msg); // Hello world!console.log(vm.inpText); // Input text 第五步要实现第四步的效果必要前提是在Vue内部初始化虚拟Dom function Vue(options){this.data options.data;let id options.el;observe(this.data, this); // 将每个data属相绑定到Vue的实例上this//------------------------添加以下代码let container document.getElementById(id);let fragment virtualDom(container, this); // 这里通过vm对象初始化container.appendChild(fragment);} 第六步至此我们已经实现了 dom的初始化 下一步我们在v-model元素添加监听事件这样就可以通过view层的操作来修改vm对应的属性值在compile编译的时候可以准确的找到v-model属性元素因此我们把监听事件添加到compile内部 function compile(node, data){let reg /\{\{(.*)\}\}/g;if(node.nodeType 1){ // 标签let attr node.attributes;for(let i 0, len attr.length; i len; i){// console.log(attr[i].nodeName, attr[i].nodeValue);if(attr[i].nodeName v-model){let name attr[i].nodeValue;node.value data[name];// ------------------------添加监听事件node.addEventListener(keyup, function(e){data[name] e.target.value;}, false);// -----------------------------------}}if(node.hasChildNodes()){node.childNodes.forEach((item) {compile(item, data);});}}if(node.nodeType 3){ // 文本节点if(reg.test(node.nodeValue)){let name RegExp.$1;name name.trim();node.nodeValue data[name];}}} 第七步 这一步我们操作页面输入框可以看到以下效果证明监听事件添加有效。 到这里我们已经实现了MVVM 即 Model - vm - View || View - vm - Model  中间桥梁就是vm实例对象 7进一步完善响应式数据绑定引入观察者模式原理 *****订阅者三个订阅者都有update方法 var subscribe_1 {update: function(){console.log(This is subscribe_1);}};var subscribe_2 {update: function(){console.log(This is subscribe_2);}};var subscribe_3 {update: function(){console.log(This is subscribe_3);}}; *****发布者发布者通过notify方法对订阅者广播订阅者通过update来接受信息 function Publisher(){this.subs [subscribe_1, subscribe_2, subscribe_3]; // 添加订阅者}Publisher.prototype {constructor: Publisher,notify: function(){      this.subs.forEach(function(sub){sub.update();})}}; *****实例化publisher: var publisher new Publisher();publisher.notify();*****创建中间件来处理发布者-订阅者模式var publisher new Publisher();var middleware {publish: function(){publisher.notify();}};middleware.publish(); 8观察者模式嵌入 我们已经实现了,接下来要实现更新视图同事把订阅-发布者模式嵌入 1) 修改 v-model 属性元素  - 触发修改vm的属性值  - 触发set 2) 发布者添加订阅  -  notify分发订阅  - 订阅者update数据 *****发布者 function Publisher(){this.subs []; // 订阅者容器}Publisher.prototype {constructor: Publisher,add: function(sub){this.subs.push(sub); // 添加订阅者},notify: function(){this.subs.forEach(function(sub){sub.update(); // 发布订阅});}}; *****订阅者 考虑到要把订阅者绑定data的每个属性来观察属性的变化参数name参数可以有compile中获取的name传参 由于传入的node节点类型分为两种可以分为两个订阅者来处理同时可以对node节点类型进行判断通过switch分别处理 function Subscriber(node, vm, name){this.node node;this.vm vm;this.name name;}Subscriber.prototype {constructor: Subscriber,update: function(){let vm this.vm;let node this.node;let name this.name;switch(this.node.nodeType){case 1:node.value vm[name];  //赋值功能移到了订阅者这里break;case 3:node.nodeValue vm[name];  //赋值功能移到了订阅者这里break;default:break;}}}; *****我们要把订阅者添加到compile进行虚拟dom的初始化替换掉原来的赋值 function compile(node, data){let reg /\{\{(.*)\}\}/g;if(node.nodeType 1){ // 标签let attr node.attributes;for(let i 0, len attr.length; i len; i){// console.log(attr[i].nodeName, attr[i].nodeValue);if(attr[i].nodeName v-model){let name attr[i].nodeValue;// --------------------这里被替换掉// node.value data[name];new Subscriber(node, data, name);// ------------------------添加监听事件node.addEventListener(keyup, function(e){data[name] e.target.value;}, false);}}if(node.hasChildNodes()){node.childNodes.forEach((item) {compile(item, data);});}}if(node.nodeType 3){ // 文本节点if(reg.test(node.nodeValue)){let name RegExp.$1;name name.trim();// ---------------------这里被替换掉// node.nodeValue data[name];new Subscriber(node, data, name);}}} *****既然是对虚拟dom编译的初始化 Subscriber也要初始化即Subscriber.update因此要对Subscriber作进一步的处理 function Subscriber(node, vm, name){this.node node;this.vm vm;this.name name;this.update();}Subscriber.prototype {constructor: Subscriber,update: function(){let vm this.vm;let node this.node;let name this.name;switch(this.node.nodeType){case 1:node.value vm[name];break;case 3:node.nodeValue vm[name];break;default:break;}}}; *****发布者添加到 defineRect函数来观察数据的变化 function defineReact(data, key, value){let publisher new Publisher();Object.defineProperty(data, key, {set: function(newValue){console.log(触发setter);value newValue;console.log(value);publisher.notify(); // 发布订阅},get: function(){console.log(触发getter);if(Publisher.global){ //这里为什么来添加判断条件主要是让publisher.add只执行一次初始化虚拟dom编译的时候来执行publisher.add(Publisher.global); // 添加订阅者}return value;}});} *****这一步将订阅者添加到发布者容器内 对订阅者改造 function Subscriber(node, vm, name){Publisher.global this;this.node node;this.vm vm;this.name name;this.update();Publisher.global null;}Subscriber.prototype {constructor: Subscriber,update: function(){let vm this.vm;let node this.node;let name this.name;switch(this.node.nodeType){case 1:node.value vm[name];break;case 3:node.nodeValue vm[name];break;default:break;}}}; 2.Vue的状态管理Vuex 1vuex是一个专门为vue.js设计的状态管理模式并且也可以使用devtools进行调试可以多个组件共享状态 简单来说就是 共享的状态用state存放用mutations来操作state但是需要用store.commit来主动式的操作mutations 2举例说明 ***** 在使用vues之前要先安装依赖前提是已经 用Vue脚手架工具构建好项目 cnpm install vuex –save *****在入口文件main.js里需要 引入 vuex注册vuex实例化store把store放在全局的实例化对象里 import Vue from vue import App from ./App //1.引入vuex import Vuex from vuex import Apple from ./components/Apple import Banana from ./components/Banana Vue.config.productionTip false //2.注册 Vue.use(Vuex); //3.实例化store let storenew Vuex.Store({state:{totalPrice:0},mutations:{increment(state,price){state.totalPriceprice},decrement(state,price){state.totalPrice-price}},actions:{increase (context,price){context.commit(increment,price)},decrease (context,price){context.commit(decrement,price)}},getters:{discount(state){return state.totalPrice *0.8;}} }) new Vue({el: #app,//4.把store放在全局的实例化对象里,可以在全局的所有地方用store,components: { App},template: App/ }) *****参数介绍 1) statevuex使用单一状态树那么就可以用一个对象包含全部的应用层级状态所以state就作为数据源2) mutations更改Vuex的store中的状态的唯一方法就是提交mutationsVuex中的mutations非常类似于事件每个mutation都有一个字符串的 事件类型(type)和一个回调函数(handler)这个回调函数就是我们实际进状态更改的地方并且它会接受state作为第一个参数。不能直接调用一个mutation handler这个选项更像是事件注册:当触发一个type为 increment的mutation时就调用handler。要唤醒一个mutation handler需要调用store.commit方法触发相应的type可以向store.commit传入额外的参数这个参数就叫做mutation的载荷。在更多的情况下载荷应该是一个对象这样可以包含更多的字段mutations必须是同步函数那么我们如何来异步的更新state呢?答案就是actions3) actionsactions类似于mutations不同的是actions提交的是mutations而不是直接变更状态这也就形成了actions--mutations--state的过程actions可以包含任意异步操作action 函数接受一个与store实例具有相同方法和属性的context对象因此你可以调用context.commit提交一个mutation或者通过context.state和context.getter来获取state和getter但是如何触发呢答案是store.dispatch4) getters有时候我们需要从store中的state中派生出一些状态getter会暴露为store.getter对象在组件中使用。5) modules除了上边用到的4个参数store还有另一个参数:modules;vuex允许把store进行一个功能拆分分割成不同的模块(module),每个模块都拥有自己的storemutationactiongetters *****App.vue templatediv idappApple/AppleBanana/Bananap 总价{{totalPrice}}/pp 折后价{{discountPrice}}/p/div /template script import HelloWorld from ./components/HelloWorld import Apple from ./components/Apple import Banana from ./components/Banana export default {name: App,components: {HelloWorld,Apple,Banana},computed:{totalPrice(){//由于vuex的状态存储是响应式的所以从store实例中读取状态的最简单方法就是使用计算属性来返回某个状态return this.$store.state.totalPrice},discountPrice(){//getter 会暴露为 store.getters 对象return this.$store.getters.discount    }} } /script *****当一个组件需要获取多个状态的时候将这些状态都声明为计算属性会有些重复和冗余为了解决这个问题我们可以使用mapState辅助函数帮助我们生成计算属性 import { mapState } from vuexcomputed: {...mapState([totalPrice])...}*****Banana.vuetemplate divp{{msg}} 单价{{price}}/p    button clickaddOneadd one/buttonbutton clickminusOneminus one/button /div /template script export default{data(){return{msg:banana,price:15}},methods:{addOne(){                       //addOne()函数调用store.commit方法触发type为increment的mutation//直接commit一个mutationthis.$store.commit(increment,this.price)},minusOne(){                    //minusOne()函数调用store.commit方法触发type为decrement的mutationthis.$store.commit(decrement,this.price)}} } /script *****可以在组件中使用this.$store.commit(xxxx)提交mutation或者使用 mapMutations辅助函数将组件中的methods映射为 store.commit调用 methods:{addOne(){this.increment(this.price)},minusOne(){this.decrement(this.price)},...mapMutations([increment, decrement]) } *****Apple.vue:  action相当于中介 template divp {{msg}}单价{{price}} /p    button clickaddOneadd one/buttonbutton clickminusOneminus one/button /div /template script export default{data(){return{msg:apple,price:5}},methods:{addOne(){                 //addOne()函数里调用store.dispatch方法触发名为increase的action,对应的在increase这个action里再去调用context.commit方法触发type为increment的mutation//dispatch一个action以action作为一个中介再去commit一个mutationthis.$store.dispatch(increase,this.price)},minusOne(){this.$store.dispatch(decrease,this.price)}} } /script *****mutation和actions的区别与联系 1) action只能调用mutation不能直接更改state执行action来分发(dispatch)事件通知store去改变 2) action里可以进行一些异步的操作再去触发mutation 3) mutation里必须是同步的触发操作state
http://www.zqtcl.cn/news/439464/

相关文章:

  • 做的网站必须放做音乐网站的目地
  • 网站备案下来以后怎么做网页万网创始人张向东
  • 怎么做网站官方电话品牌营销策划十大要点
  • 上海自适应网站深圳网络推广外包
  • 网站的建设模式是指什么时候开始外网视频网站做泥声控
  • 免费在线观看电影电视剧网站网站建设公司哪家好 在线磐石网络
  • 域名是建网站之前申请吗怎么查看网站开发语言
  • 网站建设业务的延伸性查企业信息查询平台官网免费
  • 网站如何制作的渭南网站建设推广
  • 网站的ico怎么做简单房地产网站
  • 做室内设计通常上的网站关键词挖掘查询工具爱站网
  • 大理住房和城乡建设部网站为食堂写个网站建设
  • 做网站要icp备案吗软件定制开发 报价
  • 外国网站上做雅思考试dw做网站的导航栏
  • 公司网站建设的作用网站建设网上商城心得体会
  • 珠海网站建设的公司网站生成app
  • 营销网站建设的价格私人网站建设成本
  • 企业网站制作模板免费下载淘宝指数查询官网手机版
  • 做服装外单的网站购物网站首页图片
  • 网站建设到运营赚钱上海网络哪家比较好
  • 做网站要求高吗超炫网站
  • 贵卅省住房和城乡建设厅网站怎么快速仿wordpress站
  • 苏州网站建设排名clef wordpress
  • 罗定建设局网站汽车装饰网站源码
  • 网站用什么切版商城网站怎么建
  • 设计网站公司多少钱wordpress获取所有标签
  • 怎么看一个网站是哪个公司做的电子商务网站设计与规划
  • 邯郸哪里做网站优化网站建设如何排版
  • 济南网站建设设计制作公司找人做网站价格
  • 阿里网站年费续费怎么做分录大型的网站开发