手撸一个 MVVM 不是梦

在实现 VUE 中 MVVM 的系列文章的最后一篇文章中说道:我觉得可响应的数据结构作用很大,在整理了一段时间后,这是我们的最终产出:RD - Reactive Data

ok 回到整理,这篇文章我们不研究 Vue 了,而是根据我们现在的研究成果来手撸一个 MVVM

简单介绍 RD

先看看下我们的研究成果:一个例子

let demo = new RD({
    data(){
        return {
            text: 'Hello',
            firstName: 'aco',
            lastName: 'yang'
        }
    },
    watch:{
        'text'(newValue, oldValue){
            console.log(newValue)
            console.log(oldValue)
        }
    },
    computed:{
        fullName(){
            return this.firstName + ' ' + this.lastName
        }
    },
    method:{
        testMethod(){
            console.log('test')
        }
    }
})

demo.text = 'Hello World'
// console: Hello World
// console: Hello
demo.fullName
// console: aco yang
demo.testMethod()
// console: test

写法上与 Vue 的一样,先说说拥有那些属性吧:

关于数据

  • data
  • computed
  • method
  • watch
  • prop
  • inject/provied

关于生命周期

  • beforeCreate
  • created
  • beforeDestroy
  • destroyed

关于实例间关系

  • parent

实例下的方法:

关于事件

  • $on
  • $once
  • $emit
  • $off

其他方法

  • $watch
  • $initProp

类下方法:

  • use
  • mixin
  • extend

以上便是所有的内容,因为 RD 仅仅关注于数据的变化,所以生命周期就就只有创建和销毁。

对比与 Vue 多了一个 $initProp ,同样的由于仅仅关注于数据变化,所以当父实例相关的 prop 发生变化时,需要手动通知子组件修改相关数据。

其他的属性以及方法的使用与 Vue 一致。

ok 大概说了下,具体的内容可以点击查看

手撸 MVVM

有了 RD 我们来手撸一个 MVVM 框架。

我们先确定我们大致需要什么?

  1. 一个模板引擎(不然怎么把数据变成 dom 结构)
  2. 现在主流都用虚拟节点来实现,我们也加上

ok 模板引擎,JSX 语法不错,来一份。

接着虚拟节点,github 上搜一搜,ok 找到了,点击查看

所有条件都具备了,我们的实现思路如下:

RD + JSX + VNode = MVVM

具体的实现我们一边写 TodoList 一边实现

首先我们得要有一个 render 函数,ok 配上,先来个标题组件 Title 和一个使用标题的 App 的组件吧。

可以对照完整的 demo 查看一下内容,demo。

var App = RD.extend({
  render(h) {
    return (
      
</div> ) } }) var Title = RD.extend({ render(h) { return ( <p className='title'>{this.title}</p> ) }, data(){ return { title:'这是个标题' } } })</code></pre> <p>这里就不说明 <code>JSX</code> 语法了,可以在 <code>babel</code> 上看下转码的结果,点击查看。</p> <p>至于 <code>render</code> 的参数为什么是 <code>h</code> ?这是大部分人都认可这么做,所以我们这么做就好。</p> <p>根据 <code>JSX</code> 的语法,我们需要实现一个创建虚拟节点的方法,也就是 <code>render</code> 需要传入的参数 <code>h</code> 。</p> <p>ok 实现一下,我们编写一个插件使用 <code>RD.use</code> 来实现对于实例的扩展</p> <pre><code>// demo/jsxPlugin/index.js export default { install(RD) { RD.prototype.$createElement = function (tag, properties, ...children) { return createElement(this, tag, properties, ...children) } RD.prototype.render = function () { return this.$option.render.call(this, this.$createElement.bind(this)) } } }</code></pre> <p>我们把具体的处理逻辑放在 <code>createElement</code> 这个方法中,而实例下的 <code>$createElement</code> 仅仅是为了把当前对象 <code>this</code> 传入这个函数中。</p> <p>接着我们把传入的 <code>render</code> 方法包装一下,挂载到实例的 <code>render</code> 方法下,我们先假设这个 <code>createElement</code> 能生成一个树结构,这样调用 实例下的 <code>render()</code> ,就能获得一个节点树。</p> <p>注:这里获得的并不是虚拟节点树,节点树需要涉及子组件,我们要确保这个节点树仅仅和当前实例相关,不然会比较麻烦,暂且叫它是节点模板。</p> <p>ok 我们可以想象一下这节点模板会长什么样?</p> <p>参考虚拟节点的库后,得到这样一个结构:</p> <pre><code>{ tagName: 'div', properties: {className: 'todo-wrap'}, children:[ tagName:'component-1',// 后面的 1 是扩展出来的类的 cid ,每个类都有一个单独的 cid parent: App, isComponent: true, componentClass: Title properties: {}, children: [] ] }</code></pre> <p>原有标签的处理虚拟节点的库已经帮我们做了,我们来实现一下组件的节点:</p> <pre><code>// demo/jsxPulgin/createElemet.js import {h, VNode} from 'virtual-dom' export default function createElement(ctx, tag, properties, ...children) { if (typeof tag === 'function' || typeof tag === 'object') { let node = new VNode() // 构建一个空的虚拟节点,带上组件的相关信息 node.tagName = `component-${tag.cid}` node.properties = properties // prop node.children = children // 组件的子节点,也就是 slot 这里并没有实现 node.parent = ctx // 父节点信息 node.isComponent = true // 用于判断是否是组件 node.componentClass = tag // 组件的类 return node } return h(tag, properties, children) // 一般标签直接调用库提供的方法生成 }</code></pre> <p>现在我们可以通过实例的 <code>render</code> 方法获取到了一个节点模板,但需要注意的是:这个仅仅只能算是通过 <code>JSX</code> 语法获取的一个模板,并没有转换为真正的虚拟节点,这是一个节点模板,当把其中的组件节点给替换掉就能得到真正的虚拟节点树。</p> <p>捋一捋我们现在有的:</p> <ol> <li>实例的 <code>render</code> 函数</li> <li>可以通过 <code>render</code> 函数生成的一个节点模板</li> </ol> <p>接着来实现一个方法,用于将节点模板转化为虚拟节点树,具体过程看代码中的注释</p> <pre><code>// demo/jsxPlugin/getTree.js function extend(source, extend) { for (let key in extend) { source[key] = extend[key] } return source } function createTree(template) { // 由于虚拟节点只接受通过 VNode 创建的对象 // 并且为了保持模板不被污染,所以新创建一个节点 let tree = extend(new VNode(), template) if (template && template.children) { // 遍历所有子节点 tree.children = template.children.map(node => { let treeNode = node // 如果是组件,则用保存的类实例化一个 RD 对象 if (node.isComponent) { // 确定 parent 实例以及 初始化 prop node.component = new node.componentClass({parent: node.parent, propData: node.properties}) // 将模板对应的节点模板指向实例的节点模板,实例下的 $vnode 用于存放节点模板 // 这样就将父组件中的组件节点替换为组件的节点模板,然后递归子组件,直到所有的组件节点都转换为了虚拟节点 // 这里使用了 $createComponentVNode 来获取节点模板,下一步我们就会实现它 treeNode = node.component.$vnode = node.component.$createComponentVNode(node.properties) // 如果是组件节点,则保存一个字段在虚拟节点下,用于区分普通节点 treeNode.component = node.component } if (treeNode.children) { // 递归生成虚拟节点树 treeNode = createTree(treeNode) } if (node.isComponent) { // 将生成的虚拟节点树保存在实例的 _vnode 字段下 node.component._vnode = treeNode } return treeNode }) } return tree }</code></pre> <p>现在的流程是 <code>render => createElement => createTree</code> 生成了虚拟节点,<code>$createComponentVNode</code> 其实就是调用组件的 <code>render</code> 函数,现在我们写一个 <code>$patch</code> 方法,包装这个行为,并且通过 <code>$mount</code> 实现挂载到 <code>DOM</code> 节点的过程。</p> <pre><code>// demo/jsxPlugin/index.js import {create, diff, patch} from 'virtual-dom' import createElement from './createElement' export default { install(RD) { RD.$mount = function (el, rd) { // 获取节点模板 let template = rd.render.call(rd) // 初始化 prop rd.$initProp(rd.propData) // 生成虚拟节点树 rd.$patch(template) // 挂载到传入的 DOM 上 el.appendChild(rd.$el) } RD.prototype.$createElement = function (tag, properties, ...children) { return createElement(this, tag, properties, ...children) } RD.prototype.render = function () { return this.$option.render.call(this, this.$createElement.bind(this)) } // 对 render 的封装,用于获取节点模板 RD.prototype.$createComponentVNode = function (prop) { this.$initProp(prop) return this.render.call(this) } RD.prototype.$patch = function (newTemplate) { // 获取到虚拟节点树 let newTree = createTree(newTemplate) // 将生成 DOM 元素保存在 $el 下,create 为虚拟节点库提供,用于生成 DOM 元素 this.$el = create(newTree) // 保存节点模板 this.$vnode = newTemplate // 保存虚拟节点树 this._vnode = newTree } } }</code></pre> <p>ok 接着我们来调用一下</p> <pre><code>// demo/index.js import RD from '../src/index' import jsxPlugin from './jsxPlugin/index' import App from './component/App' import './index.scss' RD.use(jsxPlugin, RD) RD.$mount(document.getElementById('app'), App)</code></pre> <p>到目前为止,我们仅仅是通过了页面的组成显示出了一个页面,并没有实现数据的绑定,但是有了 <code>RD</code> 的支持,我们可以很简单的实现这种由数据的变化导致视图变化的效果,加几段代码即可</p> <pre><code>// demo/jsxPlugin/index.js import {create, diff, patch} from 'virtual-dom' import createElement from './createElement' import getTree from './getTree' export default { install(RD) { RD.$mount = function (el, rd) { let template = null rd.$initProp(rd.propData) // 监听 render 所需要用的数据,当用到的数据发生变化的时候触发回调,也就是第二个参数 // 回调的的参数新的节点模板(也就是 $watch 第一个函数参数的返回值) // 回调触发 $patch rd.$renderWatch = rd.$watch(() => { template = rd.render.call(rd) return template }, (newTemplate) => { rd.$patch(newTemplate) }) rd.$patch(template) el.appendChild(rd.$el) } RD.prototype.$createElement = function (tag, properties, ...children) { return createElement(this, tag, properties, ...children) } RD.prototype.render = function () { return this.$option.render.call(this, this.$createElement.bind(this)) } RD.prototype.$createComponentVNode = function (prop) { let template = null this.$initProp(prop) // 监听 render 所需要用的数据,当用到的数据发生变化的时候触发 $patch this.$renderWatch = this.$watch(() => { template = this.render.call(this) return template }, (newTemplate) => { this.$patch(newTemplate) }) return template } RD.prototype.$patch = function (newTemplate) { // 由于是新创建和更新都在同一个函数中处理了 // 这里的 createTree 是需要条件判断调用的 // 所以这里的 getTree 就先认为是获取虚拟节点,之后再说 // $vnode 保存着节点模板,对于更新来说,这个就是旧模板 let newTree = getTree(newTemplate, this.$vnode) // _vnode 是原来的虚拟节点,如果没有的话就说明是第一次创建,就不需要走 diff & patch if (!this._vnode) { this.$el = create(newTree) } else { this.$el = patch(this.$el, diff(this._vnode, newTree)) } // 更新保存的变量 this.$vnode = newTemplate this._vnode = newTree this.$initDOMBind(this.$el, newTemplate) } // 由于组件的更新需要一个 $el ,所以 $initDOMBind 在每次 $patch 之后都需要调用,确定子组件绑定的元素 // 这里需要明确的是,由于模板必须使用一个元素包裹,所以父组件的状态改变时,父组件的 $el 是不会变的 // 需要变的仅仅是子组件的 $el 绑定,所以这个方法是向下进行的,不回去关注父组件以上的组件 RD.prototype.$initDOMBind = function (rootDom, vNodeTemplate) { if (!vNodeTemplate.children || vNodeTemplate.children.length === 0) return for (let i = 0, len = vNodeTemplate.children.length; i < len; i++) { if (vNodeTemplate.children[i].isComponent) { vNodeTemplate.children[i].component.$el = rootDom.childNodes[i] this.$initDOMBind(rootDom.childNodes[i], vNodeTemplate.children[i].component.$vnode) } else { this.$initDOMBind(rootDom.childNodes[i], vNodeTemplate.children[i]) } } } } }</code></pre> <p>ok 现在我们大概实现了一个 <code>MVVM</code> 框架,缺的仅仅是 <code>getTree</code> 这个获取虚拟节点树的方法,我们来实现一下。</p> <p>首先,<code>getTree</code> 需要传入两个参数,分别是新老节点模板,所以当老模板不存在时,走原来的逻辑即可</p> <pre><code>// demo/jsxPlugin/getTree.js function deepClone(node) { if (node.type === 'VirtualNode') { let children = [] if (node.children && node.children.length !== 0) { children = node.children.map(node => deepClone(node)) } let cloneNode = new VNode(node.tagName, node.properties, children) if (node.component) cloneNode.component = node.component return cloneNode } else if (node.type === 'VirtualText') { return new VText(node.text) } } export default function getTree(newTemplate, oldTemplate) { let tree = null if (!oldTemplate) { // 走原来的逻辑 tree = createTree(newTemplate) } else { // 走更新逻辑 tree = changeTree(newTemplate, oldTemplate) } // 确保给出一份完全新的虚拟节点树,我们克隆一份返回 return deepClone(tree) } // 具体的更新逻辑 function changeTree(newTemplate, oldTemplate) { let tree = extend(new VNode(), newTemplate) if (newTemplate && newTemplate.children) { // 遍历新模板的子节点 tree.children = newTemplate.children.map((node, index) => { let treeNode = node let isNewComponent = false if (treeNode.isComponent) { // 出于性能考虑,老节点模板中相同的 RD 类,就使用它 node.component = getOldComponent(oldTemplate.children, treeNode.componentClass.cid) if (!node.component) { // 在老模板中没有找到,就生成一个,与 createTree 中一致 node.component = new node.componentClass({parent: node.parent, propData: node.properties}) node.component.$vnode = node.component.$createComponentVNode(node.properties) treeNode = node.component.$vnode treeNode.component = node.component isNewComponent = true } else { // 更新复用组件的 prop node.component.$initProp(node.properties) // 直接引用组件的虚拟节点树 treeNode = node.component._vnode // 保存组件的实例 treeNode.component = node.component } } if (treeNode.children && treeNode.children.length !== 0) { if (isNewComponent) { // 如果是新的节点,直接调用 createTree treeNode = createTree(treeNode) } else { // 当递归的时候,有时可能出现老模板没有的情况,比如递归新节点的时候 // 所以需要判断 oldTemplate 的情况 if (oldTemplate && oldTemplate.children) { treeNode = changeTree(treeNode, oldTemplate.children[index]) } else { treeNode = createTree(treeNode) } } } if (isNewComponent) { node.component._vnode = treeNode } return treeNode }) // 注销在老模板中没有被复用的组件,释放内存 if (oldTemplate && oldTemplate.children.length !== 0) for (let i = 0, len = oldTemplate.children.length; i < len; i++) { if (oldTemplate.children[i].isComponent && !oldTemplate.children[i].used) { oldTemplate.children[i].component.$destroy() } } } return tree } // 获取在老模板中可服用的实例 function getOldComponent(list = [], cid) { for (let i = 0, len = list.length; i < len; i++) { if (!list[i].used && list[i].isComponent && list[i].componentClass.cid === cid) { list[i].used = true return list[i].component } } }</code></pre> <p>ok 整个 <code>MVVM</code> 框架实现,具体的效果可以把整个项目啦下来,执行 <code>npm run start:demo</code> 即可。上诉所有的代码都在 <code>demo</code> 中。</p> <p>我们来统计下我们一共写了几行代码来实现这个 <code>MVVM</code> 的框架:</p> <ul> <li>createElement.js 22行</li> <li>getTree.js 111行</li> <li>jsxPubgin/index.js 65行</li> </ul> <p>所以我们仅仅使用了 <code>22 + 111 + 65 = 198</code> 行代码实现了一个 <code>MVVM</code> 的框架,可以说是很少了。</p> <p>可能有的同学会说这还不算使用 <code>RD</code> 和虚拟节点库呢?是的我们并没有算上,因为这两个库的功能足够的独立,即使库变动了,实现相应的 <code>api</code> 用上面的代码我们同样能够实现,所以黑盒里的代码我们不算。<br>同样的我们也可以这么说,我们使用 <code>198</code> 行的代码连接了 <code>JSX/VNode/RD</code> 实现了一个 <code>MVVM</code> 框架。</p> <h3>谈谈感想</h3> <p>在研究 <code>Vue</code> 源码的过程中,在代码里看到了不少 <code>SSR</code> 和 <code>WEEX</code> 的判断,个人觉得这个没必要。这会导致 <code>Vue</code> 不论在哪段使用都会有较多的代码冗余。我认为一个理想的框架应该是足够的可配置的,至少对于开发人员来说应该如此。</p> <p>所以我觉得应该想 <code>react</code> 那样,在开发哪端的项目就引入相应的库即可,而不是将代码全部都聚合到同一个库中。</p> <p>以下我认为是可以做的,比如在开发 <code>web</code> 应用时,这样写</p> <pre><code>import vue from 'vue' import vue-dom from 'vue-dom' vue.use(vue-dom)</code></pre> <p>在开发 <code>WEEX</code> 应用时:</p> <pre><code>import vue from 'vue' import vue-dom from 'vue-weex' vue.use(vue-weex)</code></pre> <p>在开发 <code>SSR</code> 时:</p> <pre><code>import vue from 'vue' import vue-dom from 'vue-ssr' vue.use(vue-ssr)</code></pre> <p>当然如果说非要一套代码统一 <code>3</code> 端</p> <pre><code>import vue from 'vue' import vue-dom from 'vue-dynamic-import' vue.use(vue-dynamic-import)</code></pre> <p><code>vue-dynamic-import</code> 这个组件用于环境判断,动态导入相应环境的插件。</p> <p>这种想法也是我想把 <code>RD</code> 给独立出来的原因,一个模块足够的独立,让环境的判断交给程序员来决定,因为大部分项目是仅仅需要其中的一个功能,而不需要全部的功能的。</p> <p>以上,更多关于 <code>Vue</code> 的内容,已经关于 <code>RD</code> 的编写过程,可以到我的博客查看</p> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1177163015628337152"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(mvvm,vue.js)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1943919909612351488.htm" title="Vue.js 过渡 & 动画" target="_blank">Vue.js 过渡 & 动画</a> <span class="text-muted">lsx202406</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>Vue.js过渡&动画引言在Web开发中,过渡与动画是提升用户体验的关键元素。Vue.js作为一款流行的前端框架,提供了强大的过渡与动画功能,使得开发者能够轻松实现丰富的交互效果。本文将深入探讨Vue.js中的过渡与动画,包括其原理、应用场景以及实现方法。一、Vue.js过渡原理Vue.js过渡是利用CSS3的transition属性实现的。当Vue.js侦测到数据变化时,会自动触发过渡效果。过渡</div> </li> <li><a href="/article/1943917011268595712.htm" title="Javaweb学习之Vue模板语法(三)" target="_blank">Javaweb学习之Vue模板语法(三)</a> <span class="text-muted">不要数手指啦</span> <a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>目录学习资料前情回顾本期介绍(vue模板语法)文本插值Vue的Attribute绑定使用JavaScript表达式综合实例代码:学习资料Vue.js-渐进式JavaScript框架|Vue.js(vuejs.org)前情回顾项目的创建大家可以看这篇文章Vue学习之项目的创建-CSDN博客本期介绍(vue模板语法)首先,找到我们编写代码的地方找到自己项目的src文件夹,打开之后点击component</div> </li> <li><a href="/article/1943712766313426944.htm" title="android mvvm官方demo,Android mvvm架构demo(DataBinding+LiveData+ViewModel+ Repository)" target="_blank">android mvvm官方demo,Android mvvm架构demo(DataBinding+LiveData+ViewModel+ Repository)</a> <span class="text-muted"></span> <div>1.实现效果实现页面加载Bing每日一图的功能2.项目结构image(忽略没有按分类创建).png3.实现过程1.注入依赖//ViewModel与LiveDataimplementation"android.arch.lifecycle:extensions:1.1.1"//图片加载implementation'com.github.bumptech.glide:glide:4.9.0'//网络请</div> </li> <li><a href="/article/1943708224859467776.htm" title="MVVMDemo:一款现代Android开发的最佳实践示例" target="_blank">MVVMDemo:一款现代Android开发的最佳实践示例</a> <span class="text-muted"></span> <div>MVVMDemo:一款现代Android开发的最佳实践示例本文将向您介绍项目,这是一个基于MVVM(Model-View-ViewModel)架构模式的Android应用实例,旨在帮助开发者更好地理解和应用这一流行的软件设计模式。项目概述MVVMDemo是由zhouxu88维护的一个开源项目,它展示了如何在Android平台上有效地实施MVVM架构。此项目包括了基本的数据绑定、LiveData观测</div> </li> <li><a href="/article/1943707720024649728.htm" title="Android MVVM demo(使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成)" target="_blank">Android MVVM demo(使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel 完成)</a> <span class="text-muted">千雅爸爸</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>使用DataBinding,LiveData,Fresco,RecyclerView,Room,ViewModel完成玩Android开放API-玩Android-wanandroid.com接口使用的是下面的两个:https://www.wanandroid.com/banner/jsonhttps://www.wanandroid.com/banner/jsonwanandroid.com/p</div> </li> <li><a href="/article/1943697014504091648.htm" title="【WPF实战】MVVM中如何从数据模型反查自定义控件实例(ImageView + Halcon)" target="_blank">【WPF实战】MVVM中如何从数据模型反查自定义控件实例(ImageView + Halcon)</a> <span class="text-muted"></span> <div>【WPF实战】MVVM中如何从数据模型反查自定义控件实例(ImageView+Halcon)在使用PrismMVVM架构开发WPF应用时,我们通常遵循“数据驱动UI”的设计原则。但有时,我们希望从数据层反向获取控件实例,比如:✔在后台操作对应的Halcon控件HSmartWindowControlWPF,✔动态控制某一个图像窗口的图层或内容。本篇文章将通过一个实际例子,讲解如何优雅地实现这一反向访</div> </li> <li><a href="/article/1943647350308270080.htm" title="极简Vue 3应用:从入门到掌握核心概念" target="_blank">极简Vue 3应用:从入门到掌握核心概念</a> <span class="text-muted">程序猿全栈の董(董翔)</span> <a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>Vue.js作为一款渐进式JavaScript框架,以其直观的API和灵活的架构受到广泛欢迎。对于初学者而言,Vue官方CLI生成的项目结构可能略显复杂,包含了各种资源文件、样式和示例组件。本文将介绍如何创建一个最简洁的Vue3应用,帮助你专注于核心概念的学习。为什么需要最简Vue应用?VueCLI默认生成的项目包含:assets目录:存放图片、字体等资源components目录:包含多个示例组件</div> </li> <li><a href="/article/1943642181625507840.htm" title="Swift 2.0 下面向协议的MVVM架构实践" target="_blank">Swift 2.0 下面向协议的MVVM架构实践</a> <span class="text-muted"></span> <div>本文由CocoaChina译者lynulzy(社区ID,博客)翻译原文:Swift2.0:Protocol-OrientedMVVM自从令人兴奋的[《面向协议的编程方法》]在Swift的WWDC大会上发布以来。我对协议的使用考虑了很多。但是在现实中,我并没有太多的顾及和使用这些功能。我还仍旧在消化到底面向协议的编程方法是什么,在代码的哪些地方应该使用,而不是使用我目前使用的`go-to`编程方法。</div> </li> <li><a href="/article/1943640289293955072.htm" title="Swift2编程之道:POP+MVVM" target="_blank">Swift2编程之道:POP+MVVM</a> <span class="text-muted">秋雨暗千家</span> <a class="tag" taget="_blank" href="/search/Swift%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/1.htm">Swift学习笔记</a><a class="tag" taget="_blank" href="/search/Swift%E5%A4%A7%E8%AE%B2%E5%A0%82/1.htm">Swift大讲堂</a><a class="tag" taget="_blank" href="/search/pop/1.htm">pop</a><a class="tag" taget="_blank" href="/search/mvvm/1.htm">mvvm</a><a class="tag" taget="_blank" href="/search/swift/1.htm">swift</a><a class="tag" taget="_blank" href="/search/iOS/1.htm">iOS</a> <div>Swift2.0中引入了协议扩展的特性,并且建议开发者一切从协议(Protocol)出发,经过几个月的学习探索,博主发现Swift作为一门面向协议编程(POP)的语言非常适合时下火热的MVVM架构。MVVM已经提出有一段时间了,如果你还不懂什么是MVVM,建议先去补充相关的知识,再回到本文中。在CocoaTouch体系内,MVC是广为人知的经典架构,博主之前也讲解过MVC的相关知识,但是随着业务逻</div> </li> <li><a href="/article/1943594645887971328.htm" title="JavaScript 在前端 UI 框架中的应用与选型" target="_blank">JavaScript 在前端 UI 框架中的应用与选型</a> <span class="text-muted">大厂前端小白菜</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98/1.htm">前端开发实战</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/ui/1.htm">ui</a><a class="tag" taget="_blank" href="/search/ai/1.htm">ai</a> <div>JavaScript在前端UI框架中的应用与选型关键词:JavaScript、前端UI框架、应用、选型、React、Vue.js、Angular摘要:本文深入探讨了JavaScript在前端UI框架中的应用与选型问题。首先介绍了前端UI框架的背景知识,包括目的、预期读者、文档结构等。接着阐述了核心概念,分析了JavaScript与前端UI框架的联系。通过具体的算法原理和操作步骤,结合Python代</div> </li> <li><a href="/article/1943579016548118528.htm" title="uni-app跨平台开发:高效构建多端应用" target="_blank">uni-app跨平台开发:高效构建多端应用</a> <span class="text-muted">2301_81335708</span> <a class="tag" taget="_blank" href="/search/uni-app/1.htm">uni-app</a> <div>引言:开发者之痛-多端开发的十字路口你是否曾为这些难题彻夜难眠?同一业务需维护iOS、Android、Web三套代码小程序平台各异(微信/支付宝/字节跳动),API差异令人抓狂团队技能栈分散,ReactNative、Flutter、原生开发各自为战产品迭代缓慢,50%时间消耗在跨平台适配uni-app:破局者登场由DCloud推出的uni-app基于Vue.js生态,用一套代码同步生成:iOS/A</div> </li> <li><a href="/article/1943558970471936000.htm" title="20 道 Vue 常见面试题,你会几道?(含答案)" target="_blank">20 道 Vue 常见面试题,你会几道?(含答案)</a> <span class="text-muted"></span> <div>你觉得自己最擅长的技术栈是什么?Vue吧,我很喜欢尤大,最近刚发布了Vue的首部纪录片,真的很好看。1.那你能讲一讲MVVM吗?MVVM是Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面</div> </li> <li><a href="/article/1943508158056034304.htm" title="达摩院发布2022十大科技趋势!俺是一个也看不懂鸭!" target="_blank">达摩院发布2022十大科技趋势!俺是一个也看不懂鸭!</a> <span class="text-muted">xhmj12</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/1.htm">编程语言</a> <div>上一篇:MVVM已过时?MVVM升级版:MVI架构来了来源|达摩院/阿里技术 小伙伴们大家好。2021年12月28日,阿里巴巴达摩院发布了2022年的十大科技趋势预测(https://damo.alibaba.com/techtrends/2022),作为一个打工人,俺也第一时间追了一波。虽说很多都看不懂,但是我想着多了解了解趋势和方向总是好的,所以咱们这里也分享一波。这次应该是达摩院连续第四年发</div> </li> <li><a href="/article/1943499967217856512.htm" title="Vue框架基础" target="_blank">Vue框架基础</a> <span class="text-muted">所愿ღ</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>目录一、Vue是什么二、Vue的下载三、Vue的API文档四、vue.js和vue.min.js的区别五、引入外部的vue文件六、vue的标准格式以及在页面上显示数据(第一个vue程序)七、模板语法八、在插值中使用运算符九、获取对象的属性十、条件渲染十一、列表渲染(遍历数组/集合)十二、在vue中使用事件十三、图片切换一、Vue是什么1.vue是渐进式JavaScript框架,用于构建用户界面,可</div> </li> <li><a href="/article/1943439203765383168.htm" title="WePY 框架:小程序开发的“Vue式”利器!!!" target="_blank">WePY 框架:小程序开发的“Vue式”利器!!!</a> <span class="text-muted">小丁学Java</span> <a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8FWxMa/1.htm">微信小程序WxMa</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/notepad%2B%2B/1.htm">notepad++</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>WePY框架:小程序开发的“Vue式”利器哈喽,大家好!今天我们要聊聊一个在微信小程序开发中大放异彩的框架——WePY!它是什么?有什么特点?为啥值得一试?别急,带上好奇心,跟我一起探索吧!WePY是什么?WePY(微信小程序增强框架,WeChatMiniProgramFramework)是一个开源框架,由腾讯团队开发,旨在让小程序开发更高效、更现代化。简单来说,它把Vue.js的开发体验带到了微</div> </li> <li><a href="/article/1943377194654953472.htm" title="快速分页wpf" target="_blank">快速分页wpf</a> <span class="text-muted">lph1972</span> <a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a> <div>/*没有在xaml设置上下文window.context是因为命名空间一直对应不上所以在xaml.cs里面绑定*/NextusingBogus;usingCommunityToolkit.Mvvm.ComponentModel;usingCommunityToolkit.Mvvm.Input;usingSystem;usingSystem.Collections.Generic;usingSyst</div> </li> <li><a href="/article/1943376941562261504.htm" title="命令绑定非默认事件" target="_blank">命令绑定非默认事件</a> <span class="text-muted">lph1972</span> <a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a> <div>导入NuGet包必须Install-PackageMicrosoft.Xaml.Behaviors.Wpfxmlns:i="http://schemas.microsoft.com/xaml/自己的命名空间一般clr-namespace:系统的一般就是类似网址这里必须用隧道事件preview用冒泡没反应就记住mvvm绑定非默认事件只能用隧道</div> </li> <li><a href="/article/1943374672703844352.htm" title="工程改Mvvm" target="_blank">工程改Mvvm</a> <span class="text-muted">lph1972</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a> <div>导入CommunityToolKitvs2017只能导入7usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingCommunityToolkit.Mvvm.ComponentModel;usingCommunityToolkit.M</div> </li> <li><a href="/article/1943358285306458112.htm" title="【C#】MVVM知识点汇总-2" target="_blank">【C#】MVVM知识点汇总-2</a> <span class="text-muted">Mike_Wuzy</span> <a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a> <div>在C#中实现MVVM(Model-View-ViewModel)架构时,可以总结以下几个关键知识点,并通过具体的代码示例来进行说明。1.模型(Model)模型包含应用程序中的数据和业务逻辑。通常与数据库交互。publicclassUser{publicintId{get;set;}publicstringName{get;set;}publicintAge{get;set;}}2.视图(View)</div> </li> <li><a href="/article/1943334960446369792.htm" title="uniapp页面间通信相关方法总结" target="_blank">uniapp页面间通信相关方法总结</a> <span class="text-muted">前端达人</span> <a class="tag" taget="_blank" href="/search/vue/1.htm">vue</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/js/1.htm">js</a> <div>文章整理于:https://ask.dcloud.net.cn/article/35970uni-app是一个使用vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。利用url传参进行通讯A页面向B页面传递参数uni.navigateTo({url:'test/te</div> </li> <li><a href="/article/1943170450041401344.htm" title="Android MVVM架构与数据绑定:深入实战与技巧" target="_blank">Android MVVM架构与数据绑定:深入实战与技巧</a> <span class="text-muted">码上有潜</span> <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0%E6%9C%AC/1.htm">笔记本</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a> <div>AndroidMVVM架构与数据绑定:深入实战与技巧MVVM(Model-View-ViewModel)模式是Android开发中常用的一种高效架构模式,尤其是在结合Android架构组件时,可以极大简化代码结构和提高可维护性。本篇博文将带你深入了解MVVM架构的原理与**数据绑定(DataBinding)**技术,提供丰富的代码示例,帮助你从基础掌握到高级实战。1.MVVM架构概述MVVM架构模</div> </li> <li><a href="/article/1943046533628882944.htm" title="用Vue Flow绘制一个完美流程图" target="_blank">用Vue Flow绘制一个完美流程图</a> <span class="text-muted">itanly</span> <a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E6%B5%81%E7%A8%8B%E5%9B%BE/1.htm">流程图</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>VueFlow简介VueFlow是一个基于Vue.js的流程图库,专为构建交互式流程图设计。它支持节点拖拽、连线、缩放、撤销/重做等功能,适用于工作流、系统架构图等场景。以下内容将演示如何用VueFlow绘制一个完整的流程图,并提供代码示例。安装与基础配置确保项目已安装Vue3,使用以下命令安装VueFlow:npminstall@vue-flow/core基础配置示例:import{VueFlo</div> </li> <li><a href="/article/1943033300671066112.htm" title="Vue入门" target="_blank">Vue入门</a> <span class="text-muted">LUO-CHEn</span> <a class="tag" taget="_blank" href="/search/Java%E6%B8%A9%E9%A6%A8Talk/1.htm">Java温馨Talk</a><a class="tag" taget="_blank" href="/search/vue/1.htm">vue</a> <div>vue1、vue概述(1)概念vue.js(读音/vjuː/,类似于view)是一套构建用户界面的渐进式框架。Vue只关注视图层,采用自底向上增量开发的设计。随着项目业务场景的复杂,传统模式(html+jquery)已无法满足需求,就出现了Angular/React/Vue等框架(2)特点1、Vue的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。2、Vue.JS是优秀的前端Jav</div> </li> <li><a href="/article/1943016279984107520.htm" title="Vue3-尚硅谷笔记" target="_blank">Vue3-尚硅谷笔记</a> <span class="text-muted">八月份的天气</span> <a class="tag" taget="_blank" href="/search/Vue3-%E7%AC%94%E8%AE%B0/1.htm">Vue3-笔记</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>1.Vue3简介2020年9月18日,Vue.js发布版3.0版本,代号:OnePiece(n经历了:4800+次提交、40+个RFC、600+次PR、300+贡献者官方发版地址:Releasev3.0.0OnePiece·vuejs/core截止2023年10月,最新的公开版本为:3.3.41.1.【性能的提升】打包大小减少41%。初次渲染快55%,更新渲染快133%。内存减少54%。1.2.【</div> </li> <li><a href="/article/1942788247700697088.htm" title="2024三掌柜赠书活动第十二期:Nuxt.js Web开发实战" target="_blank">2024三掌柜赠书活动第十二期:Nuxt.js Web开发实战</a> <span class="text-muted"></span> <div>目录前言Nuxt.js的特性Nuxt.js的实战应用关于《Nuxt.jsWeb开发实战》编辑推荐内容简介作者简介图书目录书中前言/序言《Nuxt.jsWeb开发实战》全书速览结束语前言作为前端开发的小伙伴想必对Nuxt.js并不陌生,Nuxt.js是基于Vue.js的一款用于构建服务端渲染的应用程序的框架。它能够帮助开发者快速搭建高性能的单页面应用(SPA)和多页面应用(MPA)。Nuxt.js在</div> </li> <li><a href="/article/1942778788052004864.htm" title="vue-cropper实现图片裁剪" target="_blank">vue-cropper实现图片裁剪</a> <span class="text-muted">鸡吃丸子</span> <a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>一、什么是vue-cropper?Vue-Cropper是一个基于Vue.js的图片裁剪组件库,专为Web应用设计。当你在网上搜索的时候发现还有一个叫cropper的库,下面是他们的区别:特性cropper.jsvue-cropper框架依赖纯JavaScript,无框架依赖专为Vue.js设计包体积~200KB(含样式)~45KB(压缩后)API调用方式原生DOM操作Vue组件式API响应式支持</div> </li> <li><a href="/article/1942767322414510080.htm" title="Session:在多个请求之间跟踪用户状态" target="_blank">Session:在多个请求之间跟踪用户状态</a> <span class="text-muted"></span> <div>前端开发工程师、技术日更博主、已过CET6阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1牛客高级专题作者、打造专栏《前端面试必备》、《2024面试高频手撕题》、《前端求职突破计划》蓝桥云课签约作者、上架课程《Vue.js和Egg.js开发企业级健康管理项目》、《带你从入门到实战全面掌握uni-app》文章目录一、Session的基本概念1.SessionID2.Session数据</div> </li> <li><a href="/article/1942767322909437952.htm" title="CORS(跨域资源共享):跨域请求的解决方案" target="_blank">CORS(跨域资源共享):跨域请求的解决方案</a> <span class="text-muted">阿珊和她的猫</span> <a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>前端开发工程师、技术日更博主、已过CET6阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1牛客高级专题作者、打造专栏《前端面试必备》、《2024面试高频手撕题》、《前端求职突破计划》蓝桥云课签约作者、上架课程《Vue.js和Egg.js开发企业级健康管理项目》、《带你从入门到实战全面掌握uni-app》文章目录一、CORS的基本概念1.简单请求2.预检请求二、设置CORS使用Nod</div> </li> <li><a href="/article/1942720669838012416.htm" title="Vue.js 中跨域请求未配置 CORS 的问题及解决方案" target="_blank">Vue.js 中跨域请求未配置 CORS 的问题及解决方案</a> <span class="text-muted">JJCTO袁龙</span> <a class="tag" taget="_blank" href="/search/Vue/1.htm">Vue</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>Vue.js中跨域请求未配置CORS的问题及解决方案在Vue.js开发中,跨域请求(CORS)是一个常见的问题。当你的前端应用尝试从不同的源访问后端API时,浏览器会出于安全考虑阻止这些请求,除非后端服务器明确允许。本文将探讨这些问题的常见原因,并提供相应的解决方案。一、Vue.js中跨域请求未配置CORS的常见原因(一)浏览器的同源策略限制浏览器的同源策略限制了从一个源加载的文档或脚本与来自另一</div> </li> <li><a href="/article/1942647556697812992.htm" title="在WPF中使用CommunityToolkit.Mvvm——(一)为什么使用CommunityToolkit.Mvvm" target="_blank">在WPF中使用CommunityToolkit.Mvvm——(一)为什么使用CommunityToolkit.Mvvm</a> <span class="text-muted">永远的久远</span> <a class="tag" taget="_blank" href="/search/wpf/1.htm">wpf</a> <div>前言阅读我文章的同学可能已经发现了,我总是会在一个系列文章的第一篇抛出问题,为什么要用到这个技术。因为一些成熟的库和技术会给我们带来生产力大幅的提升,同时通过学习一些优秀的开源项目,对我们个人的能力提升也会有帮助。接下来我们一起来看一下MVVMToolkit能为我们带来哪些惊喜~~CommunityToolkit.Mvvm是什么微软的官方文档这样介绍的CommunityToolkit.Mvvm包(</div> </li> <li><a href="/article/108.htm" title="Nginx负载均衡" target="_blank">Nginx负载均衡</a> <span class="text-muted">510888780</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/%E5%BA%94%E7%94%A8%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">应用服务器</a> <div>Nginx负载均衡一些基础知识: nginx 的 upstream目前支持 4 种方式的分配 1)、轮询(默认)       每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 2)、weight       指定轮询几率,weight和访问比率成正比</div> </li> <li><a href="/article/235.htm" title="RedHat 6.4 安装 rabbitmq" target="_blank">RedHat 6.4 安装 rabbitmq</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/erlang/1.htm">erlang</a><a class="tag" taget="_blank" href="/search/rabbitmq/1.htm">rabbitmq</a><a class="tag" taget="_blank" href="/search/redhat/1.htm">redhat</a> <div>在 linux 下安装软件就是折腾,首先是测试机不能上外网要找运维开通,开通后发现测试机的 yum 不能使用于是又要配置 yum 源,最后安装 rabbitmq 时也尝试了两种方法最后才安装成功 机器版本: [root@redhat1 rabbitmq]# lsb_release LSB Version: :base-4.0-amd64:base-4.0-noarch:core</div> </li> <li><a href="/article/362.htm" title="FilenameUtils工具类" target="_blank">FilenameUtils工具类</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/FilenameUtils/1.htm">FilenameUtils</a><a class="tag" taget="_blank" href="/search/common-io/1.htm">common-io</a> <div>转载请出自出处:http://eksliang.iteye.com/blog/2217081 一、概述 这是一个Java操作文件的常用库,是Apache对java的IO包的封装,这里面有两个非常核心的类FilenameUtils跟FileUtils,其中FilenameUtils是对文件名操作的封装;FileUtils是文件封装,开发中对文件的操作,几乎都可以在这个框架里面找到。 非常的好用。 </div> </li> <li><a href="/article/489.htm" title="xml文件解析SAX" target="_blank">xml文件解析SAX</a> <span class="text-muted">不懂事的小屁孩</span> <a class="tag" taget="_blank" href="/search/xml/1.htm">xml</a> <div>xml文件解析:xml文件解析有四种方式, 1.DOM生成和解析XML文档(SAX是基于事件流的解析) 2.SAX生成和解析XML文档(基于XML文档树结构的解析) 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML 本文章用第一种方法进行解析,使用android常用的DefaultHandler import org.xml.sax.Attributes; </div> </li> <li><a href="/article/616.htm" title="通过定时任务执行mysql的定期删除和新建分区,此处是按日分区" target="_blank">通过定时任务执行mysql的定期删除和新建分区,此处是按日分区</a> <span class="text-muted">酷的飞上天空</span> <a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div>使用python脚本作为命令脚本,linux的定时任务来每天定时执行 #!/usr/bin/python # -*- coding: utf8 -*- import pymysql import datetime import calendar #要分区的表 table_name = 'my_table' #连接数据库的信息 host,user,passwd,db = </div> </li> <li><a href="/article/743.htm" title="如何搭建数据湖架构?听听专家的意见" target="_blank">如何搭建数据湖架构?听听专家的意见</a> <span class="text-muted">蓝儿唯美</span> <a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a> <div>Edo Interactive在几年前遇到一个大问题:公司使用交易数据来帮助零售商和餐馆进行个性化促销,但其数据仓库没有足够时间去处理所有的信用卡和借记卡交易数据  “我们要花费27小时来处理每日的数据量,”Edo主管基础设施和信息系统的高级副总裁Tim Garnto说道:“所以在2013年,我们放弃了现有的基于PostgreSQL的关系型数据库系统,使用了Hadoop集群作为公司的数</div> </li> <li><a href="/article/870.htm" title="spring学习——控制反转与依赖注入" target="_blank">spring学习——控制反转与依赖注入</a> <span class="text-muted">a-john</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>       控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。   </div> </li> <li><a href="/article/997.htm" title="用spool+unixshell生成文本文件的方法" target="_blank">用spool+unixshell生成文本文件的方法</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/xshell/1.htm">xshell</a> <div>例如我们把scott.dept表生成文本文件的语句写成dept.sql,内容如下:   set pages 50000;   set lines 200;   set trims on;   set heading off;   spool /oracle_backup/log/test/dept.lst;   select deptno||','||dname||','||loc </div> </li> <li><a href="/article/1124.htm" title="1、基础--名词解析(OOA/OOD/OOP)" target="_blank">1、基础--名词解析(OOA/OOD/OOP)</a> <span class="text-muted">asia007</span> <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/1.htm">学习基础知识</a> <div>OOA:Object-Oriented Analysis(面向对象分析方法) 是在一个系统的开发过程中进行了系统业务调查以后,按照面向对象的思想来分析问题。OOA与结构化分析有较大的区别。OOA所强调的是在系统调查资料的基础上,针对OO方法所需要的素材进行的归类分析和整理,而不是对管理业务现状和方法的分析。   OOA(面向对象的分析)模型由5个层次(主题层、对象类层、结构层、属性层和服务层)</div> </li> <li><a href="/article/1251.htm" title="浅谈java转成json编码格式技术" target="_blank">浅谈java转成json编码格式技术</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/json%E7%BC%96%E7%A0%81/1.htm">json编码</a><a class="tag" taget="_blank" href="/search/java%E8%BD%AC%E6%88%90json%E7%BC%96%E7%A0%81/1.htm">java转成json编码</a> <div>json编码;是一个轻量级的数据存储和传输的语言       在java中需要引入json相关的包,引包方式在工程的lib下就可以了   JSON与JAVA数据的转换(JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非   常适合于服务器与 JavaScript 之间的数据的交</div> </li> <li><a href="/article/1378.htm" title="web.xml之Spring配置(基于Spring+Struts+Ibatis)" target="_blank">web.xml之Spring配置(基于Spring+Struts+Ibatis)</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/web.xml/1.htm">web.xml</a><a class="tag" taget="_blank" href="/search/SSI/1.htm">SSI</a><a class="tag" taget="_blank" href="/search/spring%E9%85%8D%E7%BD%AE/1.htm">spring配置</a> <div>指定Spring配置文件位置 <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spring-dao-bean.xml,/WEB-INF/spring-resources.xml, /WEB-INF/</div> </li> <li><a href="/article/1505.htm" title="Installing SonarQube(Fail to download libraries from server)" target="_blank">Installing SonarQube(Fail to download libraries from server)</a> <span class="text-muted">sunjing</span> <a class="tag" taget="_blank" href="/search/Install/1.htm">Install</a><a class="tag" taget="_blank" href="/search/Sonar/1.htm">Sonar</a> <div>1.  Download and unzip the SonarQube distribution 2.  Starting the Web Server The default port is "9000" and the context path is "/". These values can be changed in &l</div> </li> <li><a href="/article/1632.htm" title="【MongoDB学习笔记十一】Mongo副本集基本的增删查" target="_blank">【MongoDB学习笔记十一】Mongo副本集基本的增删查</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a> <div>一、创建复本集   假设mongod,mongo已经配置在系统路径变量上,启动三个命令行窗口,分别执行如下命令:   mongod --port 27017 --dbpath data1 --replSet rs0 mongod --port 27018 --dbpath data2 --replSet rs0 mongod --port 27019 -</div> </li> <li><a href="/article/1759.htm" title="Anychart图表系列二之执行Flash和HTML5渲染" target="_blank">Anychart图表系列二之执行Flash和HTML5渲染</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/Flash/1.htm">Flash</a> <div>今天介绍Anychart的Flash和HTML5渲染功能   HTML5 Anychart从6.0第一个版本起,已经逐渐开始支持各种图的HTML5渲染效果了,也就是说即使你没有安装Flash插件,只要浏览器支持HTML5,也能看到Anychart的图形(不过这些是需要做一些配置的)。 这里要提醒下大家,Anychart6.0版本对HTML5的支持还不算很成熟,目前还处于</div> </li> <li><a href="/article/1886.htm" title="Laravel版本更新异常4.2.8-> 4.2.9 Declaration of ... CompilerEngine ... should be compa" target="_blank">Laravel版本更新异常4.2.8-> 4.2.9 Declaration of ... CompilerEngine ... should be compa</a> <span class="text-muted">bozch</span> <a class="tag" taget="_blank" href="/search/laravel/1.htm">laravel</a> <div>昨天在为了把laravel升级到最新的版本,突然之间就出现了如下错误: ErrorException thrown with message "Declaration of Illuminate\View\Engines\CompilerEngine::handleViewException() should be compatible with Illuminate\View\Eng</div> </li> <li><a href="/article/2013.htm" title="编程之美-NIM游戏分析-石头总数为奇数时如何保证先动手者必胜" target="_blank">编程之美-NIM游戏分析-石头总数为奇数时如何保证先动手者必胜</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E4%B9%8B%E7%BE%8E/1.htm">编程之美</a> <div> import java.util.Arrays; import java.util.Random; public class Nim { /**编程之美 NIM游戏分析 问题: 有N块石头和两个玩家A和B,玩家A先将石头随机分成若干堆,然后按照BABA...的顺序不断轮流取石头, 能将剩下的石头一次取光的玩家获胜,每次取石头时,每个玩家只能从若干堆石头中任选一堆,</div> </li> <li><a href="/article/2140.htm" title="lunce创建索引及简单查询" target="_blank">lunce创建索引及简单查询</a> <span class="text-muted">chengxuyuancsdn</span> <a class="tag" taget="_blank" href="/search/%E6%9F%A5%E8%AF%A2/1.htm">查询</a><a class="tag" taget="_blank" href="/search/%E5%88%9B%E5%BB%BA%E7%B4%A2%E5%BC%95/1.htm">创建索引</a><a class="tag" taget="_blank" href="/search/lunce/1.htm">lunce</a> <div>import java.io.File; import java.io.IOException; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Docume</div> </li> <li><a href="/article/2267.htm" title="[IT与投资]坚持独立自主的研究核心技术" target="_blank">[IT与投资]坚持独立自主的研究核心技术</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/it/1.htm">it</a> <div>        和别人合作开发某项产品....如果互相之间的技术水平不同,那么这种合作很难进行,一般都会成为强者控制弱者的方法和手段.....        所以弱者,在遇到技术难题的时候,最好不要一开始就去寻求强者的帮助,因为在我们这颗星球上,生物都有一种控制其</div> </li> <li><a href="/article/2394.htm" title="flashback transaction闪回事务查询" target="_blank">flashback transaction闪回事务查询</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/%E9%97%AA%E5%9B%9E%E4%BA%8B%E5%8A%A1/1.htm">闪回事务</a> <div>   闪回事务查询有别于闪回查询的特点有以下3个: (1)其正常工作不但需要利用撤销数据,还需要事先启用最小补充日志。 (2)返回的结果不是以前的“旧”数据,而是能够将当前数据修改为以前的样子的撤销SQL(Undo SQL)语句。 (3)集中地在名为flashback_transaction_query表上查询,而不是在各个表上通过“as of”或“vers</div> </li> <li><a href="/article/2521.htm" title="Java I/O之FilenameFilter类列举出指定路径下某个扩展名的文件" target="_blank">Java I/O之FilenameFilter类列举出指定路径下某个扩展名的文件</a> <span class="text-muted">游其是你</span> <a class="tag" taget="_blank" href="/search/FilenameFilter/1.htm">FilenameFilter</a> <div>这是一个FilenameFilter类用法的例子,实现的列举出“c:\\folder“路径下所有以“.jpg”扩展名的文件。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 </div> </li> <li><a href="/article/2648.htm" title="C语言学习五函数,函数的前置声明以及如何在软件开发中合理的设计函数来解决实际问题" target="_blank">C语言学习五函数,函数的前置声明以及如何在软件开发中合理的设计函数来解决实际问题</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/c/1.htm">c</a> <div># include <stdio.h> int f(void) //括号中的void表示该函数不能接受数据,int表示返回的类型为int类型 { return 10; //向主调函数返回10 } void g(void) //函数名前面的void表示该函数没有返回值 { //return 10; //error 与第8行行首的void相矛盾 } in</div> </li> <li><a href="/article/2775.htm" title="今天在测试环境使用yum安装,遇到一个问题: Error: Cannot retrieve metalink for repository: epel. Pl" target="_blank">今天在测试环境使用yum安装,遇到一个问题: Error: Cannot retrieve metalink for repository: epel. Pl</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/centos/1.htm">centos</a> <div>今天在测试环境使用yum安装,遇到一个问题: Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again   处理很简单,修改文件“/etc/yum.repos.d/epel.repo”, 将baseurl的注释取消, mirrorlist注释掉。即可。 &n</div> </li> <li><a href="/article/2902.htm" title="单例模式" target="_blank">单例模式</a> <span class="text-muted">shuizhaosi888</span> <a class="tag" taget="_blank" href="/search/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/1.htm">单例模式</a> <div>单例模式      懒汉式 public class RunMain { /** * 私有构造 */ private RunMain() { } /** * 内部类,用于占位,只有 */ private static class SingletonRunMain { priv</div> </li> <li><a href="/article/3029.htm" title="Spring Security(09)——Filter" target="_blank">Spring Security(09)——Filter</a> <span class="text-muted">234390216</span> <a class="tag" taget="_blank" href="/search/Spring+Security/1.htm">Spring Security</a> <div>Filter 目录 1.1     Filter顺序 1.2     添加Filter到FilterChain 1.3     DelegatingFilterProxy 1.4     FilterChainProxy 1.5</div> </li> <li><a href="/article/3156.htm" title="公司项目NODEJS实践0.1" target="_blank">公司项目NODEJS实践0.1</a> <span class="text-muted">逐行分析JS源代码</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/nodejs/1.htm">nodejs</a> <div>  一、前言         前端如何独立用nodeJs实现一个简单的注册、登录功能,是不是只用nodejs+sql就可以了?其实是可以实现,但离实际应用还有距离,那要怎么做才是实际可用的。         网上有很多nod</div> </li> <li><a href="/article/3283.htm" title="java.lang.Math" target="_blank">java.lang.Math</a> <span class="text-muted">liuhaibo_ljf</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Math/1.htm">Math</a><a class="tag" taget="_blank" href="/search/lang/1.htm">lang</a> <div>System.out.println(Math.PI); System.out.println(Math.abs(1.2)); System.out.println(Math.abs(1.2)); System.out.println(Math.abs(1)); System.out.println(Math.abs(111111111)); System.out.println(Mat</div> </li> <li><a href="/article/3410.htm" title="linux下时间同步" target="_blank">linux下时间同步</a> <span class="text-muted">nonobaba</span> <a class="tag" taget="_blank" href="/search/ntp/1.htm">ntp</a> <div>今天在linux下做hbase集群的时候,发现hmaster启动成功了,但是用hbase命令进入shell的时候报了一个错误  PleaseHoldException: Master is initializing,查看了日志,大致意思是说master和slave时间不同步,没办法,只好找一种手动同步一下,后来发现一共部署了10来台机器,手动同步偏差又比较大,所以还是从网上找现成的解决方</div> </li> <li><a href="/article/3537.htm" title="ZooKeeper3.4.6的集群部署" target="_blank">ZooKeeper3.4.6的集群部署</a> <span class="text-muted">roadrunners</span> <a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E7%BE%A4/1.htm">集群</a><a class="tag" taget="_blank" href="/search/%E9%83%A8%E7%BD%B2/1.htm">部署</a> <div>ZooKeeper是Apache的一个开源项目,在分布式服务中应用比较广泛。它主要用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步、集群管理、配置文件管理、同步锁、队列等。这里主要讲集群中ZooKeeper的部署。   1、准备工作 我们准备3台机器做ZooKeeper集群,分别在3台机器上创建ZooKeeper需要的目录。   数据存储目录</div> </li> <li><a href="/article/3664.htm" title="Java高效读取大文件" target="_blank">Java高效读取大文件</a> <span class="text-muted">tomcat_oracle</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>  读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法:   Files.readLines(new File(path), Charsets.UTF_8);   FileUtils.readLines(new File(path));   这种方法带来的问题是文件的所有行都被存放在内存中,当文件足够大时很快就会导致</div> </li> <li><a href="/article/3791.htm" title="微信支付api返回的xml转换为Map的方法" target="_blank">微信支付api返回的xml转换为Map的方法</a> <span class="text-muted">xu3508620</span> <a class="tag" taget="_blank" href="/search/xml/1.htm">xml</a><a class="tag" taget="_blank" href="/search/map/1.htm">map</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1api/1.htm">微信api</a> <div>举例如下: <xml>    <return_code><![CDATA[SUCCESS]]></return_code>    <return_msg><![CDATA[OK]]></return_msg>    <appid><</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>