提示:该文章是承接上一篇文章手写vue插值语法的2中方式的第二种写法
文章目录
前言
提示:同样手写methods是用的dom操作,因此需要大家对dom有一定的熟悉程度
例如:节点属性怎么获得呀,怎么获得全部的节点属性呀等等。
提示:以下是本篇文章正文内容,下面案例可供参考
一、vue 的 methods是什么?
简单来说就是一个方法(函数的集合区域)
二、开始操作
1、准备工作
1.1、导入上一篇的代码到vue.js
注意:这里的vue.js是我们自己新建的空脚本,不是官方的vue.js
2.1、在上一篇的vue.js中进行代码编写
注意:这里使用的是插值语法的第2种编写形式
2、开始编写
2.1、分析官方vue.js的methods 使用方式
(1)、官方采用大对象的形式将方法全部集成到methods中。
(2)、不管methods中的方法怎么改变,调用它始终逃不过原生js的事件添加。
(3)、需要在节点中找到事件并添加方法。
2.2、开始编写
(1)因为方法调用是采用属性的形式加入到节点中,因此我们是在元素节点中查找属性。
/*在元素节点类型中调用方法*/
if(child.nodeType == 1){
//调用解析
this.analysis( child )
//调用方法
this.fcUsed(child)
}
(2)编写fcUses()方法(写法1)
//首先为方法传入节点
fcUsed(node){
//判断节点中是否有 @click 属性
if(node.hasAttribute('@click')){
//如果有就得到它的值并去掉前后空格
const fcName = node.getAtrribute('@clcik').trim()
// 思考:有时候我们会这样写 @click = 'change()'
// 会在后面加上多余的括号 这属于个人习惯问题 这种也是正确的
// 因此我们需要判断 fcName 是否有(),有就去除掉
let bg = fcName.indexOf('(') //得到‘(’的下标 若没有返回 -1
let end = fcName.indexOf(')')
if((bg + end) > 0){ //判断是否有这个括号()
fcName = fcName.slice(0,bg) //分割
}
//添加事件 并传递事件对象
node.addEventListener('click',(event)=>{
this.nodeFunction = this.$options.methods[fcName].bind(this)
this.nodeFunction(event)
})
}
}
(3)分析一下
(3.1)如果这个节点中有多个不同的事件 比如@change,@input…那我们是否还需要一个一个的添加?这样未免也过于麻烦,因此一下写法更为合理。
(4)编写fcUses()方法(写法2)
fcUsed( root ){
//得到节点的全部属性 包括 class @xxx ...
let rootAttrArray = root.attributes
for(let i = 0 ; i < rootAttrArray.length ;i++){
//判断是否为 @xxx 事件
if(rootAttrArray[i].name[0] == '@'){
let fcName = root.getAttribute(rootAttrArray[i].name).trim()
let bg = fcName.indexOf('(') //得到‘(’的下标 若没有返回 -1
let end = fcName.indexOf(')')
if((bg + end) > 0){ //判断是否有这个括号()
fcName = fcName.slice(0,bg) //分割
}
let eventName = rootAttrArray[i].name.slice(1)
root.addEventListener(eventName,(event)=>{
this.nodeFunction = this.$options.methods[fcName]
this.nodeFunction(event)
})
}
}
}
完整代码
class Vue{
constructor( options ){
this.$options = options
this.$el = document.querySelector( options.el )
this.$data = options.data
// console.log( this.$el )
// console.log( this.$data().str )
this.analysis( this.$el )
}
// 模版解析
analysis( rootNode ){
// console.log( rootNode,'这是根结点' )
const childNodes = rootNode.childNodes
// console.log(childNodes,'这是自节点')
// 遍历子节点
childNodes.forEach(child => {
// console.log(child,child.nodeType)
if(child.nodeType == 3){
// console.log(child.textContent)
const nodeTextContent = child.textContent.trim()
let begin = nodeTextContent.indexOf('{{')
let end = nodeTextContent.indexOf('}}')
let key = nodeTextContent.slice(begin+2,end).trim()
if( begin > -1 && end > -1 ){
// console.log(child.textContent)
// console.log(key)
child.textContent = this.$data()[key]
}
}
if(child.nodeType == 1){
//调用解析
this.analysis( child )
//调用方法
this.fcUsed(child)
}
});
}
//方法调用 @click
fcUsed( root ){
let rootAttrArray = root.attributes
for(let i = 0 ; i < rootAttrArray.length ;i++){
if(rootAttrArray[i].name[0] == '@'){
let fcName = root.getAttribute(rootAttrArray[i].name).trim()
let bg = fcName.indexOf('(') //得到‘(’的下标 若没有返回 -1
let end = fcName.indexOf(')')
if((bg + end) > 0){ //判断是否有这个括号()
fcName = fcName.slice(0,bg) //分割
}
let eventName = rootAttrArray[i].name.slice(1)
root.addEventListener(eventName,(event)=>{
this.nodeFunction = this.$options.methods[fcName]
this.nodeFunction(event)
})
}
}
}
}
总结
提示:熟悉dom操作、字符串操作
注意:以上就是今天要讲的内容,本文仅仅简单介绍了的使用vue methods的编写,这与官方肯定存在不小的差距,因此仅供参考!!!
喜欢的小伙伴们点赞加关注,哈哈哈。