Personal blog navigation page (click on the right link to open a personal blog): Daniel take you on technology stack
The project integrated use of Vue3.0
new features.
- Based
Composition API
ThatFunction-based API
transformation, withVue Cli
priority to experience theVue3
characteristics - Singleton object model components to communicate
- Use
axios
library network request,weui
library implementation UI interface
# 安装依赖
npm install
# 在浏览器打开localhost:8080查看页面,并实时热更新
npm run serve
# 发布项目
npm run build
Recommend to use with Visual Studio Code and Vue 3 Snippets plug-in code
Dependencies
Here's what to use to rely on, @vue/composition-api
with vue
module allows us Vue2.0
version can be the first to experience the Vue3.0
new features, axios
it is to assist our network request to get the data of the tool library weui
is a set of consistent with the micro-channel native visual basic style library, help us to quickly build project page.
"@vue/composition-api": "^0.3.4",
"axios": "^0.19.0",
"core-js": "^3.4.3",
"vue": "^2.6.10",
"weui": "^2.1.3"
Directory Structure
├── src
│ ├── App.vue # 组件入口
│ ├── assets # 资源目录
│ ├── stores/index.js # 状态管理
│ ├── components # 组件目录
│ │ ├── Header.vue # 头部组件
│ │ ├── Search.vue # 搜索框组件
│ │ ├── Panel.vue # 列表组件
│ ├── main.js # 项目入口
├── public # 模板文件
├── vue.config.js # 脚手架配置文件
├── screenshot # 程序截图
Composition API
npm install @vue/composition-api --save
Use npm
command to download a @vue/composition-api
later plug-in, after the introduction of the module, need to explicitly call Vue.use(VueCompositionApi)
, according to the document main.js
cited it opens up Composition API
the ability.
// main.js
import Vue from 'vue'
import App from './App.vue'
// 1.引入Composition API模块
import VueCompositionApi from '@vue/composition-api'
Vue.config.productionTip = false
// 2.不要漏了显式调用 VueCompositionApi
Vue.use(VueCompositionApi)
new Vue({
render: h => h(App),
}).$mount('#app')
npm install weui --save
We also use the npm
installation weui
module, then main.js
introduced weui
the basis of style library, we can easily build the project page using the micro-channel basis in the global style.
// main.js
import Vue from 'vue'
import App from './App.vue'
// 全局引入 `weui` 的基础样式库
import 'weui'
import VueCompositionApi from '@vue/composition-api'
Vue.config.productionTip = false
Vue.use(VueCompositionApi)
new Vue({
render: h => h(App),
}).$mount('#app')
Back to App.vue
retain components
the attribute value to empty <template>
the contents of the template, delete the <style>
template, waiting for re-introduction of new components.
<template>
<div id="app">
Hello World
</div>
</template>
<script>
export default {
name: "app",
components: {}
};
</script>
In src/components
the first new component directory, the name is Header.vue
written to the following code:
<template>
<header :style="{
backgroundColor: color?color:defaultColor
}">{{title}}</header>
</template>
<script>
import { reactive } from "@vue/composition-api";
export default {
// 父组件传递进来更改该头部组件的属性值
props: {
// 标题
title: String,
// 颜色
color: String
},
setup() {
const state = reactive({
defaultColor: "red"
});
return {
...state
};
}
};
</script>
<style scoped>
header {
height: 50px;
width: 100%;
line-height: 50px;
text-align: center;
color: white;
}
</style>
setup
Here the use of a new property setup
, which is a component of the entrance, so that we can use Vue3.0
the exposed new interface that runs in the component is instantiated when, props
after the property is defined, essentially equivalent to Vue2.0
release beforeCreate
and Created
these two lives period, setup
returns an object, the value of all property to be returned inside, will be merged into Vue2.0
the render
rendering function which, in a single-file assembly, it will be with the <template>
contents of the template, complete Model
the View
binding between the next version it should also support the return JSX
code snippet.
<template>
<!-- View -->
<div>{{name}}</div>
</template>
<script>
import { reactive } from '@vue/composition-api'
export default {
setup() {
const state = reactive({ name: 'Eno Yao' });
// return 暴露到 template 中
return {
// Model
...state
}
}
}
</script>
reactive
In the setup
function inside, we adapt to the new interface, Vue3.0 first of reactive
which mainly deal with it through your object Proxy
processing becomes a responsive object, similar to the Vue2.0
version data
attribute should be noted that the object after processing with the original objects are not equal, and the object belonging to the target depth of the processed clones.
const state = reactive({ name: 'Eno Yao' })
props
In Vue2.0
we can use the props
property values Sons complete communication, where we need to define props
the attribute values to define the type accepted, then we can use setup
the acquired first parameter props
used.
export default {
props: {
// 标题
title: String,
// 颜色
color: String
},
setup(props) {
// 这里可以使用父组件传过来的 props 属性值
}
};
We App.vue
can use inside the head assembly, with the above props
we can based on the value passed in, so that the head assembly presents a different state.
<template>
<div id="app">
<!-- 复用组件,并传入 props 值,让组件呈现对应的状态 -->
<Header title="Eno" color="red" />
<Header title="Yao" color="blue" />
<Header title="Wscats" color="yellow" />
</div>
</template>
<script>
import Header from "./components/Header.vue";
export default {
name: "app",
components: {
Header,
}
};
</script>
context
setup
The second parameter is a function of context object, context object that contains a number of useful properties, which in Vue2.0
the need this
to have access to, in vue3.0
, accessing them into the following form:
setup(props, ctx) {
console.log(ctx) // 在 setup() 函数中无法访问到 this
console.log(this) // undefined
}
Specific access to the following useful properties:
- root
- parent
- refs
- attrs
- listeners
- isServer
- ssrContext
- emit
Completion of the above Header.vue
we can write Search.vue
the search box components, and then continue src/components
folder below the new Search.vue
document, click View Source .
<template>
<div :class="['weui-search-bar', {'weui-search-bar_focusing' : isFocus}]" id="searchBar">
<form class="weui-search-bar__form">
<div class="weui-search-bar__box">
<i class="weui-icon-search"></i>
<input
v-model="searchValue"
ref="inputElement"
type="search"
class="weui-search-bar__input"
id="searchInput"
placeholder="搜索"
required
/>
<a href="javascript:" class="weui-icon-clear" id="searchClear"></a>
</div>
<label @click="toggle" class="weui-search-bar__label" id="searchText">
<i class="weui-icon-search"></i>
<span>搜索</span>
</label>
</form>
<a @click="toggle" href="javascript:" class="weui-search-bar__cancel-btn" id="searchCancel">取消</a>
</div>
</template>
<script>
import { reactive, toRefs, watch } from "@vue/composition-api";
import store from "../stores";
export default {
// setup相当于2.x版本的beforeCreate生命周期
setup() {
// reactive() 函数接收一个普通对象,返回一个响应式的数据对象
const state = reactive({
searchValue: "",
// 搜索框两个状态,聚焦和非聚焦
isFocus: false,
inputElement: null
});
// 切换搜索框状态的方法
const toggle = () => {
// 让点击搜索后出现的输入框自动聚焦
state.inputElement.focus();
state.isFocus = !state.isFocus;
};
// 监听搜索框的值
watch(
() => {
return state.searchValue;
},
() => {
// 存储输入框到状态 store 中心,用于组件通信
store.setSearchValue(state.searchValue);
// window.console.log(state.searchValue);
}
);
return {
// 将 state 上的每个属性,都转化为 ref 形式的响应式数据
...toRefs(state),
toggle
};
}
};
</script>
toRefs
We can see the top with a lot of new properties, we first introduced toRefs
, the function can be reactive()
created out of responsive objects, converted into ordinary objects, but each attribute node on the object, is ref()
the type of responsive data, with v-model
instructions to complete the two-way data binding, in the development of very efficient.
import { reactive, toRefs } from "@vue/composition-api";
export default {
setup() {
const state = reactive({ name: 'Eno Yao' })
}
return {
// 直接返回 state 那么数据会是非响应式的, MV 单向绑定
// ...state,
// toRefs 包装后返回 state 那么数据会是响应式的, MVVM 双向绑定
...toRefs(state),
};
}
template refs
Here input box has two states, a state that has no input box and input box state, so we need a boolean value isFocus
to control the state, it encapsulates a toggle
way to let isFocus
the value of true and false switching two states.
const toggle = () => {
// isFocus 值取反
state.isFocus = !state.isFocus;
};
Then with the v-bind:class
instructions, let weui-search-bar_focusing
the class name based on isFocus
the value of the decision whether to appear, thereby changing the status of the search box.
<div :class="['weui-search-bar', {'weui-search-bar_focusing' : isFocus}]" id="searchBar">
Here the search input box into v-model
instructions for receiving user input information, to facilitate later retrieval logic performed with the list of components, but also into ref
property, for obtaining the <input/>
element node tag, with the state.inputElement.focus()
native methods in the search box to switch when the state of the input box cursor autofocus enhance the user experience.
<input
v-model="searchValue"
ref="inputElement"
/>
watch
watch()
Function is used to monitor changes in certain data items, thus triggering certain operations, before using the on-demand or need to import, monitor searchValue
the changes, then the trigger logic inside the callback function, i.e. the value entered by the user to retrieve the listener, then triggers the callback function logic searchValue
value stored into our create store
objects inside, rear, and aspects Panel.vue
list data communication components:
import { reactive, watch } from "@vue/composition-api";
import store from "../stores";
export default {
setup() {
const state = reactive({
searchValue: "",
});
// 监听搜索框的值
watch(
() => {
return state.searchValue;
},
() => {
// 存储输入框到状态 store 中心,用于组件通信
store.setSearchValue(state.searchValue);
}
);
return {
...toRefs(state)
};
}
};
state management
Here we maintain a shared data management status, which means that we create a new store.js
expose a store
target share Panel
and Search
component searchValue
values, when the Search.vue
components received from the input box searchValue
to retrieve values, you put store.js
the store
object, then the object injected into the Search
assembly, the two assemblies can share store
the value of the object, in order to facilitate debugging we also were encapsulated setSearchValue
and getSearchValue
come operating the store
objects, so that we can track the change in the state.
// store.js
export default {
state: {
searchValue: ""
},
// 设置搜索框的值
setSearchValue(value) {
this.state.searchValue = value
},
// 获取搜索框的值
getSearchValue() {
return this.state.searchValue
}
}
Completion of the above Search.vue
we immediately write Panel.vue
the search box components, and then continue src/components
folder under a new Panel.vue
file.
<template>
<div class="weui-panel weui-panel_access">
<div v-for="(n,index) in newComputed" :key="index" class="weui-panel__bd">
<a href="javascript:void(0);" class="weui-media-box weui-media-box_appmsg">
<div class="weui-media-box__hd">
<img class="weui-media-box__thumb" :src="n.author.avatar_url" alt />
</div>
<div class="weui-media-box__bd">
<h4 class="weui-media-box__title" v-text="n.title"></h4>
<p class="weui-media-box__desc" v-text="n.author.loginname"></p>
</div>
</a>
</div>
<div @click="loadMore" class="weui-panel__ft">
<a href="javascript:void(0);" class="weui-cell weui-cell_access weui-cell_link">
<div class="weui-cell__bd">查看更多</div>
<span class="weui-cell__ft"></span>
</a>
</div>
</div>
</template>
<script>
import { reactive, toRefs, onMounted, computed } from "@vue/composition-api";
import axios from "axios";
import store from "../stores";
export default {
setup() {
const state = reactive({
// 页数
page: 1,
// 列表数据
news: [],
// 通过搜索框的值去筛选劣列表数据
newComputed: computed(() => {
// 判断是否输入框是否输入了筛选条件,如果没有返回原始的 news 数组
if (store.state.searchValue) {
return state.news.filter(item => {
if (item.title.indexOf(store.state.searchValue) >= 0) {
return item;
}
});
} else {
return state.news;
}
}),
searchValue: store.state
});
// 发送 ajax 请求获取列表数据
const loadMore = async () => {
// 获取列表数据
let data = await axios.get("https://cnodejs.org/api/v1/topics", {
params: {
// 每一页的主题数量
limit: 10,
// 页数
page: state.page
}
});
// 叠加页数
state.page += 1;
state.news = [...state.news, ...data.data.data];
};
onMounted(() => {
// 首屏加载的时候触发请求
loadMore();
});
return {
// 让数据保持响应式
...toRefs(state),
// 查看更多事件
loadMore
};
}
};
</script>
lifecycle hooks
Vue3.0
The life cycle of the hook and not the same as before, the new version are based on onXxx()
the function registered, the same need to introduce the life cycle of corresponding local modules:
import { onMounted, onUpdated, onUnmounted } from "@vue/composition-api";
export default {
setup() {
const loadMore = () => {};
onMounted(() => {
loadMore();
});
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
return {
loadMore
};
}
};
The following is a comparison of the old and new versions of the life cycle:
- <s>
beforeCreate
</s> -> usesetup()
- <s>
created
</s> -> usesetup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeDestroy
->onBeforeUnmount
destroyed
->onUnmounted
errorCaptured
->onErrorCaptured
While the new version also offers two new lifecycle helps us to debug the code:
- onRenderTracked
- onRenderTriggered
In the Panel
list of components, we registered onMounted
lifecycle and trigger inside the request method loadMore
to get data from back-to-data layer, we use here is the axios
network request to the library, so we need to install the module:
npm install axios --save
A method of encapsulating data list request, the interface points to Cnode
official website provides API
, due axios
returns Promise
, so mating async
and await
perfectly prepared asynchronous logic, and then combined with onMounted
the life cycle of the trigger, and the method to bind to the view button for more layer on the list for the first time to complete loading and click to see more lazy loading functionality.
// 发送 ajax 请求获取列表数据
const loadMore = async () => {
// 获取列表数据
let data = await axios.get("https://cnodejs.org/api/v1/topics", {
params: {
// 每一页的主题数量
limit: 10,
// 页数
page: state.page
}
});
// 叠加页数
state.page += 1;
// 合并列表数据
state.news = [...state.news, ...data.data.data];
};
onMounted(() => {
// 首屏加载的时候触发请求
loadMore();
});
computed
Then we use another property computed
to calculate property, with Vue2.0
very similar use, also need to import the module as needed:
import { computed } from '@vue/composition-api';
Calculating two types of properties, and the read-only attribute calculation readable and writable calculated properties:
// 只读计算属性
let newsComputed = computed(() => news.value + 1)
// 可读可写
let newsComputed = computed({
// 取值函数
get: () => news.value + 2,
// 赋值函数
set: val => {
news.value = news.value - 3
}
})
Here we use to read and write property calculation processing table data, on a component we remember Search.vue
it, we can combine retrieve the value entered by the user in the search box, with the computed
calculated attributes to the list of useful filter our data users, so we first from store
examples of shared get inside Search.vue
the search box is shared searchValue
, and a method using a primary string indexOf
and array method filter
to filter data list, and return to the list of new data newsComputed
, and in the view layer with v-for
instructions to render the new data list, to do so either return to the original list of data when we do not retrieve the value of the search box news
, and returns a new list of data when there is a search box to retrieve the value newsComputed
.
import store from "../stores";
export default {
setup() {
const state = reactive({
// 原列表数据
news: [],
// 通过搜索框的值去筛选后的新列表数据
newsComputed: computed(() => {
// 判断是否输入框是否输入了筛选条件,如果没有返回原始的 news 数组
if (store.state.searchValue) {
return state.news.filter(item => {
if (item.title.indexOf(store.state.searchValue) >= 0) {
return item;
}
});
} else {
return state.news;
}
}),
searchValue: store.state
});
}
}
Attached Java / C / C ++ / machine learning / Algorithms and Data Structures / front-end / Android / Python / programmer reading / single books books Daquan:
(Click on the right to open there in the dry personal blog): Technical dry Flowering
===== >> ① [Java Daniel take you on the road to advanced] << ====
===== >> ② [+ acm algorithm data structure Daniel take you on the road to advanced] << ===
===== >> ③ [database Daniel take you on the road to advanced] << == ===
===== >> ④ [Daniel Web front-end to take you on the road to advanced] << ====
===== >> ⑤ [machine learning python and Daniel take you entry to the Advanced Road] << ====
===== >> ⑥ [architect Daniel take you on the road to advanced] << =====
===== >> ⑦ [C ++ Daniel advanced to take you on the road] << ====
===== >> ⑧ [ios Daniel take you on the road to advanced] << ====
=====> > ⑨ [Web security Daniel take you on the road to advanced] << =====
===== >> ⑩ [Linux operating system and Daniel take you on the road to advanced] << = ====There is no unearned fruits, hope you young friends, friends want to learn techniques, overcoming all obstacles in the way of the road determined to tie into technology, understand the book, and then knock on the code, understand the principle, and go practice, will It will bring you life, your job, your future a dream.