好啦,都归零啦,今天开始重新接触Vue
,首先从它的API入手,参考官网。
准备工作
1. 克隆代码
git clone https://github.com/vuejs/vue.git
于是本地就有一份Vue2
版本的代码了,目录如下:(可用命令tree
输出目录)
│ .editorconfig
│ .git-blame-ignore-revs
│ .gitignore
│ .prettierrc
│ api-extractor.json
│ api-extractor.tsconfig.json
│ BACKERS.md
│ catalogTree.txt
│ CHANGELOG.md
│ LICENSE
│ package.json
│ pnpm-lock.yaml
│ pnpm-workspace.yaml
│ README.md
│ tsconfig.json
│ vitest.config.ts
├─.github
├─benchmarks
├─compiler-sfc
├─dist
├─examples
├─packages
├─scripts
├─src
├─test
└─types
2. 安装依赖
cd vue
nrm ls // 查看源
nrm use taobao // 切换到淘宝源
pnpm i // 安装依赖
不得不说,pnpm
是真的好用!
3. 对源代码进行打包
打开package.json
文件,找到script
字段,运行dev
命令,该命令会生成开发环境模式的包,便于后面源码的阅读和调试。
pnpm run dev
于是在项目的dist
文件夹下面生成了vue.js
文件
4. 新建例子
该项目的examples
文件夹下面已经有官方例子了,我们在这个文件夹下面创建新的文件夹demos
,来创建自己的测试例子,结果如下:
5. 开启本地服务
在项目根目录下运行以下命令
http-server -p 5000
接下来就可以愉快地学习Vue
啦。(为什么才刚刚开始?哭唧唧)
Vue的应用
一个简单的例子
在demos
文件夹下面创建index.html
,引入打包生成的vue.js
文件,代码如下
// index.html
<!DOCTYPE html>
<html>
<head>
<title>Vue.js github commits example</title>
<script src="../../dist/vue.js"></script>
</head>
<body>
<div id="demo">
{{msg}}
</div>
</body>
<script>
new Vue({
el: '#demo',
data: {
msg: 'hello vue'
}
})
</script>
</html>
访问http://127.0.0.1:5000/examples/demos/
,效果如下:
这就是一个最最简单的例子了,接下来开始学习官网里的API。
API
-
全局配置 简单的配置见官网说明
-
silent
-
optionMergeStrategies
/** * 自定义合并策略:无论是vue实例还是vue组件,它们都是可配置的对象, * 类似 { * methods: {}, * watch: { * }, * data: {} * } * 以上对象的属性是Vue内置的配置项 * 利用这个属性可以定义内置配置项(如data)怎么合并,还可以定义新的配置项 */ // 重新定义data配置项的合并策略 Vue.config.optionMergeStrategies.data = (parent, child, vm) => { console.log(parent, child, vm) // 打印内容见图1 return { msg: `a new msg${child.msg}` } } // 自定义配置项及逻辑,这个用法待研究 Vue.config.optionMergeStrategies.myOption = Vue.config.optionMergeStrategies.methods new Vue({ el: '#demo', data: { msg: 'hello vue' }, // 这种混入有啥用???? myOption: { init() { return this.msg } } })
图1:
运行结果:
-
devtools
-
errorHandler
捕获错误,如生命周期里面的错误。
// 视图 <div id="demo"> {{msg}} <Child /> </div> // js逻辑 Vue.config.errorHandler = (err, vm, info) => { console.log(err, vm, info) // 打印结果见图2 } // 定义一个傻瓜组件 const Child = { data() { return { msg: 'I am child' } }, template: `<div>{{msg}}</div>`, mounted() { console.log(count) // 错误的用法:count未定义,errorHandler会捕获到这个错误 } } new Vue({ el: '#demo', components: { Child }, data: { msg: 'hello vue' } })
运行结果:
图2:捕获到错误控制台打印的结果
页面结果:
稍微改动上面的errorHandler例子,改变子组件的变量名,如下
// 处理运行时警告:使用子组件时没有用-的格式 <div id="demo"> {{msg}} // 应该是<child-comp/> <ChildComp /> </div> Vue.config.warnHandler = function(msg, vm, trace) { // `trace` 是组件的继承关系追踪 console.log(msg, vm, trace) // 打印见图3 } // 定义一个傻瓜组件 const ChildComp = { data() { return { msg: 'I am child' } }, template: `<div>{{msg}}</div>`, } new Vue({ el: '#demo', components: { // 注册组件 ChildComp }, data: { msg: 'hello vue' } }) </div>
运行结果:
图3:
页面结果: 子组件并没有渲染出来
// 使用web components apis定义的组件:(这是一个知识点哦,待了解) class ChildComp extends HTMLElement { constructor() { super() // Create a shadow root const shadow = this.attachShadow({ mode: 'open' }); // Create p const info = document.createElement('p'); info.innerHTML = '32323' info.setAttribute('class', 'info'); // Create some CSS to apply to the shadow dom const style = document.createElement('style'); console.log(style.isConnected); style.textContent = ` .info { color: red; } `; // Attach the created elements to the shadow dom shadow.appendChild(style); shadow.appendChild(info); } } customElements.define('child-comp', ChildComp) // 其实这步也没有产生什么作用呀?????? Vue.config.ignoredElements = [ 'child-comp' ] // 使用 <div id="demo"> {{msg}} <child-comp /> </div>
运行结果:
keyCode是数值,使用起来不方便,可定义keyCode别名
使用: @键盘事件.别名
<input type="text" @keyup.media-play-pause="method">
-
以上全局配置属性在Vue.config
对象上,打印该对象的默认值如下:
{
"optionMergeStrategies": {},
"silent": false,
"productionTip": true,
"devtools": true,
"performance": false,
"errorHandler": null,
"warnHandler": null,
"ignoredElements": [],
"keyCodes": {},
"async": true,
"_lifecycleHooks": [
"beforeCreate",
"created",
"beforeMount",
"mounted",
"beforeUpdate",
"updated",
"beforeDestroy",
"destroyed",
"activated",
"deactivated",
"errorCaptured",
"serverPrefetch",
"renderTracked",
"renderTriggered"
]
}
-
全局 API
这部分新建一个新的html文件,
global-apis.index.html
, 访问http://127.0.0.1:5000/examples/demos/global-apis.html
// global-apis.index.html <!DOCTYPE html> <html> <head> <title>Vue.js github commits example</title> <script src="../../dist/vue.js"></script> </head> <body> <div id="demo"> {{msg}} </div> </body> <script> new Vue({ el: '#demo', data: { msg: 'hello vue' } }) </script> </html>
原先我们是使用
new Vue
去创建一个vue
实例,一般来说,一个实例就是一个应用。Vue.extends
允许我们使用基础构造器创建一个子类,使用子类去创建一个实例,参数是一个包含组件选项的对象。- 示例代码
<!DOCTYPE html> <html> <head> <title>Vue.js github commits example</title> <script src="../../dist/vue.js"></script> </head> <body> <div id="demo"> {{msg}} <div id="mount-point"></div> </div> </body> <script> // Vue.extends // 创建构造器 var Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function() { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point') new Vue({ el: '#demo', data: { msg: 'hello vue' } }) </script> </html>
- 运行结果
dom的更新是异步的,修改数据之后并不会立即生效,如果想要获取更新后的dom,可以在
Vue.nextTick
的回调函数里面获取。注册或获取全局指令。
- 示例代码
<!DOCTYPE html> <html> <head> <title>Vue.js github commits example</title> <script src="../../dist/vue.js"></script> </head> <body> <div id="demo"> {{msg}} <div id="hook-arguments-example" v-demo:foo.a.b="message"></div> </div> </body> <script> // Vue.directive Vue.directive('demo', { bind: function(el, binding, vnode) { var s = JSON.stringify el.innerHTML = 'name: ' + s(binding.name) + '<br>' + 'value: ' + s(binding.value) + '<br>' + 'expression: ' + s(binding.expression) + '<br>' + 'argument: ' + s(binding.arg) + '<br>' + 'modifiers: ' + s(binding.modifiers) + '<br>' + 'vnode keys: ' + Object.keys(vnode).join(', ') } }) new Vue({ el: '#demo', data: { msg: 'hello vue' } }) </script> </html>
- 运行结果
过滤器。
Vue.filter('self-filter', (value) => { // value是要处理的值,最后返回处理的结果即可 return 处理后的结果 }
自定义全局组件,配置项同普通组件。
使用
Vue
插件,至于如何开发一个插件,参考这里。全局混入,会影响所有组件,不建议使用,其合并策略可以自定义,通过
Vue.config.optionMergeStrategies
将一个模板字符串编译成 render 函数。牛气哄哄! 所以提供模板的方式有:
- render函数
- template模板
- el
<!DOCTYPE html> <html> <head> <title>Vue.js github commits example</title> <script src="../../dist/vue.js"></script> </head> <body> <div id="demo"></div> </body> <script> const res = Vue.compile('<div><span>{{ msg }}</span></div>') console.log(res, '>>>>>>>>>') new Vue({ el: '#demo', render: res.render, staticRenderFns: res.staticRenderFns, data: { msg: 'hello vue' } }) </script> </html>
控制台打印内容:
-
选项 / 数据
-
选项 / DOM
-
选项 / 生命周期钩子
-
选项 / 资源
-
选项 / 组合
-
选项 / 其它
-
实例 property
-
实例方法 / 数据
-
实例方法 / 事件
-
实例方法 / 生命周期
-
指令
-
特殊 attribute
-
内置的组件
-
VNode 接口
-
服务端渲染