2023-2-2
从0到1 创建
npm install --global vue-cli
Error: Cannot find module 'C:\Users\LUI\AppData\Roaming\npm\node_modules\@vue\cli\bin\vue.js'
当在使用vue-cli创建项目时,出现以上错误检查node-v,vue-V,npm -version。
npm install --global vue-cli --force
npm install -g @vue/cli --force
目录概览
.browserslistrc //CSS代码适配的浏览器
.editorconfig //编辑器:
2.1 上传到GitHub
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/clo03/Eribbit.git
git push -u origin main
Error: 使用http一直要输入用户名和密码
使用ssh,设置key
Error: git@github.com: Permission denied (publickey)
①git config --global --list 验证邮箱与GitHub注册时输入的是否一致
![](https://i-blog.csdnimg.cn/blog_migrate/11e8397bd1b227a3efa4541d45d9ccf9.png)
②通过git config --global user.name “yourname”,git config --global user.email “email@email.com ”设置全局用户名和邮箱
![](https://i-blog.csdnimg.cn/blog_migrate/7316ce50d6b2a824ab3c8343cf51ea12.png)
③ssh-keygen -t rsa -C “这里换上你的邮箱”,一路回车,在出现选择时输入Y,再一路回车直到生成密钥。会在/Users/***/路径下生成一个.ssh文件夹,密钥就存储在其中。
④到git仓库,添加秘钥。
Error: Key is invalid. You must supply a key in OpenSSH public key format
C:\Users\LUI\.ssh → id_rsa.pub
2.2 同时上传到GitHub和Gitee
在我们执行了git add .指令之后,我们的代码是被放到了本地仓库,而且一个本地仓库可以对应多个远程仓库。
//指令来添加远程仓库
//name 是远程仓库的别名,便于区分不同的远程仓库
//url-of-remote 是我们的远程仓库链接,就是平时看到的以.git为后缀的链接
git remote add <name> <url-of-remote>
//查看刚刚添加好的仓库
git remote -v
//添加代码到本地仓库
git add .
//提交并添加描述
git commit -m "first commit"
//push到相应的仓库
git push github master //push 到github
git push gitee master //push 到gitee
![](https://i-blog.csdnimg.cn/blog_migrate/905be51b75fe9f98de06827116da603c.png)
Error: src refspec master does not match any
Error: failed to push some refs to 'gitee.com:liu-yue23/eribbit.git'
ssh没有配置好
//测试ssh
ssh -T git@gitee.com
ssh -T git@github.com
![](https://i-blog.csdnimg.cn/blog_migrate/4c3c1ff1f285410ab857dff590b771b8.png)
Error: kex_exchange_identification: read: Software caused connection abort
Error: banner exchange: Connection to 212.64.62.174 port 22: Software caused connection abort
在电脑的host文件中(C:/WINDOW/Sysvstem32/drivers/etc),固定死了gitee.com的 ip 地址,这个ip应该是有异常了,你修改一下host文件中的ip 地址,改成 gitee.com其他的ip地址,就可以了。或者使用公共 DNS 如 114.114.114.114 进行解析。
在控制面板中找到"网络和Internet",点击下方的"查看网络状态和任务"。.点击已经连接的wifi,在wifi状态窗口中,点击"详细信息",找到IPv4就是你电脑的ip地址了(192.168.1.7)。
Error: Hi LUIV! You've successfully authenticated, but GITEE.COM does not provide shell access.
2.3 vue2.0和vue3.0的不同
vue2.0——this可以直接调用到data、methods和props、computed里的值
export default {
data() {
return {
name: '彭鱼宴'
}
},
methods: {
greet() {
console.log(`hello, 我是${this.name}`)
}
}
}
//vue实例的构造函数,构造函数在源码的目录/vue/src/core/instance/index.js下
function Vue (options) {
if (process.env.NODE_ENV !== 'production' && !(this instanceof Vue)) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue
// 构造函数很简单,if (!(this instanceof Vue)){} 判断是不是用了 new 关键词调用构造函数,没有则抛出warning,这里的this指的是Vue的一个实例。如果正常使用了new关键词,就走_init函数。
//_init函数分析
let uid = 0
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// a uid
vm._uid = uid++
let startTag, endTag
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
startTag = `vue-perf-start:${vm._uid}`
endTag = `vue-perf-end:${vm._uid}`
mark(startTag)
}
// a flag to avoid this being observed
vm._isVue = true
// merge options
if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
initProxy(vm)
} else {
vm._renderProxy = vm
}
// expose real self
vm._self = vm
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
vm._name = formatComponentName(vm, false)
mark(endTag)
measure(`vue ${vm._name} init`, startTag, endTag)
}
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
}
//initState函数分析
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
//initState做了5件事情:初化props,初始化methods,初始化data,初始化computed,初始化watch
//initMethods 初始化方法
function initMethods (vm, methods) {
var props = vm.$options.props;
for (var key in methods) {
{
if (typeof methods[key] !== 'function') {
warn(
"Method \"" + key + "\" has type \"" + (typeof methods[key]) + "\" in the component definition. " +
"Did you reference the function correctly?",
vm
);
}
if (props && hasOwn(props, key)) {
warn(
("Method \"" + key + "\" has already been defined as a prop."),
vm
);
}
if ((key in vm) && isReserved(key)) {
warn(
"Method \"" + key + "\" conflicts with an existing Vue instance method. " +
"Avoid defining component methods that start with _ or $."
);
}
}
vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm);
}
}
//initMethods主要是一些判断:
//判断methods中定义的函数是不是函数,不是函数就抛warning;
//判断methods中定义的函数名是否与props冲突,冲突抛warning;
//判断methods中定义的函数名是否与已经定义在Vue实例上的函数相冲突,冲突的话就建议开发者用_或者$开头命名;
//最重要的就是在vue实例上定义了一遍methods里所有的方法,并且使用bind函数将函数的this指向Vue实例上,就是我们new Vue()的实例对象上,解释了为什么this可以直接访问到methods里的方法
//initData 初始化数据
function initData (vm) {
var data = vm.$options.data;
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {};
if (!isPlainObject(data)) {
data = {};
warn(
'data functions should return an object:\n' +
'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
vm
);
}
// proxy data on instance
var keys = Object.keys(data);
var props = vm.$options.props;
var methods = vm.$options.methods;
var i = keys.length;
while (i--) {
var key = keys[i];
{
if (methods && hasOwn(methods, key)) {
warn(
("Method \"" + key + "\" has already been defined as a data property."),
vm
);
}
}
if (props && hasOwn(props, key)) {
warn(
"The data property \"" + key + "\" is already declared as a prop. " +
"Use prop default value instead.",
vm
);
} else if (!isReserved(key)) {
proxy(vm, "_data", key);
}
}
// observe data
observe(data, true /* asRootData */);
// initdata做了哪些事情呢:
//先在实例 _data 上赋值,getData函数处理 data 这个 function,返回的是一个对象
//判断最终获取到的 data, 不是对象给出警告。
//判断methods里的函数和data里的key是否有冲突
//判断props和data里的key是否有冲突
//判断是不是内部私有的保留属性,若不是就做一层代理,代理到 _data 上
//最后监听data,使之成为响应式数据
//再看下proxy函数做了什么:
function noop (a, b, c) {}
var sharedPropertyDefinition = {
enumerable: true,
configurable: true,
get: noop,
set: noop
};
function proxy (target, sourceKey, key) {
sharedPropertyDefinition.get = function proxyGetter () {
return this[sourceKey][key]
};
sharedPropertyDefinition.set = function proxySetter (val) {
this[sourceKey][key] = val;
};
Object.defineProperty(target, key, sharedPropertyDefinition);
}
//其实这里的Object.defineProperty就是用来定义对象的,prox的用处就是使this.name指向this._data.name
methods里的方法通过 bind 指定了this为 new Vue的实例(vm),methods里的函数也都定义在vm上了,所以可以直接通过this直接访问到methods里面的函数。
data函数返回的数据对象也都存储在了new Vue的实例(vm)上的_data上了,访问 this.name时实际访问的是Object.defineProperty代理后的 this._data.name。